diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2017-12-05 17:03:58 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2017-12-05 20:08:06 +0100 |
| commit | 64d31856d9053f217112eacad348cbde37aed2a5 (patch) | |
| tree | 4da93fd48f9c28d51dc569bb3f8e47f8c61f4119 /executor | |
| parent | c2c4cd4e57b36e5f8b1e1731a78bfc66147222f4 (diff) | |
executor: unshare PID namespace even for sandbox=none
Unshare as much as we can for all sandboxing modes.
This fixes "kernel panic: Attempted to kill init!" crashes
under sandbox=none. And should just generally improve
reproducibility, e.g. if we unshare SYSVSEM fuzzer won't
collide with any existing semaphores.
Diffstat (limited to 'executor')
| -rw-r--r-- | executor/common_linux.h | 31 |
1 files changed, 26 insertions, 5 deletions
diff --git a/executor/common_linux.h b/executor/common_linux.h index aee1f65b9..b405b999b 100644 --- a/executor/common_linux.h +++ b/executor/common_linux.h @@ -700,17 +700,30 @@ static void sandbox_common() rlim.rlim_cur = rlim.rlim_max = 0; setrlimit(RLIMIT_CORE, &rlim); - // CLONE_NEWIPC/CLONE_IO cause EINVAL on some systems, so we do them separately of clone. +#ifndef CLONE_NEWCGROUP +#define CLONE_NEWCGROUP 0x02000000 +#endif + + // 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_IO); + unshare(CLONE_NEWCGROUP); + unshare(CLONE_NEWNET); + unshare(CLONE_NEWUTS); + unshare(CLONE_SYSVSEM); } #endif #if defined(SYZ_EXECUTOR) || defined(SYZ_SANDBOX_NONE) 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); int pid = fork(); + if (pid < 0) + exitf("sandbox fork failed"); if (pid) return pid; @@ -727,7 +740,10 @@ 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); int pid = fork(); + if (pid < 0) + exitf("sandbox fork failed"); if (pid) return pid; @@ -846,6 +862,8 @@ static int namespace_sandbox_proc(void* arg) static int do_sandbox_namespace(int executor_pid, bool enable_tun) { + int pid; + #if defined(SYZ_EXECUTOR) || defined(SYZ_TUN_ENABLE) // For sandbox namespace we setup tun before dropping privs, // because IFF_NAPI_FRAGS requires root. @@ -855,8 +873,11 @@ static int do_sandbox_namespace(int executor_pid, bool enable_tun) real_uid = getuid(); real_gid = getgid(); mprotect(sandbox_stack, 4096, PROT_NONE); // to catch stack underflows - return clone(namespace_sandbox_proc, &sandbox_stack[sizeof(sandbox_stack) - 64], - CLONE_NEWUSER | CLONE_NEWPID | CLONE_NEWUTS | CLONE_NEWNET, NULL); + pid = clone(namespace_sandbox_proc, &sandbox_stack[sizeof(sandbox_stack) - 64], + CLONE_NEWUSER | CLONE_NEWPID, NULL); + if (pid < 0) + exitf("sandbox clone failed"); + return pid; } #endif @@ -990,7 +1011,7 @@ void loop() #endif int pid = fork(); if (pid < 0) - fail("clone failed"); + exitf("loop fork failed"); if (pid == 0) { prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); setpgrp(); |
