aboutsummaryrefslogtreecommitdiffstats
path: root/executor
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 /executor
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).
Diffstat (limited to 'executor')
-rw-r--r--executor/common_linux.h16
-rw-r--r--executor/executor.h40
2 files changed, 33 insertions, 23 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;
}