mirror of
https://github.com/reactos/syzkaller.git
synced 2024-11-23 11:29:46 +00:00
sys/linux: add cgroup descriptions
This commit is contained in:
parent
2e9d905410
commit
2675f92065
@ -42,6 +42,12 @@ typedef unsigned int uint32;
|
||||
typedef unsigned short uint16;
|
||||
typedef unsigned char uint8;
|
||||
|
||||
#ifdef SYZ_EXECUTOR
|
||||
// Note: zircon max fd is 256.
|
||||
const int kInPipeFd = 250; // remapped from stdin
|
||||
const int kOutPipeFd = 251; // remapped from stdout
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define SYSCALLAPI
|
||||
#define NORETURN __attribute__((noreturn))
|
||||
|
@ -43,15 +43,20 @@
|
||||
#include <sys/time.h>
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_FAULT_INJECTION) || defined(SYZ_SANDBOX_NAMESPACE) || \
|
||||
defined(SYZ_ENABLE_CGROUPS)
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_SANDBOX_SETUID)
|
||||
#include <grp.h>
|
||||
#endif
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_SANDBOX_NAMESPACE)
|
||||
#include <fcntl.h>
|
||||
#include <linux/capability.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_TUN_ENABLE)
|
||||
#include <arpa/inet.h>
|
||||
@ -120,11 +125,15 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#if defined(SYZ_EXECUTOR) || defined(__NR_syz_genetlink_get_family_id)
|
||||
#include <errno.h>
|
||||
#include <linux/genetlink.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_ENABLE_CGROUPS)
|
||||
#include <sys/mount.h>
|
||||
#endif
|
||||
|
||||
#if defined(SYZ_EXECUTOR) || (defined(SYZ_REPEAT) && defined(SYZ_WAIT_REPEAT)) || \
|
||||
defined(SYZ_USE_TMP_DIR) || defined(SYZ_HANDLE_SEGV) || defined(SYZ_TUN_ENABLE) || \
|
||||
@ -791,6 +800,74 @@ static uintptr_t syz_kvm_setup_cpu(uintptr_t a0, uintptr_t a1, uintptr_t a2, uin
|
||||
#endif
|
||||
#endif // #ifdef __NR_syz_kvm_setup_cpu
|
||||
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_FAULT_INJECTION) || defined(SYZ_SANDBOX_NAMESPACE) || \
|
||||
defined(SYZ_ENABLE_CGROUPS)
|
||||
static bool write_file(const char* file, const char* what, ...)
|
||||
{
|
||||
char buf[1024];
|
||||
va_list args;
|
||||
va_start(args, what);
|
||||
vsnprintf(buf, sizeof(buf), what, args);
|
||||
va_end(args);
|
||||
buf[sizeof(buf) - 1] = 0;
|
||||
int len = strlen(buf);
|
||||
|
||||
int fd = open(file, O_WRONLY | O_CLOEXEC);
|
||||
if (fd == -1)
|
||||
return false;
|
||||
if (write(fd, buf, len) != len) {
|
||||
int err = errno;
|
||||
close(fd);
|
||||
errno = err;
|
||||
return false;
|
||||
}
|
||||
close(fd);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_ENABLE_CGROUPS)
|
||||
static void setup_cgroups()
|
||||
{
|
||||
if (mkdir("/syzcgroup", 0777)) {
|
||||
debug("mkdir(/syzcgroup) failed: %d\n", errno);
|
||||
}
|
||||
if (mkdir("/syzcgroup/unified", 0777)) {
|
||||
debug("mkdir(/syzcgroup/unified) failed: %d\n", errno);
|
||||
}
|
||||
if (mount("none", "/syzcgroup/unified", "cgroup2", 0, NULL)) {
|
||||
debug("mount(cgroup2) failed: %d\n", errno);
|
||||
}
|
||||
if (chmod("/syzcgroup/unified", 0777)) {
|
||||
debug("chmod(/syzcgroup/unified) failed: %d\n", errno);
|
||||
}
|
||||
if (!write_file("/syzcgroup/unified/cgroup.subtree_control", "+cpu +memory +io +pids +rdma")) {
|
||||
debug("write(cgroup.subtree_control) failed: %d\n", errno);
|
||||
}
|
||||
if (mkdir("/syzcgroup/cpu", 0777)) {
|
||||
debug("mkdir(/syzcgroup/cpu) failed: %d\n", errno);
|
||||
}
|
||||
if (mount("none", "/syzcgroup/cpu", "cgroup", 0, "cpuset,cpuacct,perf_event,hugetlb")) {
|
||||
debug("mount(cgroup cpu) failed: %d\n", errno);
|
||||
}
|
||||
if (!write_file("/syzcgroup/cpu/cgroup.clone_children", "1")) {
|
||||
debug("write(/syzcgroup/cpu/cgroup.clone_children) failed: %d\n", errno);
|
||||
}
|
||||
if (chmod("/syzcgroup/cpu", 0777)) {
|
||||
debug("chmod(/syzcgroup/cpu) failed: %d\n", errno);
|
||||
}
|
||||
if (mkdir("/syzcgroup/net", 0777)) {
|
||||
debug("mkdir(/syzcgroup/net) failed: %d\n", errno);
|
||||
}
|
||||
if (mount("none", "/syzcgroup/net", "cgroup", 0, "net_cls,net_prio,devices,freezer")) {
|
||||
debug("mount(cgroup net) failed: %d\n", errno);
|
||||
}
|
||||
if (chmod("/syzcgroup/net", 0777)) {
|
||||
debug("chmod(/syzcgroup/net) failed: %d\n", errno);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_SANDBOX_NONE) || defined(SYZ_SANDBOX_SETUID) || defined(SYZ_SANDBOX_NAMESPACE)
|
||||
static void loop();
|
||||
|
||||
@ -863,6 +940,9 @@ static int do_sandbox_none(void)
|
||||
if (pid)
|
||||
return pid;
|
||||
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_ENABLE_CGROUPS)
|
||||
setup_cgroups();
|
||||
#endif
|
||||
sandbox_common();
|
||||
if (unshare(CLONE_NEWNET)) {
|
||||
debug("unshare(CLONE_NEWNET): %d\n", errno);
|
||||
@ -889,6 +969,9 @@ static int do_sandbox_setuid(void)
|
||||
if (pid)
|
||||
return pid;
|
||||
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_ENABLE_CGROUPS)
|
||||
setup_cgroups();
|
||||
#endif
|
||||
sandbox_common();
|
||||
if (unshare(CLONE_NEWNET))
|
||||
fail("unshare(CLONE_NEWNET)");
|
||||
@ -916,29 +999,6 @@ static int do_sandbox_setuid(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_SANDBOX_NAMESPACE) || defined(SYZ_FAULT_INJECTION)
|
||||
static bool write_file(const char* file, const char* what, ...)
|
||||
{
|
||||
char buf[1024];
|
||||
va_list args;
|
||||
va_start(args, what);
|
||||
vsnprintf(buf, sizeof(buf), what, args);
|
||||
va_end(args);
|
||||
buf[sizeof(buf) - 1] = 0;
|
||||
int len = strlen(buf);
|
||||
|
||||
int fd = open(file, O_WRONLY | O_CLOEXEC);
|
||||
if (fd == -1)
|
||||
return false;
|
||||
if (write(fd, buf, len) != len) {
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
close(fd);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_SANDBOX_NAMESPACE)
|
||||
static int real_uid;
|
||||
static int real_gid;
|
||||
@ -994,6 +1054,29 @@ static int namespace_sandbox_proc(void* arg)
|
||||
if (mount("/sys/fs/selinux", selinux_path, NULL, mount_flags, NULL) && errno != ENOENT)
|
||||
fail("mount(/sys/fs/selinux) failed");
|
||||
}
|
||||
if (mkdir("./syz-tmp/newroot/sys", 0700))
|
||||
fail("mkdir failed");
|
||||
if (mount(NULL, "./syz-tmp/newroot/sys", "sysfs", 0, NULL))
|
||||
fail("mount(sysfs) failed");
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_ENABLE_CGROUPS)
|
||||
if (mkdir("./syz-tmp/newroot/syzcgroup", 0700))
|
||||
fail("mkdir failed");
|
||||
if (mkdir("./syz-tmp/newroot/syzcgroup/unified", 0700))
|
||||
fail("mkdir failed");
|
||||
if (mkdir("./syz-tmp/newroot/syzcgroup/cpu", 0700))
|
||||
fail("mkdir failed");
|
||||
if (mkdir("./syz-tmp/newroot/syzcgroup/net", 0700))
|
||||
fail("mkdir failed");
|
||||
if (mount("/syzcgroup/unified", "./syz-tmp/newroot/syzcgroup/unified", NULL, mount_flags, NULL)) {
|
||||
debug("mount(cgroup2, MS_BIND) failed: %d\n", errno);
|
||||
}
|
||||
if (mount("/syzcgroup/cpu", "./syz-tmp/newroot/syzcgroup/cpu", NULL, mount_flags, NULL)) {
|
||||
debug("mount(cgroup/cpu, MS_BIND) failed: %d\n", errno);
|
||||
}
|
||||
if (mount("/syzcgroup/net", "./syz-tmp/newroot/syzcgroup/net", NULL, mount_flags, NULL)) {
|
||||
debug("mount(cgroup/net, MS_BIND) failed: %d\n", errno);
|
||||
}
|
||||
#endif
|
||||
if (mkdir("./syz-tmp/pivot", 0777))
|
||||
fail("mkdir failed");
|
||||
if (syscall(SYS_pivot_root, "./syz-tmp", "./syz-tmp/pivot")) {
|
||||
@ -1036,6 +1119,9 @@ static int do_sandbox_namespace(void)
|
||||
{
|
||||
int pid;
|
||||
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_ENABLE_CGROUPS)
|
||||
setup_cgroups();
|
||||
#endif
|
||||
real_uid = getuid();
|
||||
real_gid = getgid();
|
||||
mprotect(sandbox_stack, 4096, PROT_NONE); // to catch stack underflows
|
||||
@ -1554,58 +1640,185 @@ static int fault_injected(int fail_fd)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(SYZ_REPEAT)
|
||||
static void test();
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_REPEAT)
|
||||
static void execute_one();
|
||||
extern unsigned long long procid;
|
||||
|
||||
#if defined(SYZ_WAIT_REPEAT)
|
||||
void loop()
|
||||
#if defined(SYZ_EXECUTOR)
|
||||
void reply_handshake();
|
||||
void receive_execute(bool need_prog);
|
||||
void reply_execute(int status);
|
||||
extern uint32* output_data;
|
||||
extern uint32* output_pos;
|
||||
#endif
|
||||
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_WAIT_REPEAT)
|
||||
static void loop()
|
||||
{
|
||||
int iter;
|
||||
#if defined(SYZ_RESET_NET_NAMESPACE)
|
||||
#if defined(SYZ_EXECUTOR)
|
||||
// Tell parent that we are ready to serve.
|
||||
reply_handshake();
|
||||
#endif
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_RESET_NET_NAMESPACE)
|
||||
checkpoint_net_namespace();
|
||||
#endif
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_ENABLE_CGROUPS)
|
||||
char cgroupdir[64];
|
||||
snprintf(cgroupdir, sizeof(cgroupdir), "/syzcgroup/unified/syz%llu", procid);
|
||||
char cgroupdir_cpu[64];
|
||||
snprintf(cgroupdir_cpu, sizeof(cgroupdir_cpu), "/syzcgroup/cpu/syz%llu", procid);
|
||||
char cgroupdir_net[64];
|
||||
snprintf(cgroupdir_net, sizeof(cgroupdir_net), "/syzcgroup/net/syz%llu", procid);
|
||||
#endif
|
||||
int iter;
|
||||
for (iter = 0;; iter++) {
|
||||
#ifdef SYZ_USE_TMP_DIR
|
||||
char cwdbuf[256];
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_USE_TMP_DIR)
|
||||
// Create a new private work dir for this test (removed at the end of the loop).
|
||||
char cwdbuf[32];
|
||||
sprintf(cwdbuf, "./%d", iter);
|
||||
if (mkdir(cwdbuf, 0777))
|
||||
fail("failed to mkdir");
|
||||
#endif
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_ENABLE_CGROUPS)
|
||||
if (mkdir(cgroupdir, 0777)) {
|
||||
debug("mkdir(%s) failed: %d\n", cgroupdir, errno);
|
||||
}
|
||||
if (mkdir(cgroupdir_cpu, 0777)) {
|
||||
debug("mkdir(%s) failed: %d\n", cgroupdir_cpu, errno);
|
||||
}
|
||||
if (mkdir(cgroupdir_net, 0777)) {
|
||||
debug("mkdir(%s) failed: %d\n", cgroupdir_net, errno);
|
||||
}
|
||||
#endif
|
||||
#if defined(SYZ_EXECUTOR)
|
||||
// TODO: consider moving the read into the child.
|
||||
// Potentially it can speed up things a bit -- when the read finishes
|
||||
// we already have a forked worker process.
|
||||
receive_execute(false);
|
||||
#endif
|
||||
int pid = fork();
|
||||
if (pid < 0)
|
||||
fail("loop fork failed");
|
||||
fail("clone failed");
|
||||
if (pid == 0) {
|
||||
prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
|
||||
setpgrp();
|
||||
#ifdef SYZ_USE_TMP_DIR
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_USE_TMP_DIR)
|
||||
if (chdir(cwdbuf))
|
||||
fail("failed to chdir");
|
||||
#endif
|
||||
#ifdef SYZ_TUN_ENABLE
|
||||
#if defined(SYZ_EXECUTOR)
|
||||
close(kInPipeFd);
|
||||
close(kOutPipeFd);
|
||||
#endif
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_ENABLE_CGROUPS)
|
||||
if (symlink(cgroupdir, "./cgroup")) {
|
||||
debug("symlink(%s, ./cgroup) failed: %d\n", cgroupdir, errno);
|
||||
}
|
||||
if (symlink(cgroupdir_cpu, "./cgroup.cpu")) {
|
||||
debug("symlink(%s, ./cgroup.cpu) failed: %d\n", cgroupdir_cpu, errno);
|
||||
}
|
||||
if (symlink(cgroupdir_net, "./cgroup.net")) {
|
||||
debug("symlink(%s, ./cgroup.net) failed: %d\n", cgroupdir_net, errno);
|
||||
}
|
||||
int pid = getpid();
|
||||
if (!write_file("./cgroup/cgroup.procs", "%d", pid)) {
|
||||
debug("write(./cgroup/cgroup.procs) failed: %d\n", errno);
|
||||
}
|
||||
if (!write_file("./cgroup.cpu/cgroup.procs", "%d", pid)) {
|
||||
debug("write(./cgroup.cpu/cgroup.procs) failed: %d\n", errno);
|
||||
}
|
||||
if (!write_file("./cgroup.net/cgroup.procs", "%d", pid)) {
|
||||
debug("write(./cgroup.net/cgroup.procs) failed: %d\n", errno);
|
||||
}
|
||||
#endif
|
||||
#if defined(SYZ_EXECUTOR)
|
||||
if (flag_enable_tun) {
|
||||
// Read all remaining packets from tun to better
|
||||
// isolate consequently executing programs.
|
||||
flush_tun();
|
||||
}
|
||||
output_pos = output_data;
|
||||
#elif defined(SYZ_TUN_ENABLE)
|
||||
flush_tun();
|
||||
#endif
|
||||
test();
|
||||
execute_one();
|
||||
debug("worker exiting\n");
|
||||
doexit(0);
|
||||
}
|
||||
debug("spawned worker pid %d\n", pid);
|
||||
|
||||
// We used to use sigtimedwait(SIGCHLD) to wait for the subprocess.
|
||||
// But SIGCHLD is also delivered when a process stops/continues,
|
||||
// so it would require a loop with status analysis and timeout recalculation.
|
||||
// SIGCHLD should also unblock the usleep below, so the spin loop
|
||||
// should be as efficient as sigtimedwait.
|
||||
int status = 0;
|
||||
uint64 start = current_time_ms();
|
||||
#if defined(SYZ_EXECUTOR)
|
||||
uint64 last_executed = start;
|
||||
uint32 executed_calls = __atomic_load_n(output_data, __ATOMIC_RELAXED);
|
||||
#endif
|
||||
for (;;) {
|
||||
int res = waitpid(-1, &status, __WALL | WNOHANG);
|
||||
if (res == pid)
|
||||
break;
|
||||
usleep(1000);
|
||||
if (current_time_ms() - start > 5 * 1000) {
|
||||
kill(-pid, SIGKILL);
|
||||
kill(pid, SIGKILL);
|
||||
while (waitpid(-1, &status, __WALL) != pid) {
|
||||
}
|
||||
if (res == pid) {
|
||||
debug("waitpid(%d)=%d\n", pid, res);
|
||||
break;
|
||||
}
|
||||
usleep(1000);
|
||||
#if defined(SYZ_EXECUTOR)
|
||||
// Even though the test process executes exit at the end
|
||||
// and execution time of each syscall is bounded by 20ms,
|
||||
// this backup watchdog is necessary and its performance is important.
|
||||
// The problem is that exit in the test processes can fail (sic).
|
||||
// One observed scenario is that the test processes prohibits
|
||||
// exit_group syscall using seccomp. Another observed scenario
|
||||
// is that the test processes setups a userfaultfd for itself,
|
||||
// then the main thread hangs when it wants to page in a page.
|
||||
// Below we check if the test process still executes syscalls
|
||||
// and kill it after 200ms of inactivity.
|
||||
uint64 now = current_time_ms();
|
||||
uint32 now_executed = __atomic_load_n(output_data, __ATOMIC_RELAXED);
|
||||
if (executed_calls != now_executed) {
|
||||
executed_calls = now_executed;
|
||||
last_executed = now;
|
||||
}
|
||||
if ((now - start < 3 * 1000) && (now - last_executed < 500))
|
||||
continue;
|
||||
#else
|
||||
if (current_time_ms() - start < 3 * 1000)
|
||||
continue;
|
||||
#endif
|
||||
debug("waitpid(%d)=%d\n", pid, res);
|
||||
debug("killing\n");
|
||||
kill(-pid, SIGKILL);
|
||||
kill(pid, SIGKILL);
|
||||
while (waitpid(-1, &status, __WALL) != pid) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
#ifdef SYZ_USE_TMP_DIR
|
||||
#if defined(SYZ_EXECUTOR)
|
||||
status = WEXITSTATUS(status);
|
||||
if (status == kFailStatus)
|
||||
fail("child failed");
|
||||
if (status == kErrorStatus)
|
||||
error("child errored");
|
||||
reply_execute(0);
|
||||
#endif
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_USE_TMP_DIR)
|
||||
remove_dir(cwdbuf);
|
||||
#endif
|
||||
#if defined(SYZ_RESET_NET_NAMESPACE)
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_ENABLE_CGROUPS)
|
||||
if (rmdir(cgroupdir)) {
|
||||
debug("rmdir(%s) failed: %d\n", cgroupdir, errno);
|
||||
}
|
||||
if (rmdir(cgroupdir_cpu)) {
|
||||
debug("rmdir(%s) failed: %d\n", cgroupdir_cpu, errno);
|
||||
}
|
||||
if (rmdir(cgroupdir_net)) {
|
||||
debug("rmdir(%s) failed: %d\n", cgroupdir_net, errno);
|
||||
}
|
||||
#endif
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_RESET_NET_NAMESPACE)
|
||||
reset_net_namespace();
|
||||
#endif
|
||||
}
|
||||
@ -1614,7 +1827,7 @@ void loop()
|
||||
void loop()
|
||||
{
|
||||
while (1) {
|
||||
test();
|
||||
execute_one();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -20,10 +20,6 @@
|
||||
#define GOOS "unknown"
|
||||
#endif
|
||||
|
||||
// Note: zircon max fd is 256.
|
||||
const int kInPipeFd = 250; // remapped from stdin
|
||||
const int kOutPipeFd = 251; // remapped from stdout
|
||||
|
||||
const int kMaxInput = 2 << 20;
|
||||
const int kMaxOutput = 16 << 20;
|
||||
const int kCoverSize = 64 << 10;
|
||||
@ -67,7 +63,7 @@ bool flag_inject_fault;
|
||||
int flag_fault_call;
|
||||
int flag_fault_nth;
|
||||
|
||||
int flag_pid;
|
||||
unsigned long long procid;
|
||||
|
||||
int running;
|
||||
uint32 completed;
|
||||
@ -226,7 +222,7 @@ void receive_handshake()
|
||||
if (req.magic != kInMagic)
|
||||
fail("bad handshake magic 0x%llx", req.magic);
|
||||
parse_env_flags(req.flags);
|
||||
flag_pid = req.pid;
|
||||
procid = req.pid;
|
||||
}
|
||||
|
||||
void reply_handshake()
|
||||
@ -247,7 +243,7 @@ void receive_execute(bool need_prog)
|
||||
if (req.prog_size > kMaxInput)
|
||||
fail("bad execute prog size 0x%llx", req.prog_size);
|
||||
parse_env_flags(req.env_flags);
|
||||
flag_pid = req.pid;
|
||||
procid = req.pid;
|
||||
flag_collect_cover = req.exec_flags & (1 << 0);
|
||||
flag_dedup_cover = req.exec_flags & (1 << 1);
|
||||
flag_inject_fault = req.exec_flags & (1 << 2);
|
||||
@ -258,8 +254,8 @@ void receive_execute(bool need_prog)
|
||||
flag_fault_nth = req.fault_nth;
|
||||
if (!flag_threaded)
|
||||
flag_collide = false;
|
||||
debug("exec opts: pid=%d threaded=%d collide=%d cover=%d comps=%d dedup=%d fault=%d/%d/%d prog=%llu\n",
|
||||
flag_pid, flag_threaded, flag_collide, flag_collect_cover, flag_collect_comps,
|
||||
debug("exec opts: pid=%llu threaded=%d collide=%d cover=%d comps=%d dedup=%d fault=%d/%d/%d prog=%llu\n",
|
||||
procid, flag_threaded, flag_collide, flag_collect_cover, flag_collect_comps,
|
||||
flag_dedup_cover, flag_inject_fault, flag_fault_call, flag_fault_nth,
|
||||
req.prog_size);
|
||||
if (req.prog_size == 0) {
|
||||
@ -754,7 +750,7 @@ uint64 read_const_arg(uint64** input_posp, uint64* size_p, uint64* bf_off_p, uin
|
||||
*bf_off_p = (meta >> 16) & 0xff;
|
||||
*bf_len_p = (meta >> 24) & 0xff;
|
||||
uint64 pid_stride = meta >> 32;
|
||||
val += pid_stride * flag_pid;
|
||||
val += pid_stride * procid;
|
||||
if (be) {
|
||||
switch (*size_p) {
|
||||
case 2:
|
||||
|
@ -119,103 +119,6 @@ int main(int argc, char** argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Tell parent that we are ready to serve.
|
||||
reply_handshake();
|
||||
checkpoint_net_namespace();
|
||||
|
||||
for (int iter = 0;; iter++) {
|
||||
// Create a new private work dir for this test (removed at the end of the loop).
|
||||
char cwdbuf[256];
|
||||
sprintf(cwdbuf, "./%d", iter);
|
||||
if (mkdir(cwdbuf, 0777))
|
||||
fail("failed to mkdir");
|
||||
|
||||
// TODO: consider moving the read into the child.
|
||||
// Potentially it can speed up things a bit -- when the read finishes
|
||||
// we already have a forked worker process.
|
||||
receive_execute(false);
|
||||
int pid = fork();
|
||||
if (pid < 0)
|
||||
fail("clone failed");
|
||||
if (pid == 0) {
|
||||
prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
|
||||
setpgrp();
|
||||
if (chdir(cwdbuf))
|
||||
fail("failed to chdir");
|
||||
close(kInPipeFd);
|
||||
close(kOutPipeFd);
|
||||
if (flag_enable_tun) {
|
||||
// Read all remaining packets from tun to better
|
||||
// isolate consequently executing programs.
|
||||
flush_tun();
|
||||
}
|
||||
output_pos = output_data;
|
||||
execute_one();
|
||||
debug("worker exiting\n");
|
||||
doexit(0);
|
||||
}
|
||||
debug("spawned worker pid %d\n", pid);
|
||||
|
||||
// We used to use sigtimedwait(SIGCHLD) to wait for the subprocess.
|
||||
// But SIGCHLD is also delivered when a process stops/continues,
|
||||
// so it would require a loop with status analysis and timeout recalculation.
|
||||
// SIGCHLD should also unblock the usleep below, so the spin loop
|
||||
// should be as efficient as sigtimedwait.
|
||||
int status = 0;
|
||||
uint64 start = current_time_ms();
|
||||
uint64 last_executed = start;
|
||||
uint32 executed_calls = __atomic_load_n(output_data, __ATOMIC_RELAXED);
|
||||
for (;;) {
|
||||
int res = waitpid(-1, &status, __WALL | WNOHANG);
|
||||
int errno0 = errno;
|
||||
if (res == pid) {
|
||||
debug("waitpid(%d)=%d (%d)\n", pid, res, errno0);
|
||||
break;
|
||||
}
|
||||
usleep(1000);
|
||||
// Even though the test process executes exit at the end
|
||||
// and execution time of each syscall is bounded by 20ms,
|
||||
// this backup watchdog is necessary and its performance is important.
|
||||
// The problem is that exit in the test processes can fail (sic).
|
||||
// One observed scenario is that the test processes prohibits
|
||||
// exit_group syscall using seccomp. Another observed scenario
|
||||
// is that the test processes setups a userfaultfd for itself,
|
||||
// then the main thread hangs when it wants to page in a page.
|
||||
// Below we check if the test process still executes syscalls
|
||||
// and kill it after 200ms of inactivity.
|
||||
uint64 now = current_time_ms();
|
||||
uint32 now_executed = __atomic_load_n(output_data, __ATOMIC_RELAXED);
|
||||
if (executed_calls != now_executed) {
|
||||
executed_calls = now_executed;
|
||||
last_executed = now;
|
||||
}
|
||||
if ((now - start < 3 * 1000) && (now - last_executed < 500))
|
||||
continue;
|
||||
debug("waitpid(%d)=%d (%d)\n", pid, res, errno0);
|
||||
debug("killing\n");
|
||||
kill(-pid, SIGKILL);
|
||||
kill(pid, SIGKILL);
|
||||
for (;;) {
|
||||
int res = waitpid(-1, &status, __WALL);
|
||||
debug("waitpid(%d)=%d (%d)\n", pid, res, errno);
|
||||
if (res == pid)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
status = WEXITSTATUS(status);
|
||||
if (status == kFailStatus)
|
||||
fail("child failed");
|
||||
if (status == kErrorStatus)
|
||||
error("child errored");
|
||||
reply_execute(0);
|
||||
remove_dir(cwdbuf);
|
||||
reset_net_namespace();
|
||||
}
|
||||
}
|
||||
|
||||
long execute_syscall(call_t* c, long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8)
|
||||
{
|
||||
if (c->call)
|
||||
|
@ -2,11 +2,11 @@
|
||||
|
||||
#if defined(__i386__) || 0
|
||||
#define GOARCH "386"
|
||||
#define SYZ_REVISION "b0cca0943b5017ba63ed5e3b325251612d061f21"
|
||||
#define SYZ_REVISION "c01f41f1487f5d5a5b0104b876d11c9af1090248"
|
||||
#define SYZ_PAGE_SIZE 4096
|
||||
#define SYZ_NUM_PAGES 4096
|
||||
#define SYZ_DATA_OFFSET 536870912
|
||||
unsigned syscall_count = 1613;
|
||||
unsigned syscall_count = 1626;
|
||||
call_t syscalls[] = {
|
||||
{"accept4", 364},
|
||||
{"accept4$alg", 364},
|
||||
@ -991,6 +991,7 @@ call_t syscalls[] = {
|
||||
{"mincore", 218},
|
||||
{"mkdir", 39},
|
||||
{"mkdirat", 296},
|
||||
{"mkdirat$cgroup", 296},
|
||||
{"mknod", 14},
|
||||
{"mknod$loop", 14},
|
||||
{"mknodat", 297},
|
||||
@ -1027,6 +1028,13 @@ call_t syscalls[] = {
|
||||
{"openat$audio", 295},
|
||||
{"openat$autofs", 295},
|
||||
{"openat$capi20", 295},
|
||||
{"openat$cgroup", 295},
|
||||
{"openat$cgroup_int", 295},
|
||||
{"openat$cgroup_procs", 295},
|
||||
{"openat$cgroup_ro", 295},
|
||||
{"openat$cgroup_root", 295},
|
||||
{"openat$cgroup_subtree", 295},
|
||||
{"openat$cgroup_type", 295},
|
||||
{"openat$cuse", 295},
|
||||
{"openat$dir", 295},
|
||||
{"openat$dsp", 295},
|
||||
@ -1080,6 +1088,7 @@ call_t syscalls[] = {
|
||||
{"openat$zygote", 295},
|
||||
{"pause", 29},
|
||||
{"perf_event_open", 336},
|
||||
{"perf_event_open$cgroup", 336},
|
||||
{"personality", 136},
|
||||
{"pipe", 42},
|
||||
{"pipe2", 331},
|
||||
@ -1607,6 +1616,10 @@ call_t syscalls[] = {
|
||||
{"wait4", 114},
|
||||
{"waitid", 284},
|
||||
{"write", 4},
|
||||
{"write$cgroup_int", 4},
|
||||
{"write$cgroup_pid", 4},
|
||||
{"write$cgroup_subtree", 4},
|
||||
{"write$cgroup_type", 4},
|
||||
{"write$evdev", 4},
|
||||
{"write$eventfd", 4},
|
||||
{"write$fuse", 4},
|
||||
@ -1627,11 +1640,11 @@ call_t syscalls[] = {
|
||||
|
||||
#if defined(__x86_64__) || 0
|
||||
#define GOARCH "amd64"
|
||||
#define SYZ_REVISION "c4e271d66e2dfd758cf369682d72bbf3590dedd0"
|
||||
#define SYZ_REVISION "b9c8e658cfa4e7d66e21b0a6c1fcddfe61acbeb2"
|
||||
#define SYZ_PAGE_SIZE 4096
|
||||
#define SYZ_NUM_PAGES 4096
|
||||
#define SYZ_DATA_OFFSET 536870912
|
||||
unsigned syscall_count = 1665;
|
||||
unsigned syscall_count = 1678;
|
||||
call_t syscalls[] = {
|
||||
{"accept", 43},
|
||||
{"accept$alg", 43},
|
||||
@ -2630,6 +2643,7 @@ call_t syscalls[] = {
|
||||
{"mincore", 27},
|
||||
{"mkdir", 83},
|
||||
{"mkdirat", 258},
|
||||
{"mkdirat$cgroup", 258},
|
||||
{"mknod", 133},
|
||||
{"mknod$loop", 133},
|
||||
{"mknodat", 259},
|
||||
@ -2676,6 +2690,13 @@ call_t syscalls[] = {
|
||||
{"openat$audio", 257},
|
||||
{"openat$autofs", 257},
|
||||
{"openat$capi20", 257},
|
||||
{"openat$cgroup", 257},
|
||||
{"openat$cgroup_int", 257},
|
||||
{"openat$cgroup_procs", 257},
|
||||
{"openat$cgroup_ro", 257},
|
||||
{"openat$cgroup_root", 257},
|
||||
{"openat$cgroup_subtree", 257},
|
||||
{"openat$cgroup_type", 257},
|
||||
{"openat$cuse", 257},
|
||||
{"openat$dir", 257},
|
||||
{"openat$dsp", 257},
|
||||
@ -2729,6 +2750,7 @@ call_t syscalls[] = {
|
||||
{"openat$zygote", 257},
|
||||
{"pause", 34},
|
||||
{"perf_event_open", 298},
|
||||
{"perf_event_open$cgroup", 298},
|
||||
{"personality", 135},
|
||||
{"pipe", 22},
|
||||
{"pipe2", 293},
|
||||
@ -3284,6 +3306,10 @@ call_t syscalls[] = {
|
||||
{"wait4", 61},
|
||||
{"waitid", 247},
|
||||
{"write", 1},
|
||||
{"write$cgroup_int", 1},
|
||||
{"write$cgroup_pid", 1},
|
||||
{"write$cgroup_subtree", 1},
|
||||
{"write$cgroup_type", 1},
|
||||
{"write$evdev", 1},
|
||||
{"write$eventfd", 1},
|
||||
{"write$fuse", 1},
|
||||
@ -3304,11 +3330,11 @@ call_t syscalls[] = {
|
||||
|
||||
#if defined(__arm__) || 0
|
||||
#define GOARCH "arm"
|
||||
#define SYZ_REVISION "07cef835f8b609cd2ffca0b97f77fa531c570b71"
|
||||
#define SYZ_REVISION "e7d1c116b96d76e3529774adf2b448f8717b76eb"
|
||||
#define SYZ_PAGE_SIZE 4096
|
||||
#define SYZ_NUM_PAGES 4096
|
||||
#define SYZ_DATA_OFFSET 536870912
|
||||
unsigned syscall_count = 1610;
|
||||
unsigned syscall_count = 1623;
|
||||
call_t syscalls[] = {
|
||||
{"accept", 285},
|
||||
{"accept$alg", 285},
|
||||
@ -4264,6 +4290,7 @@ call_t syscalls[] = {
|
||||
{"mincore", 219},
|
||||
{"mkdir", 39},
|
||||
{"mkdirat", 323},
|
||||
{"mkdirat$cgroup", 323},
|
||||
{"mknod", 14},
|
||||
{"mknod$loop", 14},
|
||||
{"mknodat", 324},
|
||||
@ -4306,6 +4333,13 @@ call_t syscalls[] = {
|
||||
{"openat$audio", 322},
|
||||
{"openat$autofs", 322},
|
||||
{"openat$capi20", 322},
|
||||
{"openat$cgroup", 322},
|
||||
{"openat$cgroup_int", 322},
|
||||
{"openat$cgroup_procs", 322},
|
||||
{"openat$cgroup_ro", 322},
|
||||
{"openat$cgroup_root", 322},
|
||||
{"openat$cgroup_subtree", 322},
|
||||
{"openat$cgroup_type", 322},
|
||||
{"openat$cuse", 322},
|
||||
{"openat$dir", 322},
|
||||
{"openat$dsp", 322},
|
||||
@ -4359,6 +4393,7 @@ call_t syscalls[] = {
|
||||
{"openat$zygote", 322},
|
||||
{"pause", 29},
|
||||
{"perf_event_open", 364},
|
||||
{"perf_event_open$cgroup", 364},
|
||||
{"personality", 136},
|
||||
{"pipe", 42},
|
||||
{"pipe2", 359},
|
||||
@ -4906,6 +4941,10 @@ call_t syscalls[] = {
|
||||
{"wait4", 114},
|
||||
{"waitid", 280},
|
||||
{"write", 4},
|
||||
{"write$cgroup_int", 4},
|
||||
{"write$cgroup_pid", 4},
|
||||
{"write$cgroup_subtree", 4},
|
||||
{"write$cgroup_type", 4},
|
||||
{"write$evdev", 4},
|
||||
{"write$eventfd", 4},
|
||||
{"write$fuse", 4},
|
||||
@ -4926,11 +4965,11 @@ call_t syscalls[] = {
|
||||
|
||||
#if defined(__aarch64__) || 0
|
||||
#define GOARCH "arm64"
|
||||
#define SYZ_REVISION "cac26d4197832d1b50b8b6ea469c8061b7405bc4"
|
||||
#define SYZ_REVISION "43a2d759c153cf5c6b39a47c64efd7abcf669c26"
|
||||
#define SYZ_PAGE_SIZE 4096
|
||||
#define SYZ_NUM_PAGES 4096
|
||||
#define SYZ_DATA_OFFSET 536870912
|
||||
unsigned syscall_count = 1594;
|
||||
unsigned syscall_count = 1607;
|
||||
call_t syscalls[] = {
|
||||
{"accept", 202},
|
||||
{"accept$alg", 202},
|
||||
@ -5886,6 +5925,7 @@ call_t syscalls[] = {
|
||||
{"migrate_pages", 238},
|
||||
{"mincore", 232},
|
||||
{"mkdirat", 34},
|
||||
{"mkdirat$cgroup", 34},
|
||||
{"mknodat", 33},
|
||||
{"mlock", 228},
|
||||
{"mlock2", 284},
|
||||
@ -5924,6 +5964,13 @@ call_t syscalls[] = {
|
||||
{"openat$audio", 56},
|
||||
{"openat$autofs", 56},
|
||||
{"openat$capi20", 56},
|
||||
{"openat$cgroup", 56},
|
||||
{"openat$cgroup_int", 56},
|
||||
{"openat$cgroup_procs", 56},
|
||||
{"openat$cgroup_ro", 56},
|
||||
{"openat$cgroup_root", 56},
|
||||
{"openat$cgroup_subtree", 56},
|
||||
{"openat$cgroup_type", 56},
|
||||
{"openat$cuse", 56},
|
||||
{"openat$dir", 56},
|
||||
{"openat$dsp", 56},
|
||||
@ -5976,6 +6023,7 @@ call_t syscalls[] = {
|
||||
{"openat$xenevtchn", 56},
|
||||
{"openat$zygote", 56},
|
||||
{"perf_event_open", 241},
|
||||
{"perf_event_open$cgroup", 241},
|
||||
{"personality", 92},
|
||||
{"pipe2", 59},
|
||||
{"pivot_root", 41},
|
||||
@ -6512,6 +6560,10 @@ call_t syscalls[] = {
|
||||
{"wait4", 260},
|
||||
{"waitid", 95},
|
||||
{"write", 64},
|
||||
{"write$cgroup_int", 64},
|
||||
{"write$cgroup_pid", 64},
|
||||
{"write$cgroup_subtree", 64},
|
||||
{"write$cgroup_type", 64},
|
||||
{"write$evdev", 64},
|
||||
{"write$eventfd", 64},
|
||||
{"write$fuse", 64},
|
||||
@ -6532,11 +6584,11 @@ call_t syscalls[] = {
|
||||
|
||||
#if defined(__ppc64__) || defined(__PPC64__) || defined(__powerpc64__) || 0
|
||||
#define GOARCH "ppc64le"
|
||||
#define SYZ_REVISION "d32421a63a0dd72f857a8cb4cdc483487132c60a"
|
||||
#define SYZ_REVISION "b84bf7ffe358a4f0f2e3375c1421e3e3dd5da519"
|
||||
#define SYZ_PAGE_SIZE 4096
|
||||
#define SYZ_NUM_PAGES 4096
|
||||
#define SYZ_DATA_OFFSET 536870912
|
||||
unsigned syscall_count = 1584;
|
||||
unsigned syscall_count = 1597;
|
||||
call_t syscalls[] = {
|
||||
{"accept", 330},
|
||||
{"accept$alg", 330},
|
||||
@ -7495,6 +7547,7 @@ call_t syscalls[] = {
|
||||
{"mincore", 206},
|
||||
{"mkdir", 39},
|
||||
{"mkdirat", 287},
|
||||
{"mkdirat$cgroup", 287},
|
||||
{"mknod", 14},
|
||||
{"mknod$loop", 14},
|
||||
{"mknodat", 288},
|
||||
@ -7531,6 +7584,13 @@ call_t syscalls[] = {
|
||||
{"openat$audio", 286},
|
||||
{"openat$autofs", 286},
|
||||
{"openat$capi20", 286},
|
||||
{"openat$cgroup", 286},
|
||||
{"openat$cgroup_int", 286},
|
||||
{"openat$cgroup_procs", 286},
|
||||
{"openat$cgroup_ro", 286},
|
||||
{"openat$cgroup_root", 286},
|
||||
{"openat$cgroup_subtree", 286},
|
||||
{"openat$cgroup_type", 286},
|
||||
{"openat$cuse", 286},
|
||||
{"openat$dir", 286},
|
||||
{"openat$dsp", 286},
|
||||
@ -7584,6 +7644,7 @@ call_t syscalls[] = {
|
||||
{"openat$zygote", 286},
|
||||
{"pause", 29},
|
||||
{"perf_event_open", 319},
|
||||
{"perf_event_open$cgroup", 319},
|
||||
{"personality", 136},
|
||||
{"pipe", 42},
|
||||
{"pipe2", 317},
|
||||
@ -8108,6 +8169,10 @@ call_t syscalls[] = {
|
||||
{"wait4", 114},
|
||||
{"waitid", 272},
|
||||
{"write", 4},
|
||||
{"write$cgroup_int", 4},
|
||||
{"write$cgroup_pid", 4},
|
||||
{"write$cgroup_subtree", 4},
|
||||
{"write$cgroup_type", 4},
|
||||
{"write$evdev", 4},
|
||||
{"write$eventfd", 4},
|
||||
{"write$fuse", 4},
|
||||
|
@ -8,10 +8,6 @@
|
||||
|
||||
#include <sys/utsname.h>
|
||||
|
||||
void loop()
|
||||
{
|
||||
} // to prevent warning: ‘void loop()’ used but never defined
|
||||
|
||||
extern "C" int test_copyin()
|
||||
{
|
||||
unsigned char x[4] = {};
|
||||
|
@ -78,6 +78,11 @@ typedef unsigned int uint32;
|
||||
typedef unsigned short uint16;
|
||||
typedef unsigned char uint8;
|
||||
|
||||
#ifdef SYZ_EXECUTOR
|
||||
const int kInPipeFd = 250;
|
||||
const int kOutPipeFd = 251;
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define SYSCALLAPI
|
||||
#define NORETURN __attribute__((noreturn))
|
||||
|
@ -89,6 +89,9 @@ func defineList(p *prog.Prog, opts Options) ([]string, error) {
|
||||
if opts.EnableTun {
|
||||
defines = append(defines, "SYZ_TUN_ENABLE")
|
||||
}
|
||||
if opts.EnableCgroups {
|
||||
defines = append(defines, "SYZ_ENABLE_CGROUPS")
|
||||
}
|
||||
if opts.UseTmpDir {
|
||||
defines = append(defines, "SYZ_USE_TMP_DIR")
|
||||
}
|
||||
|
@ -63,8 +63,8 @@ func Write(p *prog.Prog, opts Options) ([]byte, error) {
|
||||
}
|
||||
ctx.printf("};\n")
|
||||
}
|
||||
if opts.Procs > 1 {
|
||||
ctx.printf("uint64_t procid;\n")
|
||||
if opts.Procs > 1 || opts.EnableCgroups {
|
||||
ctx.printf("unsigned long long procid;\n")
|
||||
}
|
||||
|
||||
if !opts.Repeat {
|
||||
@ -93,7 +93,7 @@ func Write(p *prog.Prog, opts Options) ([]byte, error) {
|
||||
}
|
||||
ctx.print("\treturn 0;\n}\n")
|
||||
} else {
|
||||
ctx.generateTestFunc(calls, len(vars) != 0, "test")
|
||||
ctx.generateTestFunc(calls, len(vars) != 0, "execute_one")
|
||||
if opts.Procs <= 1 {
|
||||
ctx.print("int main()\n{\n")
|
||||
for _, c := range mmapCalls {
|
||||
|
@ -89,6 +89,7 @@ func TestGenerateOptions(t *testing.T) {
|
||||
permutations = allPermutations
|
||||
}
|
||||
for i, opts := range permutations {
|
||||
opts := opts
|
||||
t.Run(fmt.Sprintf("%v", i), func(t *testing.T) {
|
||||
target, rs, iters := initTest(t)
|
||||
t.Logf("opts: %+v", opts)
|
||||
|
@ -69,6 +69,11 @@ typedef unsigned int uint32;
|
||||
typedef unsigned short uint16;
|
||||
typedef unsigned char uint8;
|
||||
|
||||
#ifdef SYZ_EXECUTOR
|
||||
const int kInPipeFd = 250;
|
||||
const int kOutPipeFd = 251;
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define SYSCALLAPI
|
||||
#define NORETURN __attribute__((noreturn))
|
||||
|
@ -44,15 +44,20 @@ var commonHeaderLinux = `
|
||||
#include <sys/time.h>
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_FAULT_INJECTION) || defined(SYZ_SANDBOX_NAMESPACE) || \
|
||||
defined(SYZ_ENABLE_CGROUPS)
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_SANDBOX_SETUID)
|
||||
#include <grp.h>
|
||||
#endif
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_SANDBOX_NAMESPACE)
|
||||
#include <fcntl.h>
|
||||
#include <linux/capability.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_TUN_ENABLE)
|
||||
#include <arpa/inet.h>
|
||||
@ -121,11 +126,15 @@ var commonHeaderLinux = `
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#if defined(SYZ_EXECUTOR) || defined(__NR_syz_genetlink_get_family_id)
|
||||
#include <errno.h>
|
||||
#include <linux/genetlink.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_ENABLE_CGROUPS)
|
||||
#include <sys/mount.h>
|
||||
#endif
|
||||
|
||||
#if defined(SYZ_EXECUTOR) || (defined(SYZ_REPEAT) && defined(SYZ_WAIT_REPEAT)) || \
|
||||
defined(SYZ_USE_TMP_DIR) || defined(SYZ_HANDLE_SEGV) || defined(SYZ_TUN_ENABLE) || \
|
||||
@ -176,6 +185,11 @@ typedef unsigned int uint32;
|
||||
typedef unsigned short uint16;
|
||||
typedef unsigned char uint8;
|
||||
|
||||
#ifdef SYZ_EXECUTOR
|
||||
const int kInPipeFd = 250;
|
||||
const int kOutPipeFd = 251;
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define SYSCALLAPI
|
||||
#define NORETURN __attribute__((noreturn))
|
||||
@ -1857,6 +1871,74 @@ static uintptr_t syz_kvm_setup_cpu(uintptr_t a0, uintptr_t a1, uintptr_t a2, uin
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_FAULT_INJECTION) || defined(SYZ_SANDBOX_NAMESPACE) || \
|
||||
defined(SYZ_ENABLE_CGROUPS)
|
||||
static bool write_file(const char* file, const char* what, ...)
|
||||
{
|
||||
char buf[1024];
|
||||
va_list args;
|
||||
va_start(args, what);
|
||||
vsnprintf(buf, sizeof(buf), what, args);
|
||||
va_end(args);
|
||||
buf[sizeof(buf) - 1] = 0;
|
||||
int len = strlen(buf);
|
||||
|
||||
int fd = open(file, O_WRONLY | O_CLOEXEC);
|
||||
if (fd == -1)
|
||||
return false;
|
||||
if (write(fd, buf, len) != len) {
|
||||
int err = errno;
|
||||
close(fd);
|
||||
errno = err;
|
||||
return false;
|
||||
}
|
||||
close(fd);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_ENABLE_CGROUPS)
|
||||
static void setup_cgroups()
|
||||
{
|
||||
if (mkdir("/syzcgroup", 0777)) {
|
||||
debug("mkdir(/syzcgroup) failed: %d\n", errno);
|
||||
}
|
||||
if (mkdir("/syzcgroup/unified", 0777)) {
|
||||
debug("mkdir(/syzcgroup/unified) failed: %d\n", errno);
|
||||
}
|
||||
if (mount("none", "/syzcgroup/unified", "cgroup2", 0, NULL)) {
|
||||
debug("mount(cgroup2) failed: %d\n", errno);
|
||||
}
|
||||
if (chmod("/syzcgroup/unified", 0777)) {
|
||||
debug("chmod(/syzcgroup/unified) failed: %d\n", errno);
|
||||
}
|
||||
if (!write_file("/syzcgroup/unified/cgroup.subtree_control", "+cpu +memory +io +pids +rdma")) {
|
||||
debug("write(cgroup.subtree_control) failed: %d\n", errno);
|
||||
}
|
||||
if (mkdir("/syzcgroup/cpu", 0777)) {
|
||||
debug("mkdir(/syzcgroup/cpu) failed: %d\n", errno);
|
||||
}
|
||||
if (mount("none", "/syzcgroup/cpu", "cgroup", 0, "cpuset,cpuacct,perf_event,hugetlb")) {
|
||||
debug("mount(cgroup cpu) failed: %d\n", errno);
|
||||
}
|
||||
if (!write_file("/syzcgroup/cpu/cgroup.clone_children", "1")) {
|
||||
debug("write(/syzcgroup/cpu/cgroup.clone_children) failed: %d\n", errno);
|
||||
}
|
||||
if (chmod("/syzcgroup/cpu", 0777)) {
|
||||
debug("chmod(/syzcgroup/cpu) failed: %d\n", errno);
|
||||
}
|
||||
if (mkdir("/syzcgroup/net", 0777)) {
|
||||
debug("mkdir(/syzcgroup/net) failed: %d\n", errno);
|
||||
}
|
||||
if (mount("none", "/syzcgroup/net", "cgroup", 0, "net_cls,net_prio,devices,freezer")) {
|
||||
debug("mount(cgroup net) failed: %d\n", errno);
|
||||
}
|
||||
if (chmod("/syzcgroup/net", 0777)) {
|
||||
debug("chmod(/syzcgroup/net) failed: %d\n", errno);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_SANDBOX_NONE) || defined(SYZ_SANDBOX_SETUID) || defined(SYZ_SANDBOX_NAMESPACE)
|
||||
static void loop();
|
||||
|
||||
@ -1921,6 +2003,9 @@ static int do_sandbox_none(void)
|
||||
if (pid)
|
||||
return pid;
|
||||
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_ENABLE_CGROUPS)
|
||||
setup_cgroups();
|
||||
#endif
|
||||
sandbox_common();
|
||||
if (unshare(CLONE_NEWNET)) {
|
||||
debug("unshare(CLONE_NEWNET): %d\n", errno);
|
||||
@ -1946,6 +2031,9 @@ static int do_sandbox_setuid(void)
|
||||
if (pid)
|
||||
return pid;
|
||||
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_ENABLE_CGROUPS)
|
||||
setup_cgroups();
|
||||
#endif
|
||||
sandbox_common();
|
||||
if (unshare(CLONE_NEWNET))
|
||||
fail("unshare(CLONE_NEWNET)");
|
||||
@ -1969,29 +2057,6 @@ static int do_sandbox_setuid(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_SANDBOX_NAMESPACE) || defined(SYZ_FAULT_INJECTION)
|
||||
static bool write_file(const char* file, const char* what, ...)
|
||||
{
|
||||
char buf[1024];
|
||||
va_list args;
|
||||
va_start(args, what);
|
||||
vsnprintf(buf, sizeof(buf), what, args);
|
||||
va_end(args);
|
||||
buf[sizeof(buf) - 1] = 0;
|
||||
int len = strlen(buf);
|
||||
|
||||
int fd = open(file, O_WRONLY | O_CLOEXEC);
|
||||
if (fd == -1)
|
||||
return false;
|
||||
if (write(fd, buf, len) != len) {
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
close(fd);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_SANDBOX_NAMESPACE)
|
||||
static int real_uid;
|
||||
static int real_gid;
|
||||
@ -2038,6 +2103,29 @@ static int namespace_sandbox_proc(void* arg)
|
||||
if (mount("/sys/fs/selinux", selinux_path, NULL, mount_flags, NULL) && errno != ENOENT)
|
||||
fail("mount(/sys/fs/selinux) failed");
|
||||
}
|
||||
if (mkdir("./syz-tmp/newroot/sys", 0700))
|
||||
fail("mkdir failed");
|
||||
if (mount(NULL, "./syz-tmp/newroot/sys", "sysfs", 0, NULL))
|
||||
fail("mount(sysfs) failed");
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_ENABLE_CGROUPS)
|
||||
if (mkdir("./syz-tmp/newroot/syzcgroup", 0700))
|
||||
fail("mkdir failed");
|
||||
if (mkdir("./syz-tmp/newroot/syzcgroup/unified", 0700))
|
||||
fail("mkdir failed");
|
||||
if (mkdir("./syz-tmp/newroot/syzcgroup/cpu", 0700))
|
||||
fail("mkdir failed");
|
||||
if (mkdir("./syz-tmp/newroot/syzcgroup/net", 0700))
|
||||
fail("mkdir failed");
|
||||
if (mount("/syzcgroup/unified", "./syz-tmp/newroot/syzcgroup/unified", NULL, mount_flags, NULL)) {
|
||||
debug("mount(cgroup2, MS_BIND) failed: %d\n", errno);
|
||||
}
|
||||
if (mount("/syzcgroup/cpu", "./syz-tmp/newroot/syzcgroup/cpu", NULL, mount_flags, NULL)) {
|
||||
debug("mount(cgroup/cpu, MS_BIND) failed: %d\n", errno);
|
||||
}
|
||||
if (mount("/syzcgroup/net", "./syz-tmp/newroot/syzcgroup/net", NULL, mount_flags, NULL)) {
|
||||
debug("mount(cgroup/net, MS_BIND) failed: %d\n", errno);
|
||||
}
|
||||
#endif
|
||||
if (mkdir("./syz-tmp/pivot", 0777))
|
||||
fail("mkdir failed");
|
||||
if (syscall(SYS_pivot_root, "./syz-tmp", "./syz-tmp/pivot")) {
|
||||
@ -2076,6 +2164,9 @@ static int do_sandbox_namespace(void)
|
||||
{
|
||||
int pid;
|
||||
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_ENABLE_CGROUPS)
|
||||
setup_cgroups();
|
||||
#endif
|
||||
real_uid = getuid();
|
||||
real_gid = getgid();
|
||||
mprotect(sandbox_stack, 4096, PROT_NONE);
|
||||
@ -2577,58 +2668,163 @@ static int fault_injected(int fail_fd)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(SYZ_REPEAT)
|
||||
static void test();
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_REPEAT)
|
||||
static void execute_one();
|
||||
extern unsigned long long procid;
|
||||
|
||||
#if defined(SYZ_WAIT_REPEAT)
|
||||
void loop()
|
||||
#if defined(SYZ_EXECUTOR)
|
||||
void reply_handshake();
|
||||
void receive_execute(bool need_prog);
|
||||
void reply_execute(int status);
|
||||
extern uint32* output_data;
|
||||
extern uint32* output_pos;
|
||||
#endif
|
||||
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_WAIT_REPEAT)
|
||||
static void loop()
|
||||
{
|
||||
int iter;
|
||||
#if defined(SYZ_RESET_NET_NAMESPACE)
|
||||
#if defined(SYZ_EXECUTOR)
|
||||
reply_handshake();
|
||||
#endif
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_RESET_NET_NAMESPACE)
|
||||
checkpoint_net_namespace();
|
||||
#endif
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_ENABLE_CGROUPS)
|
||||
char cgroupdir[64];
|
||||
snprintf(cgroupdir, sizeof(cgroupdir), "/syzcgroup/unified/syz%llu", procid);
|
||||
char cgroupdir_cpu[64];
|
||||
snprintf(cgroupdir_cpu, sizeof(cgroupdir_cpu), "/syzcgroup/cpu/syz%llu", procid);
|
||||
char cgroupdir_net[64];
|
||||
snprintf(cgroupdir_net, sizeof(cgroupdir_net), "/syzcgroup/net/syz%llu", procid);
|
||||
#endif
|
||||
int iter;
|
||||
for (iter = 0;; iter++) {
|
||||
#ifdef SYZ_USE_TMP_DIR
|
||||
char cwdbuf[256];
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_USE_TMP_DIR)
|
||||
char cwdbuf[32];
|
||||
sprintf(cwdbuf, "./%d", iter);
|
||||
if (mkdir(cwdbuf, 0777))
|
||||
fail("failed to mkdir");
|
||||
#endif
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_ENABLE_CGROUPS)
|
||||
if (mkdir(cgroupdir, 0777)) {
|
||||
debug("mkdir(%s) failed: %d\n", cgroupdir, errno);
|
||||
}
|
||||
if (mkdir(cgroupdir_cpu, 0777)) {
|
||||
debug("mkdir(%s) failed: %d\n", cgroupdir_cpu, errno);
|
||||
}
|
||||
if (mkdir(cgroupdir_net, 0777)) {
|
||||
debug("mkdir(%s) failed: %d\n", cgroupdir_net, errno);
|
||||
}
|
||||
#endif
|
||||
#if defined(SYZ_EXECUTOR)
|
||||
receive_execute(false);
|
||||
#endif
|
||||
int pid = fork();
|
||||
if (pid < 0)
|
||||
fail("loop fork failed");
|
||||
fail("clone failed");
|
||||
if (pid == 0) {
|
||||
prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
|
||||
setpgrp();
|
||||
#ifdef SYZ_USE_TMP_DIR
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_USE_TMP_DIR)
|
||||
if (chdir(cwdbuf))
|
||||
fail("failed to chdir");
|
||||
#endif
|
||||
#ifdef SYZ_TUN_ENABLE
|
||||
#if defined(SYZ_EXECUTOR)
|
||||
close(kInPipeFd);
|
||||
close(kOutPipeFd);
|
||||
#endif
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_ENABLE_CGROUPS)
|
||||
if (symlink(cgroupdir, "./cgroup")) {
|
||||
debug("symlink(%s, ./cgroup) failed: %d\n", cgroupdir, errno);
|
||||
}
|
||||
if (symlink(cgroupdir_cpu, "./cgroup.cpu")) {
|
||||
debug("symlink(%s, ./cgroup.cpu) failed: %d\n", cgroupdir_cpu, errno);
|
||||
}
|
||||
if (symlink(cgroupdir_net, "./cgroup.net")) {
|
||||
debug("symlink(%s, ./cgroup.net) failed: %d\n", cgroupdir_net, errno);
|
||||
}
|
||||
int pid = getpid();
|
||||
if (!write_file("./cgroup/cgroup.procs", "%d", pid)) {
|
||||
debug("write(./cgroup/cgroup.procs) failed: %d\n", errno);
|
||||
}
|
||||
if (!write_file("./cgroup.cpu/cgroup.procs", "%d", pid)) {
|
||||
debug("write(./cgroup.cpu/cgroup.procs) failed: %d\n", errno);
|
||||
}
|
||||
if (!write_file("./cgroup.net/cgroup.procs", "%d", pid)) {
|
||||
debug("write(./cgroup.net/cgroup.procs) failed: %d\n", errno);
|
||||
}
|
||||
#endif
|
||||
#if defined(SYZ_EXECUTOR)
|
||||
if (flag_enable_tun) {
|
||||
flush_tun();
|
||||
}
|
||||
output_pos = output_data;
|
||||
#elif defined(SYZ_TUN_ENABLE)
|
||||
flush_tun();
|
||||
#endif
|
||||
test();
|
||||
execute_one();
|
||||
debug("worker exiting\n");
|
||||
doexit(0);
|
||||
}
|
||||
debug("spawned worker pid %d\n", pid);
|
||||
|
||||
int status = 0;
|
||||
uint64 start = current_time_ms();
|
||||
#if defined(SYZ_EXECUTOR)
|
||||
uint64 last_executed = start;
|
||||
uint32 executed_calls = __atomic_load_n(output_data, __ATOMIC_RELAXED);
|
||||
#endif
|
||||
for (;;) {
|
||||
int res = waitpid(-1, &status, __WALL | WNOHANG);
|
||||
if (res == pid)
|
||||
break;
|
||||
usleep(1000);
|
||||
if (current_time_ms() - start > 5 * 1000) {
|
||||
kill(-pid, SIGKILL);
|
||||
kill(pid, SIGKILL);
|
||||
while (waitpid(-1, &status, __WALL) != pid) {
|
||||
}
|
||||
if (res == pid) {
|
||||
debug("waitpid(%d)=%d\n", pid, res);
|
||||
break;
|
||||
}
|
||||
usleep(1000);
|
||||
#if defined(SYZ_EXECUTOR)
|
||||
uint64 now = current_time_ms();
|
||||
uint32 now_executed = __atomic_load_n(output_data, __ATOMIC_RELAXED);
|
||||
if (executed_calls != now_executed) {
|
||||
executed_calls = now_executed;
|
||||
last_executed = now;
|
||||
}
|
||||
if ((now - start < 3 * 1000) && (now - last_executed < 500))
|
||||
continue;
|
||||
#else
|
||||
if (current_time_ms() - start < 3 * 1000)
|
||||
continue;
|
||||
#endif
|
||||
debug("waitpid(%d)=%d\n", pid, res);
|
||||
debug("killing\n");
|
||||
kill(-pid, SIGKILL);
|
||||
kill(pid, SIGKILL);
|
||||
while (waitpid(-1, &status, __WALL) != pid) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
#ifdef SYZ_USE_TMP_DIR
|
||||
#if defined(SYZ_EXECUTOR)
|
||||
status = WEXITSTATUS(status);
|
||||
if (status == kFailStatus)
|
||||
fail("child failed");
|
||||
if (status == kErrorStatus)
|
||||
error("child errored");
|
||||
reply_execute(0);
|
||||
#endif
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_USE_TMP_DIR)
|
||||
remove_dir(cwdbuf);
|
||||
#endif
|
||||
#if defined(SYZ_RESET_NET_NAMESPACE)
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_ENABLE_CGROUPS)
|
||||
if (rmdir(cgroupdir)) {
|
||||
debug("rmdir(%s) failed: %d\n", cgroupdir, errno);
|
||||
}
|
||||
if (rmdir(cgroupdir_cpu)) {
|
||||
debug("rmdir(%s) failed: %d\n", cgroupdir_cpu, errno);
|
||||
}
|
||||
if (rmdir(cgroupdir_net)) {
|
||||
debug("rmdir(%s) failed: %d\n", cgroupdir_net, errno);
|
||||
}
|
||||
#endif
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_RESET_NET_NAMESPACE)
|
||||
reset_net_namespace();
|
||||
#endif
|
||||
}
|
||||
@ -2637,7 +2833,7 @@ void loop()
|
||||
void loop()
|
||||
{
|
||||
while (1) {
|
||||
test();
|
||||
execute_one();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -69,6 +69,11 @@ typedef unsigned int uint32;
|
||||
typedef unsigned short uint16;
|
||||
typedef unsigned char uint8;
|
||||
|
||||
#ifdef SYZ_EXECUTOR
|
||||
const int kInPipeFd = 250;
|
||||
const int kOutPipeFd = 251;
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define SYSCALLAPI
|
||||
#define NORETURN __attribute__((noreturn))
|
||||
|
@ -23,11 +23,12 @@ type Options struct {
|
||||
FaultNth int
|
||||
|
||||
// These options allow for a more fine-tuned control over the generated C code.
|
||||
EnableTun bool
|
||||
UseTmpDir bool
|
||||
HandleSegv bool
|
||||
WaitRepeat bool
|
||||
Debug bool
|
||||
EnableTun bool
|
||||
UseTmpDir bool
|
||||
EnableCgroups bool
|
||||
HandleSegv bool
|
||||
WaitRepeat bool
|
||||
Debug bool
|
||||
|
||||
// Generate code for use with repro package to prints log messages,
|
||||
// which allows to distinguish between a hang and an absent crash.
|
||||
@ -55,6 +56,15 @@ func (opts Options) Check() error {
|
||||
// which will fail if procs>1 and on second run of the program.
|
||||
return errors.New("Sandbox=namespace without UseTmpDir")
|
||||
}
|
||||
if opts.EnableTun && opts.Sandbox == "" {
|
||||
return errors.New("EnableTun without sandbox")
|
||||
}
|
||||
if opts.EnableCgroups && opts.Sandbox == "" {
|
||||
return errors.New("EnableCgroups without sandbox")
|
||||
}
|
||||
if opts.EnableCgroups && !opts.UseTmpDir {
|
||||
return errors.New("EnableCgroups without UseTmpDir")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -72,14 +82,30 @@ func DeserializeOptions(data []byte) (Options, error) {
|
||||
&opts.Threaded, &opts.Collide, &opts.Repeat, &opts.Procs, &opts.Sandbox,
|
||||
&opts.Fault, &opts.FaultCall, &opts.FaultNth, &opts.EnableTun, &opts.UseTmpDir,
|
||||
&opts.HandleSegv, &opts.WaitRepeat, &opts.Debug, &opts.Repro)
|
||||
if err != nil {
|
||||
return opts, fmt.Errorf("failed to parse repro options: %v", err)
|
||||
if err == nil {
|
||||
if want := 14; n != want {
|
||||
return opts, fmt.Errorf("failed to parse repro options: got %v fields, want %v", n, want)
|
||||
}
|
||||
if opts.Sandbox == "empty" {
|
||||
opts.Sandbox = ""
|
||||
}
|
||||
return opts, nil
|
||||
}
|
||||
if want := 14; n != want {
|
||||
return opts, fmt.Errorf("failed to parse repro options: got %v fields, want %v", n, want)
|
||||
n, err = fmt.Sscanf(string(data),
|
||||
"{Threaded:%t Collide:%t Repeat:%t Procs:%d Sandbox:%s"+
|
||||
" Fault:%t FaultCall:%d FaultNth:%d EnableTun:%t UseTmpDir:%t"+
|
||||
" EnableCgroups:%t HandleSegv:%t WaitRepeat:%t Debug:%t Repro:%t}",
|
||||
&opts.Threaded, &opts.Collide, &opts.Repeat, &opts.Procs, &opts.Sandbox,
|
||||
&opts.Fault, &opts.FaultCall, &opts.FaultNth, &opts.EnableTun, &opts.UseTmpDir,
|
||||
&opts.EnableCgroups, &opts.HandleSegv, &opts.WaitRepeat, &opts.Debug, &opts.Repro)
|
||||
if err == nil {
|
||||
if want := 15; n != want {
|
||||
return opts, fmt.Errorf("failed to parse repro options: got %v fields, want %v", n, want)
|
||||
}
|
||||
if opts.Sandbox == "empty" {
|
||||
opts.Sandbox = ""
|
||||
}
|
||||
return opts, nil
|
||||
}
|
||||
if opts.Sandbox == "empty" {
|
||||
opts.Sandbox = ""
|
||||
}
|
||||
return opts, nil
|
||||
return opts, err
|
||||
}
|
||||
|
@ -29,36 +29,55 @@ func TestParseOptionsCanned(t *testing.T) {
|
||||
// so we need to be able to parse old formats.
|
||||
canned := map[string]Options{
|
||||
"{Threaded:true Collide:true Repeat:true Procs:1 Sandbox:none Fault:false FaultCall:-1 FaultNth:0 EnableTun:true UseTmpDir:true HandleSegv:true WaitRepeat:true Debug:false Repro:false}": Options{
|
||||
Threaded: true,
|
||||
Collide: true,
|
||||
Repeat: true,
|
||||
Procs: 1,
|
||||
Sandbox: "none",
|
||||
Fault: false,
|
||||
FaultCall: -1,
|
||||
FaultNth: 0,
|
||||
EnableTun: true,
|
||||
UseTmpDir: true,
|
||||
HandleSegv: true,
|
||||
WaitRepeat: true,
|
||||
Debug: false,
|
||||
Repro: false,
|
||||
Threaded: true,
|
||||
Collide: true,
|
||||
Repeat: true,
|
||||
Procs: 1,
|
||||
Sandbox: "none",
|
||||
Fault: false,
|
||||
FaultCall: -1,
|
||||
FaultNth: 0,
|
||||
EnableTun: true,
|
||||
UseTmpDir: true,
|
||||
EnableCgroups: false,
|
||||
HandleSegv: true,
|
||||
WaitRepeat: true,
|
||||
Debug: false,
|
||||
Repro: false,
|
||||
},
|
||||
"{Threaded:true Collide:true Repeat:true Procs:1 Sandbox: Fault:false FaultCall:-1 FaultNth:0 EnableTun:true UseTmpDir:true HandleSegv:true WaitRepeat:true Debug:false Repro:false}": Options{
|
||||
Threaded: true,
|
||||
Collide: true,
|
||||
Repeat: true,
|
||||
Procs: 1,
|
||||
Sandbox: "",
|
||||
Fault: false,
|
||||
FaultCall: -1,
|
||||
FaultNth: 0,
|
||||
EnableTun: true,
|
||||
UseTmpDir: true,
|
||||
HandleSegv: true,
|
||||
WaitRepeat: true,
|
||||
Debug: false,
|
||||
Repro: false,
|
||||
Threaded: true,
|
||||
Collide: true,
|
||||
Repeat: true,
|
||||
Procs: 1,
|
||||
Sandbox: "",
|
||||
Fault: false,
|
||||
FaultCall: -1,
|
||||
FaultNth: 0,
|
||||
EnableTun: true,
|
||||
UseTmpDir: true,
|
||||
EnableCgroups: false,
|
||||
HandleSegv: true,
|
||||
WaitRepeat: true,
|
||||
Debug: false,
|
||||
Repro: false,
|
||||
},
|
||||
"{Threaded:false Collide:true Repeat:true Procs:1 Sandbox:namespace Fault:false FaultCall:-1 FaultNth:0 EnableTun:true UseTmpDir:true EnableCgroups:true HandleSegv:true WaitRepeat:true Debug:false Repro:false}": Options{
|
||||
Threaded: false,
|
||||
Collide: true,
|
||||
Repeat: true,
|
||||
Procs: 1,
|
||||
Sandbox: "namespace",
|
||||
Fault: false,
|
||||
FaultCall: -1,
|
||||
FaultNth: 0,
|
||||
EnableTun: true,
|
||||
UseTmpDir: true,
|
||||
EnableCgroups: true,
|
||||
HandleSegv: true,
|
||||
WaitRepeat: true,
|
||||
Debug: false,
|
||||
Repro: false,
|
||||
},
|
||||
}
|
||||
for data, want := range canned {
|
||||
@ -76,7 +95,15 @@ func allOptionsSingle() []Options {
|
||||
var opts []Options
|
||||
fields := reflect.TypeOf(Options{}).NumField()
|
||||
for i := 0; i < fields; i++ {
|
||||
opts = append(opts, enumerateField(Options{}, i)...)
|
||||
// Because of constraints on options, we need some defaults
|
||||
// (e.g. no collide without threaded).
|
||||
opt := Options{
|
||||
Threaded: true,
|
||||
Repeat: true,
|
||||
Sandbox: "none",
|
||||
UseTmpDir: true,
|
||||
}
|
||||
opts = append(opts, enumerateField(opt, i)...)
|
||||
}
|
||||
return opts
|
||||
}
|
||||
|
@ -155,7 +155,7 @@ func isSupportedSocket(c *prog.Syscall) bool {
|
||||
|
||||
func isSupportedOpenAt(c *prog.Syscall) bool {
|
||||
fname, ok := extractStringConst(c.Args[1])
|
||||
if !ok {
|
||||
if !ok || len(fname) == 0 || fname[0] != '/' {
|
||||
return true
|
||||
}
|
||||
fd, err := syscall.Open(fname, syscall.O_RDONLY, 0)
|
||||
|
@ -41,6 +41,7 @@ for i in {0..31}; do
|
||||
echo "KERNEL==\"binder$i\", NAME=\"binder$i\", MODE=\"0666\"" | \
|
||||
tee -a disk.mnt/etc/udev/50-binder.rules
|
||||
done
|
||||
echo 'SELINUX=disabled' | sudo tee disk.mnt/etc/selinux/config
|
||||
|
||||
echo "kernel.printk = 7 4 1 3" | sudo tee -a disk.mnt/etc/sysctl.conf
|
||||
echo "debug.exception-trace = 0" | sudo tee -a disk.mnt/etc/sysctl.conf
|
||||
|
@ -291,16 +291,17 @@ func (ctx *context) extractProg(entries []*prog.LogEntry) (*Result, error) {
|
||||
|
||||
func (ctx *context) createDefaultOps() csource.Options {
|
||||
opts := csource.Options{
|
||||
Threaded: true,
|
||||
Collide: true,
|
||||
Repeat: true,
|
||||
Procs: ctx.cfg.Procs,
|
||||
Sandbox: ctx.cfg.Sandbox,
|
||||
EnableTun: true,
|
||||
UseTmpDir: true,
|
||||
HandleSegv: true,
|
||||
WaitRepeat: true,
|
||||
Repro: true,
|
||||
Threaded: true,
|
||||
Collide: true,
|
||||
Repeat: true,
|
||||
Procs: ctx.cfg.Procs,
|
||||
Sandbox: ctx.cfg.Sandbox,
|
||||
EnableTun: true,
|
||||
EnableCgroups: true,
|
||||
UseTmpDir: true,
|
||||
HandleSegv: true,
|
||||
WaitRepeat: true,
|
||||
Repro: true,
|
||||
}
|
||||
return opts
|
||||
}
|
||||
@ -816,6 +817,8 @@ var cSimplifies = append(progSimplifies, []Simplify{
|
||||
return false
|
||||
}
|
||||
opts.Sandbox = ""
|
||||
opts.EnableTun = false
|
||||
opts.EnableCgroups = false
|
||||
return true
|
||||
},
|
||||
func(opts *csource.Options) bool {
|
||||
@ -826,7 +829,14 @@ var cSimplifies = append(progSimplifies, []Simplify{
|
||||
return true
|
||||
},
|
||||
func(opts *csource.Options) bool {
|
||||
if !opts.UseTmpDir || opts.Sandbox == "namespace" {
|
||||
if !opts.EnableCgroups {
|
||||
return false
|
||||
}
|
||||
opts.EnableCgroups = false
|
||||
return true
|
||||
},
|
||||
func(opts *csource.Options) bool {
|
||||
if !opts.UseTmpDir || opts.Sandbox == "namespace" || opts.EnableCgroups {
|
||||
return false
|
||||
}
|
||||
opts.UseTmpDir = false
|
||||
|
@ -67,16 +67,17 @@ func TestBisect(t *testing.T) {
|
||||
|
||||
func TestSimplifies(t *testing.T) {
|
||||
opts := csource.Options{
|
||||
Threaded: true,
|
||||
Collide: true,
|
||||
Repeat: true,
|
||||
Procs: 10,
|
||||
Sandbox: "namespace",
|
||||
EnableTun: true,
|
||||
UseTmpDir: true,
|
||||
HandleSegv: true,
|
||||
WaitRepeat: true,
|
||||
Repro: true,
|
||||
Threaded: true,
|
||||
Collide: true,
|
||||
Repeat: true,
|
||||
Procs: 10,
|
||||
Sandbox: "namespace",
|
||||
EnableTun: true,
|
||||
EnableCgroups: true,
|
||||
UseTmpDir: true,
|
||||
HandleSegv: true,
|
||||
WaitRepeat: true,
|
||||
Repro: true,
|
||||
}
|
||||
var check func(opts csource.Options, i int)
|
||||
check = func(opts csource.Options, i int) {
|
||||
|
106
sys/linux/386.go
106
sys/linux/386.go
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
106
sys/linux/arm.go
106
sys/linux/arm.go
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -267,8 +267,7 @@ bpf_obj_get {
|
||||
}
|
||||
|
||||
bpf_attach_arg {
|
||||
# TODO: this must be cgroup fd (obtained by opening cgroup dir)
|
||||
target_fd fd
|
||||
target_fd fd_cgroup
|
||||
attach_bpf_fd fd_bpf_prog
|
||||
type flags[bpf_attach_type, int32]
|
||||
flags flags[bpf_attach_flags, int32]
|
||||
@ -331,8 +330,7 @@ bpf_map_info {
|
||||
} [align_8]
|
||||
|
||||
bpf_prog_query {
|
||||
# TODO: this must be cgroup fd (obtained by opening cgroup dir)
|
||||
target_fd fd
|
||||
target_fd fd_cgroup
|
||||
attach_type flags[bpf_prog_query_attach_type, int32]
|
||||
query_flags flags[bpf_prog_query_flags, int32]
|
||||
attach_flags int32
|
||||
|
56
sys/linux/cgroup.txt
Normal file
56
sys/linux/cgroup.txt
Normal file
@ -0,0 +1,56 @@
|
||||
# Copyright 2018 syzkaller project authors. All rights reserved.
|
||||
# Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
||||
|
||||
include <uapi/linux/fcntl.h>
|
||||
|
||||
resource fd_cgroup[fd]
|
||||
resource fd_cgroup_type[fd]
|
||||
resource fd_cgroup_subtree[fd]
|
||||
resource fd_cgroup_int[fd]
|
||||
resource fd_cgroup_pid[fd]
|
||||
|
||||
openat$cgroup_root(fd const[AT_FDCWD], file ptr[in, string[cgroup_dirs]], flags const[CGROUP_OPEN_FLAGS], mode const[0]) fd_cgroup
|
||||
openat$cgroup(fd fd_cgroup, file ptr[in, string[cgroup_names]], flags const[CGROUP_OPEN_FLAGS], mode const[0]) fd_cgroup
|
||||
mkdirat$cgroup(fd fd_cgroup, path ptr[in, string[cgroup_names]], mode flags[open_mode])
|
||||
openat$cgroup_ro(fd fd_cgroup, file ptr[in, string[cgroup_ctrl_read]], flags const[O_RDONLY], mode const[0]) fd
|
||||
openat$cgroup_int(fd fd_cgroup, file ptr[in, string[cgroup_ctrl_int]], flags const[O_RDWR], mode const[0]) fd_cgroup_int
|
||||
openat$cgroup_procs(fd fd_cgroup, file ptr[in, string[cgroup_proc_files]], flags const[O_RDWR], mode const[0]) fd_cgroup_pid
|
||||
openat$cgroup_subtree(fd fd_cgroup, file ptr[in, string["cgroup.subtree_control"]], flags const[O_RDWR], mode const[0]) fd_cgroup_subtree
|
||||
openat$cgroup_type(fd fd_cgroup, file ptr[in, string["cgroup.type"]], flags const[O_RDWR], mode const[0]) fd_cgroup_type
|
||||
write$cgroup_int(fd fd_cgroup_int, buf ptr[in, cgroup_int], len bytesize[buf])
|
||||
write$cgroup_pid(fd fd_cgroup_pid, buf ptr[in, cgroup_pid], len bytesize[buf])
|
||||
write$cgroup_subtree(fd fd_cgroup_subtree, buf ptr[in, cgroup_subtree], len bytesize[buf])
|
||||
write$cgroup_type(fd fd_cgroup_type, buf ptr[in, string["threaded"]], len bytesize[buf])
|
||||
|
||||
cgroup_int {
|
||||
digits array[flags[cgroup_digits, int8]]
|
||||
} [packed]
|
||||
|
||||
# TODO: these are bad pid's. We need something like sprintf["%v", pid].
|
||||
cgroup_pid {
|
||||
digits array[int8[48:57]]
|
||||
} [packed]
|
||||
|
||||
cgroup_subtree {
|
||||
controls array[cgroup_control]
|
||||
} [packed]
|
||||
|
||||
cgroup_control {
|
||||
sign flags[cgroup_control_signs, int8]
|
||||
subsys stringnoz[cgroup_subsystems]
|
||||
sp const[32, int8]
|
||||
} [packed]
|
||||
|
||||
cgroup_dirs = "./cgroup", "./cgroup.cpu", "./cgroup.net"
|
||||
cgroup_names = "syz0", "syz1"
|
||||
cgroup_paths = "./cgroup", "./cgroup.cpu", "./cgroup.net", "./cgroup/syz0", "./cgroup.cpu/syz0", "./cgroup.net/syz0", "./cgroup/syz1", "./cgroup.cpu/syz1", "./cgroup.net/syz1"
|
||||
# '+', '-'
|
||||
cgroup_control_signs = 43, 45
|
||||
# '+', '-', ',', '/', ';' and digits
|
||||
cgroup_digits = 0, 43, 45, 44, 47, 58, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57
|
||||
cgroup_subsystems = "cpu", "memory", "io", "pids", "rdma"
|
||||
cgroup_proc_files = "cgroup.procs", "cgroup.threads", "tasks"
|
||||
cgroup_ctrl_read = "cgroup.controllers", "cgroup.events", "cgroup.stat", "cpu.stat", "cpu.stat", "io.stat", "memory.current", "memory.events", "memory.stat", "memory.swap.current", "pids.current", "pids.events", "rdma.current", "cpuacct.stat", "cpuacct.usage_all", "cpuacct.usage_percpu", "cpuacct.usage_percpu_sys", "cpuacct.usage_percpu_user", "cpuacct.usage_sys", "cpuacct.usage_user", "cpuset.effective_cpus", "cpuset.effective_mems", "cpuset.memory_pressure", "hugetlb.2MB.usage_in_bytes"
|
||||
cgroup_ctrl_int = "cgroup.max.depth", "cgroup.max.descendants", "cpu.weight", "cpu.weight.nice", "io.bfq.weight", "io.max", "io.weight", "memory.high", "memory.low", "memory.max", "memory.swap.max", "pids.max", "rdma.max", "cgroup.clone_children", "cpuacct.usage", "cpuset.cpu_exclusive", "cpuset.cpus", "cpuset.mem_exclusive", "cpuset.mem_hardwall", "cpuset.memory_migrate", "cpuset.memory_spread_page", "cpuset.memory_spread_slab", "cpuset.mems", "cpuset.sched_load_balance", "cpuset.sched_relax_domain_level", "hugetlb.2MB.failcnt", "hugetlb.2MB.limit_in_bytes", "hugetlb.2MB.max_usage_in_bytes", "notify_on_release"
|
||||
|
||||
define CGROUP_OPEN_FLAGS O_RDWR | O_PATH
|
8
sys/linux/cgroup_386.const
Normal file
8
sys/linux/cgroup_386.const
Normal file
@ -0,0 +1,8 @@
|
||||
# AUTOGENERATED FILE
|
||||
AT_FDCWD = 18446744073709551516
|
||||
CGROUP_OPEN_FLAGS = 2097154
|
||||
O_RDONLY = 0
|
||||
O_RDWR = 2
|
||||
__NR_mkdirat = 296
|
||||
__NR_openat = 295
|
||||
__NR_write = 4
|
8
sys/linux/cgroup_amd64.const
Normal file
8
sys/linux/cgroup_amd64.const
Normal file
@ -0,0 +1,8 @@
|
||||
# AUTOGENERATED FILE
|
||||
AT_FDCWD = 18446744073709551516
|
||||
CGROUP_OPEN_FLAGS = 2097154
|
||||
O_RDONLY = 0
|
||||
O_RDWR = 2
|
||||
__NR_mkdirat = 258
|
||||
__NR_openat = 257
|
||||
__NR_write = 1
|
8
sys/linux/cgroup_arm.const
Normal file
8
sys/linux/cgroup_arm.const
Normal file
@ -0,0 +1,8 @@
|
||||
# AUTOGENERATED FILE
|
||||
AT_FDCWD = 18446744073709551516
|
||||
CGROUP_OPEN_FLAGS = 2097154
|
||||
O_RDONLY = 0
|
||||
O_RDWR = 2
|
||||
__NR_mkdirat = 323
|
||||
__NR_openat = 322
|
||||
__NR_write = 4
|
8
sys/linux/cgroup_arm64.const
Normal file
8
sys/linux/cgroup_arm64.const
Normal file
@ -0,0 +1,8 @@
|
||||
# AUTOGENERATED FILE
|
||||
AT_FDCWD = 18446744073709551516
|
||||
CGROUP_OPEN_FLAGS = 2097154
|
||||
O_RDONLY = 0
|
||||
O_RDWR = 2
|
||||
__NR_mkdirat = 34
|
||||
__NR_openat = 56
|
||||
__NR_write = 64
|
8
sys/linux/cgroup_ppc64le.const
Normal file
8
sys/linux/cgroup_ppc64le.const
Normal file
@ -0,0 +1,8 @@
|
||||
# AUTOGENERATED FILE
|
||||
AT_FDCWD = 18446744073709551516
|
||||
CGROUP_OPEN_FLAGS = 2097154
|
||||
O_RDONLY = 0
|
||||
O_RDWR = 2
|
||||
__NR_mkdirat = 287
|
||||
__NR_openat = 286
|
||||
__NR_write = 4
|
@ -195,8 +195,7 @@ xt_cgroup_info_v1 {
|
||||
has_classid bool8
|
||||
invert_path bool8
|
||||
invert_classid bool8
|
||||
# TODO: this is some "cgroup path"
|
||||
path array[int8, PATH_MAX]
|
||||
path string[cgroup_paths, PATH_MAX]
|
||||
# TODO: again "cgroup classid"
|
||||
classid int32
|
||||
priv intptr
|
||||
|
@ -6,8 +6,8 @@ include <linux/hw_breakpoint.h>
|
||||
|
||||
resource fd_perf[fd]
|
||||
|
||||
# TODO: pid is cgroup fd if ERF_FLAG_PID_CGROUP is set.
|
||||
perf_event_open(attr ptr[in, perf_event_attr], pid pid, cpu intptr, group fd_perf, flags flags[perf_flags]) fd_perf
|
||||
perf_event_open(attr ptr[in, perf_event_attr], pid pid, cpu intptr[0:16], group fd_perf, flags flags[perf_flags]) fd_perf
|
||||
perf_event_open$cgroup(attr ptr[in, perf_event_attr], fd fd_cgroup, cpu intptr[0:16], group fd_perf, flags flags[perf_flags]) fd_perf
|
||||
|
||||
ioctl$PERF_EVENT_IOC_ENABLE(fd fd_perf, cmd const[PERF_EVENT_IOC_ENABLE], flags intptr)
|
||||
ioctl$PERF_EVENT_IOC_DISABLE(fd fd_perf, cmd const[PERF_EVENT_IOC_DISABLE], flags intptr)
|
||||
@ -21,7 +21,8 @@ ioctl$PERF_EVENT_IOC_SET_BPF(fd fd_perf, cmd const[PERF_EVENT_IOC_SET_BPF], prog
|
||||
ioctl$PERF_EVENT_IOC_PAUSE_OUTPUT(fd fd_perf, cmd const[PERF_EVENT_IOC_PAUSE_OUTPUT], arg boolptr)
|
||||
ioctl$PERF_EVENT_IOC_QUERY_BPF(fd fd_perf, cmd const[PERF_EVENT_IOC_QUERY_BPF], arg ptr[in, perf_event_query_bpf])
|
||||
|
||||
perf_flags = PERF_FLAG_FD_NO_GROUP, PERF_FLAG_FD_OUTPUT, PERF_FLAG_PID_CGROUP, PERF_FLAG_FD_CLOEXEC
|
||||
perf_flags = PERF_FLAG_FD_NO_GROUP, PERF_FLAG_FD_OUTPUT, PERF_FLAG_FD_CLOEXEC
|
||||
perf_flags_cgroup = PERF_FLAG_FD_NO_GROUP, PERF_FLAG_FD_OUTPUT, PERF_FLAG_PID_CGROUP, PERF_FLAG_FD_CLOEXEC
|
||||
perf_event_type = PERF_TYPE_HARDWARE, PERF_TYPE_SOFTWARE, PERF_TYPE_TRACEPOINT, PERF_TYPE_HW_CACHE, PERF_TYPE_RAW, PERF_TYPE_BREAKPOINT
|
||||
perf_bp_type = HW_BREAKPOINT_EMPTY, HW_BREAKPOINT_R, HW_BREAKPOINT_W, HW_BREAKPOINT_X
|
||||
perf_sample_type = PERF_SAMPLE_IP, PERF_SAMPLE_TID, PERF_SAMPLE_TIME, PERF_SAMPLE_ADDR, PERF_SAMPLE_READ, PERF_SAMPLE_CALLCHAIN, PERF_SAMPLE_ID, PERF_SAMPLE_CPU, PERF_SAMPLE_PERIOD, PERF_SAMPLE_STREAM_ID, PERF_SAMPLE_RAW, PERF_SAMPLE_BRANCH_STACK, PERF_SAMPLE_REGS_USER, PERF_SAMPLE_STACK_USER, PERF_SAMPLE_WEIGHT, PERF_SAMPLE_DATA_SRC, PERF_SAMPLE_IDENTIFIER, PERF_SAMPLE_TRANSACTION, PERF_SAMPLE_REGS_INTR, PERF_SAMPLE_PHYS_ADDR
|
||||
|
File diff suppressed because one or more lines are too long
@ -80,6 +80,9 @@ for i in {0..31}; do
|
||||
echo "KERNEL==\"binder$i\", NAME=\"binder$i\", MODE=\"0666\"" | \
|
||||
tee -a disk.mnt/etc/udev/50-binder.rules
|
||||
done
|
||||
# We disable selinux for now because the default policy on wheezy prevents
|
||||
# mounting of cgroup2 (and stretch we don't know how to configure yet).
|
||||
echo 'SELINUX=disabled' | sudo tee disk.mnt/etc/selinux/config
|
||||
|
||||
# sysctls
|
||||
echo "kernel.printk = 7 4 1 3" | sudo tee -a disk.mnt/etc/sysctl.conf
|
||||
|
@ -7,33 +7,34 @@
|
||||
set -eux
|
||||
|
||||
# Create a minimal Debian-wheezy distributive as a directory.
|
||||
sudo rm -rf wheezy
|
||||
mkdir -p wheezy
|
||||
sudo debootstrap --include=openssh-server,curl,tar,gcc,libc6-dev,time,strace,sudo,less,psmisc,selinux-utils,policycoreutils,checkpolicy,selinux-policy-default wheezy wheezy
|
||||
RELEASE=wheezy
|
||||
DIR=wheezy
|
||||
#sudo rm -rf $DIR
|
||||
#mkdir -p $DIR
|
||||
#sudo debootstrap --include=openssh-server,curl,tar,gcc,libc6-dev,time,strace,sudo,less,psmisc,selinux-utils,policycoreutils,checkpolicy,selinux-policy-default $RELEASE $DIR
|
||||
|
||||
# Set some defaults and enable promtless ssh to the machine for root.
|
||||
sudo sed -i '/^root/ { s/:x:/::/ }' wheezy/etc/passwd
|
||||
echo 'T0:23:respawn:/sbin/getty -L ttyS0 115200 vt100' | sudo tee -a wheezy/etc/inittab
|
||||
printf '\nauto eth0\niface eth0 inet dhcp\n' | sudo tee -a wheezy/etc/network/interfaces
|
||||
echo 'debugfs /sys/kernel/debug debugfs defaults 0 0' | sudo tee -a wheezy/etc/fstab
|
||||
echo "kernel.printk = 7 4 1 3" | sudo tee -a wheezy/etc/sysctl.conf
|
||||
echo 'debug.exception-trace = 0' | sudo tee -a wheezy/etc/sysctl.conf
|
||||
echo "net.core.bpf_jit_enable = 1" | sudo tee -a wheezy/etc/sysctl.conf
|
||||
echo "net.core.bpf_jit_harden = 2" | sudo tee -a wheezy/etc/sysctl.conf
|
||||
echo "net.ipv4.ping_group_range = 0 65535" | sudo tee -a wheezy/etc/sysctl.conf
|
||||
echo -en "127.0.0.1\tlocalhost\n" | sudo tee wheezy/etc/hosts
|
||||
echo "nameserver 8.8.8.8" | sudo tee -a wheezy/etc/resolve.conf
|
||||
echo "syzkaller" | sudo tee wheezy/etc/hostname
|
||||
sudo mkdir -p wheezy/root/.ssh/
|
||||
rm -rf ssh
|
||||
mkdir -p ssh
|
||||
ssh-keygen -f ssh/id_rsa -t rsa -N ''
|
||||
cat ssh/id_rsa.pub | sudo tee wheezy/root/.ssh/authorized_keys
|
||||
sudo sed -i '/^root/ { s/:x:/::/ }' $DIR/etc/passwd
|
||||
echo 'T0:23:respawn:/sbin/getty -L ttyS0 115200 vt100' | sudo tee -a $DIR/etc/inittab
|
||||
printf '\nauto eth0\niface eth0 inet dhcp\n' | sudo tee -a $DIR/etc/network/interfaces
|
||||
echo 'debugfs /sys/kernel/debug debugfs defaults 0 0' | sudo tee -a $DIR/etc/fstab
|
||||
echo 'SELINUX=disabled' | sudo tee $DIR/etc/selinux/config
|
||||
echo "kernel.printk = 7 4 1 3" | sudo tee -a $DIR/etc/sysctl.conf
|
||||
echo 'debug.exception-trace = 0' | sudo tee -a $DIR/etc/sysctl.conf
|
||||
echo "net.core.bpf_jit_enable = 1" | sudo tee -a $DIR/etc/sysctl.conf
|
||||
echo "net.core.bpf_jit_harden = 2" | sudo tee -a $DIR/etc/sysctl.conf
|
||||
echo "net.ipv4.ping_group_range = 0 65535" | sudo tee -a $DIR/etc/sysctl.conf
|
||||
echo -en "127.0.0.1\tlocalhost\n" | sudo tee $DIR/etc/hosts
|
||||
echo "nameserver 8.8.8.8" | sudo tee -a $DIR/etc/resolve.conf
|
||||
echo "syzkaller" | sudo tee $DIR/etc/hostname
|
||||
ssh-keygen -f $RELEASE.id_rsa -t rsa -N ''
|
||||
sudo mkdir -p $DIR/root/.ssh/
|
||||
cat $RELEASE.id_rsa.pub | sudo tee $DIR/root/.ssh/authorized_keys
|
||||
|
||||
# Build a disk image
|
||||
dd if=/dev/zero of=wheezy.img bs=1M seek=2047 count=1
|
||||
sudo mkfs.ext4 -F wheezy.img
|
||||
sudo mkdir -p /mnt/wheezy
|
||||
sudo mount -o loop wheezy.img /mnt/wheezy
|
||||
sudo cp -a wheezy/. /mnt/wheezy/.
|
||||
sudo umount /mnt/wheezy
|
||||
dd if=/dev/zero of=$RELEASE.img bs=1M seek=2047 count=1
|
||||
sudo mkfs.ext4 -F $RELEASE.img
|
||||
sudo mkdir -p /mnt/$DIR
|
||||
sudo mount -o loop $RELEASE.img /mnt/$DIR
|
||||
sudo cp -a $DIR/. /mnt/$DIR/.
|
||||
sudo umount /mnt/$DIR
|
||||
|
Loading…
Reference in New Issue
Block a user