diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2018-02-26 15:54:02 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2018-02-26 15:54:02 +0100 |
| commit | 66cf309385d0da374a6b0f14fcc87cef2cd6768f (patch) | |
| tree | 768b104a7bc49773aa3cdcd488b393ecc29c2bf9 | |
| parent | 14dae29c2abebd8886909c7a09c5795ffdd11515 (diff) | |
executor, pkg/csource: make fd numbers consistent
Currently when executor creates fd's it gets: 0, 3, 4.
When tun is enabled: 3, 4, 5.
For C programs: 3, 4, 5.
When run is enabled: 4, 5, 6.
Theoretically it should not matter,
but these fd numbers are probably sometimes are used as data.
So make them consistent in all these cases (3, 4, 5).
| -rw-r--r-- | executor/common_linux.h | 16 | ||||
| -rw-r--r-- | executor/executor.h | 40 | ||||
| -rw-r--r-- | pkg/csource/linux_common.go | 14 |
3 files changed, 44 insertions, 26 deletions
diff --git a/executor/common_linux.h b/executor/common_linux.h index 1411fe8e2..f74effbba 100644 --- a/executor/common_linux.h +++ b/executor/common_linux.h @@ -309,6 +309,13 @@ static void initialize_tun(int id) return; #endif } + // Remap tun onto higher fd number to hide it from fuzzer and to keep + // fd numbers stable regardless of whether tun is opened or not. + const int kTunFd = 252; + if (dup2(tunfd, kTunFd) < 0) + fail("dup2(tunfd, kTunFd) failed"); + close(tunfd); + tunfd = kTunFd; char iface[IFNAMSIZ]; snprintf_check(iface, sizeof(iface), "syz%d", id); @@ -896,9 +903,12 @@ static int namespace_sandbox_proc(void* arg) fail("mkdir failed"); // selinux mount used to be at /selinux, but then moved to /sys/fs/selinux. const char* selinux_path = "./syz-tmp/newroot/selinux"; - if (mount("/selinux", selinux_path, NULL, mount_flags, NULL) && - mount("/sys/fs/selinux", selinux_path, NULL, mount_flags, NULL)) - fail("mount(selinuxfs) failed"); + if (mount("/selinux", selinux_path, NULL, mount_flags, NULL)) { + if (errno != ENOENT) + fail("mount(/selinux) failed"); + if (mount("/sys/fs/selinux", selinux_path, NULL, mount_flags, NULL) && errno != ENOENT) + fail("mount(/sys/fs/selinux) failed"); + } if (mkdir("./syz-tmp/pivot", 0777)) fail("mkdir failed"); if (syscall(SYS_pivot_root, "./syz-tmp", "./syz-tmp/pivot")) { diff --git a/executor/executor.h b/executor/executor.h index ee48981a9..063b61ff3 100644 --- a/executor/executor.h +++ b/executor/executor.h @@ -198,8 +198,10 @@ void setup_control_pipes() fail("dup2(1, kOutPipeFd) failed"); if (dup2(2, 1) < 0) fail("dup2(2, 1) failed"); - if (close(0)) - fail("close(0) failed"); + // We used to close(0), but now we dup stderr to stdin to keep fd numbers + // stable across executor and C programs generated by pkg/csource. + if (dup2(2, 0) < 0) + fail("dup2(2, 0) failed"); } void parse_env_flags(uint64 flags) @@ -707,24 +709,22 @@ bool copyout(char* addr, uint64 size, uint64* res) { bool ok = false; NONFAILING( - switch (size) { - case 1: - *res = *(uint8*)addr; - break; - case 2: - *res = *(uint16*)addr; - break; - case 4: - *res = *(uint32*)addr; - break; - case 8: - *res = *(uint64*)addr; - break; - default: - fail("copyout: bad argument size %llu", size); - } - __atomic_store_n(&ok, true, __ATOMIC_RELEASE); - ); + switch (size) { + case 1: + *res = *(uint8*)addr; + break; + case 2: + *res = *(uint16*)addr; + break; + case 4: + *res = *(uint32*)addr; + break; + case 8: + *res = *(uint64*)addr; + break; + default: + fail("copyout: bad argument size %llu", size); + } __atomic_store_n(&ok, true, __ATOMIC_RELEASE);); return ok; } diff --git a/pkg/csource/linux_common.go b/pkg/csource/linux_common.go index dc917fed2..fe380d9d4 100644 --- a/pkg/csource/linux_common.go +++ b/pkg/csource/linux_common.go @@ -451,6 +451,11 @@ static void initialize_tun(int id) return; #endif } + const int kTunFd = 252; + if (dup2(tunfd, kTunFd) < 0) + fail("dup2(tunfd, kTunFd) failed"); + close(tunfd); + tunfd = kTunFd; char iface[IFNAMSIZ]; snprintf_check(iface, sizeof(iface), "syz%d", id); @@ -1938,9 +1943,12 @@ static int namespace_sandbox_proc(void* arg) if (mkdir("./syz-tmp/newroot/selinux", 0700)) fail("mkdir failed"); const char* selinux_path = "./syz-tmp/newroot/selinux"; - if (mount("/selinux", selinux_path, NULL, mount_flags, NULL) && - mount("/sys/fs/selinux", selinux_path, NULL, mount_flags, NULL)) - fail("mount(selinuxfs) failed"); + if (mount("/selinux", selinux_path, NULL, mount_flags, NULL)) { + if (errno != ENOENT) + fail("mount(/selinux) failed"); + if (mount("/sys/fs/selinux", selinux_path, NULL, mount_flags, NULL) && errno != ENOENT) + fail("mount(/sys/fs/selinux) failed"); + } if (mkdir("./syz-tmp/pivot", 0777)) fail("mkdir failed"); if (syscall(SYS_pivot_root, "./syz-tmp", "./syz-tmp/pivot")) { |
