diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2018-01-15 19:09:16 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2018-01-15 19:09:16 +0100 |
| commit | b705c0226334d8763a9f1b9ee06fe7a78a5558e7 (patch) | |
| tree | ceaf2e9b9bd72b53b6884d09407c6edfcf46c4e6 /executor/common_linux.h | |
| parent | b75f5cb3cb6145796e39a799e4b4c83d7d4b4237 (diff) | |
executor: fix tun/device setup for sandbox=namespace
For sandbox=namespace we first create network devices
and then do CLONE_NEWNS, which brings us into a new
namespace which actually does not have any of these devices.
Tun mostly worked, because we hold fd to the tun device.
However, even for tun we could not see the "syz0" device.
Diffstat (limited to 'executor/common_linux.h')
| -rw-r--r-- | executor/common_linux.h | 41 |
1 files changed, 33 insertions, 8 deletions
diff --git a/executor/common_linux.h b/executor/common_linux.h index ce7466789..3e84f333e 100644 --- a/executor/common_linux.h +++ b/executor/common_linux.h @@ -735,12 +735,21 @@ static void sandbox_common() // CLONE_NEWNS/NEWCGROUP cause EINVAL on some systems, // so we do them separately of clone in do_sandbox_namespace. - unshare(CLONE_NEWNS); - unshare(CLONE_NEWIPC); - unshare(CLONE_NEWCGROUP); - unshare(CLONE_NEWNET); - unshare(CLONE_NEWUTS); - unshare(CLONE_SYSVSEM); + if (unshare(CLONE_NEWNS)) { + debug("unshare(CLONE_NEWNS): %d\n", errno); + } + if (unshare(CLONE_NEWIPC)) { + debug("unshare(CLONE_NEWIPC): %d\n", errno); + } + if (unshare(CLONE_NEWCGROUP)) { + debug("unshare(CLONE_NEWCGROUP): %d\n", errno); + } + if (unshare(CLONE_NEWUTS)) { + debug("unshare(CLONE_NEWUTS): %d\n", errno); + } + if (unshare(CLONE_SYSVSEM)) { + debug("unshare(CLONE_SYSVSEM): %d\n", errno); + } } #endif @@ -749,7 +758,13 @@ static int do_sandbox_none(int executor_pid, bool enable_tun) { // CLONE_NEWPID takes effect for the first child of the current process, // so we do it before fork to make the loop "init" process of the namespace. - unshare(CLONE_NEWPID); + // We ought to do fail here, but sandbox=none is used in pkg/ipc tests + // and they are usually run under non-root. + // Also since debug is stripped by pkg/csource, we need to do {} + // even though we generally don't do {} around single statements. + if (unshare(CLONE_NEWPID)) { + debug("unshare(CLONE_NEWPID): %d\n", errno); + } int pid = fork(); if (pid < 0) fail("sandbox fork failed"); @@ -757,6 +772,9 @@ static int do_sandbox_none(int executor_pid, bool enable_tun) return pid; sandbox_common(); + if (unshare(CLONE_NEWNET)) { + debug("unshare(CLONE_NEWNET): %d\n", errno); + } #if defined(SYZ_EXECUTOR) || defined(SYZ_TUN_ENABLE) setup_tun(executor_pid, enable_tun); #endif @@ -769,7 +787,8 @@ static int do_sandbox_none(int executor_pid, bool enable_tun) #if defined(SYZ_EXECUTOR) || defined(SYZ_SANDBOX_SETUID) static int do_sandbox_setuid(int executor_pid, bool enable_tun) { - unshare(CLONE_NEWPID); + if (unshare(CLONE_NEWPID)) + fail("unshare(CLONE_NEWPID)"); int pid = fork(); if (pid < 0) fail("sandbox fork failed"); @@ -777,6 +796,8 @@ static int do_sandbox_setuid(int executor_pid, bool enable_tun) return pid; sandbox_common(); + if (unshare(CLONE_NEWNET)) + fail("unshare(CLONE_NEWNET)"); #if defined(SYZ_EXECUTOR) || defined(SYZ_TUN_ENABLE) setup_tun(executor_pid, enable_tun); #endif @@ -893,6 +914,10 @@ static int do_sandbox_namespace(int executor_pid, bool enable_tun) { int pid; + // CLONE_NEWNET must always happen before tun setup, + // because we want the tun device in the test namespace. + if (unshare(CLONE_NEWNET)) + fail("unshare(CLONE_NEWNET)"); #if defined(SYZ_EXECUTOR) || defined(SYZ_TUN_ENABLE) // For sandbox namespace we setup tun before dropping privs, // because IFF_NAPI_FRAGS requires root. |
