Fix -x/--exec to also join a session's network namespace
net was deliberately excluded from exec_session.cpp's joinable_namespaces list, written back when this project never isolated networking at all. Now that -r/--run sometimes does (whenever -n/--network was used), -x/--exec'ing into such a session saw the host's own network stack instead of the container's -- confirmed directly: it showed the host's unrelated listening ports and couldn't reach the container's own service on 127.0.0.1. Fixed by joining net the same way -x/--exec already joins mnt/uts/ipc/pid/cgroup/user when they differ from the caller's own -- not required, so a session with no isolated net namespace (never joined any network) is unaffected, the entry is just skipped like any other identical-to-ours namespace. Verified as root (via a scoped doas rule): execing into a session joined to an extern network now correctly shows its own eth0 and reaches its own service on 127.0.0.1; execing into a plain session with no -n is unaffected.
This commit is contained in:
@@ -686,19 +686,23 @@ Source layout (all under `src/`):
|
||||
and an `extern` network simultaneously got two working interfaces
|
||||
(`eth0`/`eth1`) with neither one breaking the other.
|
||||
|
||||
**Real, separate bug found while testing this commit, not yet fixed** (out
|
||||
of scope for the networking feature's own commit sequence, noted here so
|
||||
it isn't lost): `exec_session.cpp`'s `-x/--exec` deliberately never joins
|
||||
the `net` namespace type (see that file's own entry below — written when
|
||||
this project genuinely never isolated networking at all, so there was
|
||||
nothing to join). Now that `-r/--run` sometimes *does* isolate networking
|
||||
(whenever any `-n` was given), `-x/--exec`'ing into such a session sees the
|
||||
*host's* network stack instead of the container's — confirmed directly:
|
||||
execing into a session running a network-isolated `httpd` showed the
|
||||
host's own unrelated listening ports and failed to reach the container's
|
||||
own service on `127.0.0.1`. `exec_session.cpp` needs updating to join
|
||||
`net` too, the same way it already joins `mnt`/`uts`/`ipc`/`pid`/`cgroup`/
|
||||
`user` when they differ from the caller's own.
|
||||
**Real, separate bug found while testing this commit — since fixed**
|
||||
(`exec_session.{h,cpp}`, see that file's own entry below): `-x/--exec`
|
||||
deliberately never joined the `net` namespace type, written back when this
|
||||
project genuinely never isolated networking at all, so there was nothing
|
||||
to join. Once `-r/--run` sometimes isolates networking (whenever any `-n`
|
||||
was given), `-x/--exec`'ing into such a session saw the *host's* network
|
||||
stack instead of the container's — confirmed directly: execing into a
|
||||
session running a network-isolated `httpd` showed the host's own unrelated
|
||||
listening ports and failed to reach the container's own service on
|
||||
`127.0.0.1`. Fixed by joining `net` too, the same way `-x/--exec` already
|
||||
joins `mnt`/`uts`/`ipc`/`pid`/`cgroup`/`user` when they differ from the
|
||||
caller's own — reverified afterward: execing into that same session now
|
||||
correctly shows the container's own `eth0` and reaches its own service on
|
||||
`127.0.0.1`, while execing into a plain session with no `-n` at all is
|
||||
unaffected (still just loopback, whether or not the kernel happened to
|
||||
give it its own otherwise-empty net namespace via the default
|
||||
`global.unshare-net` policy).
|
||||
- `port_forward.{h,cpp}` — implements `-p`. `parse_port_forward_spec()`
|
||||
splits `"[<network>:]<host-port>:<container-port>"` on `':'` (2 or 3
|
||||
fields; the network name is deliberately restricted to excluding `':'` --
|
||||
@@ -929,8 +933,18 @@ Source layout (all under `src/`):
|
||||
(`sandbox_process.{h,cpp}` — moved out of this file once `--kill`
|
||||
needed the exact same logic, see that entry) finds that real inner process
|
||||
so this can join *its* namespaces instead. For each of `{mnt→--mount, uts→--uts, ipc→--ipc, pid→--pid,
|
||||
cgroup→--cgroup, user→--user}` (`net` deliberately excluded — this project
|
||||
never isolates networking, see `bwrap.cpp` below), `readlink()`s both
|
||||
net→--net, cgroup→--cgroup, user→--user}` — `net` used to be excluded here
|
||||
(this project never isolated networking at all, back when this comment was
|
||||
first written), but now that a session started with `-n/--network`
|
||||
(`network_join.h`) genuinely does get an isolated net namespace, skipping
|
||||
it left `-x/--exec` seeing the *host's* network stack instead of the
|
||||
container's — confirmed directly (execing into a network-isolated session
|
||||
showed the host's own unrelated listening ports and couldn't reach the
|
||||
container's own service on `127.0.0.1`), fixed by including it the same
|
||||
way as the other optional types: a session with no isolated net namespace
|
||||
at all (i.e. `net` identical to ours) just has this entry skipped like any
|
||||
other, so nothing changes for a session that never joined a network.
|
||||
`readlink()`s both
|
||||
`/proc/<ns_pid>/ns/<type>` and `/proc/self/ns/<type>` and only passes
|
||||
nsenter's corresponding `--type=/proc/<ns_pid>/ns/<type>` flag when they
|
||||
differ — an identical-namespace re-entry attempt can fail outright
|
||||
|
||||
Reference in New Issue
Block a user