aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2018-02-26 15:54:02 +0100
committerDmitry Vyukov <dvyukov@google.com>2018-02-26 15:54:02 +0100
commit66cf309385d0da374a6b0f14fcc87cef2cd6768f (patch)
tree768b104a7bc49773aa3cdcd488b393ecc29c2bf9
parent14dae29c2abebd8886909c7a09c5795ffdd11515 (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.h16
-rw-r--r--executor/executor.h40
-rw-r--r--pkg/csource/linux_common.go14
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")) {