mirror of
https://github.com/reactos/syzkaller.git
synced 2024-11-24 03:49:45 +00:00
executor: fix tun initialization when sandbox != none
This commit is contained in:
parent
dd4e19c77a
commit
f3bb6d96be
@ -189,12 +189,14 @@ static void execute_command(const char* format, ...)
|
||||
{
|
||||
va_list args;
|
||||
char command[COMMAND_MAX_LEN];
|
||||
int rv;
|
||||
|
||||
va_start(args, format);
|
||||
|
||||
vsnprintf_check(command, sizeof(command), format, args);
|
||||
if (system(command) < 0)
|
||||
fail("tun: command \"%s\" failed", &command[0]);
|
||||
rv = system(command);
|
||||
if (rv != 0)
|
||||
fail("tun: command \"%s\" failed with code %d", &command[0], rv);
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
@ -215,9 +217,6 @@ int tunfd = -1;
|
||||
|
||||
static void initialize_tun(uint64_t pid)
|
||||
{
|
||||
if (getuid() != 0)
|
||||
return;
|
||||
|
||||
if (pid >= MAX_PIDS)
|
||||
fail("tun: no more than %d executors", MAX_PIDS);
|
||||
int id = pid;
|
||||
@ -259,6 +258,13 @@ static void initialize_tun(uint64_t pid)
|
||||
execute_command("ip link set %s up", iface);
|
||||
}
|
||||
|
||||
static void setup_tun(uint64_t pid, bool enable_tun) {
|
||||
#ifdef __NR_syz_emit_ethernet
|
||||
if (enable_tun)
|
||||
initialize_tun(pid);
|
||||
#endif
|
||||
}
|
||||
|
||||
static uintptr_t syz_emit_ethernet(uintptr_t a0, uintptr_t a1)
|
||||
{
|
||||
if (tunfd < 0)
|
||||
@ -1354,7 +1360,7 @@ static uintptr_t execute_syscall(int nr, uintptr_t a0, uintptr_t a1, uintptr_t a
|
||||
}
|
||||
}
|
||||
|
||||
static void setup_main_process(uint64_t pid, bool enable_tun)
|
||||
static void setup_main_process()
|
||||
{
|
||||
struct sigaction sa;
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
@ -1363,11 +1369,6 @@ static void setup_main_process(uint64_t pid, bool enable_tun)
|
||||
syscall(SYS_rt_sigaction, 0x21, &sa, NULL, 8);
|
||||
install_segv_handler();
|
||||
|
||||
#ifdef __NR_syz_emit_ethernet
|
||||
if (enable_tun)
|
||||
initialize_tun(pid);
|
||||
#endif
|
||||
|
||||
char tmpdir_template[] = "./syzkaller.XXXXXX";
|
||||
char* tmpdir = mkdtemp(tmpdir_template);
|
||||
if (!tmpdir)
|
||||
@ -1402,25 +1403,29 @@ static void sandbox_common()
|
||||
}
|
||||
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_SANDBOX_NONE)
|
||||
static int do_sandbox_none()
|
||||
static int do_sandbox_none(int executor_pid, bool enable_tun)
|
||||
{
|
||||
int pid = fork();
|
||||
if (pid)
|
||||
return pid;
|
||||
|
||||
sandbox_common();
|
||||
setup_tun(executor_pid, enable_tun);
|
||||
|
||||
loop();
|
||||
doexit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_SANDBOX_SETUID)
|
||||
static int do_sandbox_setuid()
|
||||
static int do_sandbox_setuid(int executor_pid, bool enable_tun)
|
||||
{
|
||||
int pid = fork();
|
||||
if (pid)
|
||||
return pid;
|
||||
|
||||
sandbox_common();
|
||||
setup_tun(executor_pid, enable_tun);
|
||||
|
||||
const int nobody = 65534;
|
||||
if (setgroups(0, NULL))
|
||||
@ -1438,6 +1443,8 @@ static int do_sandbox_setuid()
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_SANDBOX_NAMESPACE)
|
||||
static int real_uid;
|
||||
static int real_gid;
|
||||
static int epid;
|
||||
static bool etun;
|
||||
__attribute__((aligned(64 << 10))) static char sandbox_stack[1 << 20];
|
||||
|
||||
static bool write_file(const char* file, const char* what, ...)
|
||||
@ -1471,6 +1478,8 @@ static int namespace_sandbox_proc(void* arg)
|
||||
if (!write_file("/proc/self/gid_map", "0 %d 1\n", real_gid))
|
||||
fail("write of /proc/self/gid_map failed");
|
||||
|
||||
setup_tun(epid, etun);
|
||||
|
||||
if (mkdir("./syz-tmp", 0777))
|
||||
fail("mkdir(syz-tmp) failed");
|
||||
if (mount("", "./syz-tmp", "tmpfs", 0, NULL))
|
||||
@ -1514,10 +1523,12 @@ static int namespace_sandbox_proc(void* arg)
|
||||
doexit(1);
|
||||
}
|
||||
|
||||
static int do_sandbox_namespace()
|
||||
static int do_sandbox_namespace(int executor_pid, bool enable_tun)
|
||||
{
|
||||
real_uid = getuid();
|
||||
real_gid = getgid();
|
||||
epid = executor_pid;
|
||||
etun = enable_tun;
|
||||
mprotect(sandbox_stack, 4096, PROT_NONE);
|
||||
return clone(namespace_sandbox_proc, &sandbox_stack[sizeof(sandbox_stack) - 8],
|
||||
CLONE_NEWUSER | CLONE_NEWPID | CLONE_NEWUTS | CLONE_NEWNET, NULL);
|
||||
|
@ -68,8 +68,8 @@ func Write(p *prog.Prog, opts Options) ([]byte, error) {
|
||||
generateTestFunc(w, opts, calls, "loop")
|
||||
|
||||
fmt.Fprint(w, "int main()\n{\n")
|
||||
fmt.Fprintf(w, "\tsetup_main_process(0, %v);\n", enableTun)
|
||||
fmt.Fprintf(w, "\tint pid = do_sandbox_%v();\n", opts.Sandbox)
|
||||
fmt.Fprintf(w, "\tsetup_main_process();\n")
|
||||
fmt.Fprintf(w, "\tint pid = do_sandbox_%v(0, %v);\n", opts.Sandbox, enableTun)
|
||||
fmt.Fprint(w, "\tint status = 0;\n")
|
||||
fmt.Fprint(w, "\twhile (waitpid(pid, &status, __WALL) != pid) {}\n")
|
||||
fmt.Fprint(w, "\treturn 0;\n}\n")
|
||||
@ -77,8 +77,8 @@ func Write(p *prog.Prog, opts Options) ([]byte, error) {
|
||||
generateTestFunc(w, opts, calls, "test")
|
||||
if opts.Procs <= 1 {
|
||||
fmt.Fprint(w, "int main()\n{\n")
|
||||
fmt.Fprintf(w, "\tsetup_main_process(0, %v);\n", enableTun)
|
||||
fmt.Fprintf(w, "\tint pid = do_sandbox_%v();\n", opts.Sandbox)
|
||||
fmt.Fprintf(w, "\tsetup_main_process();\n")
|
||||
fmt.Fprintf(w, "\tint pid = do_sandbox_%v(0, %v);\n", opts.Sandbox, enableTun)
|
||||
fmt.Fprint(w, "\tint status = 0;\n")
|
||||
fmt.Fprint(w, "\twhile (waitpid(pid, &status, __WALL) != pid) {}\n")
|
||||
fmt.Fprint(w, "\treturn 0;\n}\n")
|
||||
@ -87,8 +87,8 @@ func Write(p *prog.Prog, opts Options) ([]byte, error) {
|
||||
fmt.Fprint(w, "\tint i;")
|
||||
fmt.Fprintf(w, "\tfor (i = 0; i < %v; i++) {\n", opts.Procs)
|
||||
fmt.Fprint(w, "\t\tif (fork() == 0) {\n")
|
||||
fmt.Fprintf(w, "\t\t\tsetup_main_process(i, %v);\n", enableTun)
|
||||
fmt.Fprintf(w, "\t\t\tdo_sandbox_%v();\n", opts.Sandbox)
|
||||
fmt.Fprintf(w, "\t\t\tsetup_main_process();\n")
|
||||
fmt.Fprintf(w, "\t\t\tdo_sandbox_%v(i, %v);\n", opts.Sandbox, enableTun)
|
||||
fmt.Fprint(w, "\t\t\treturn 0;\n")
|
||||
fmt.Fprint(w, "\t\t}\n")
|
||||
fmt.Fprint(w, "\t}\n")
|
||||
|
@ -211,12 +211,14 @@ static void execute_command(const char* format, ...)
|
||||
{
|
||||
va_list args;
|
||||
char command[COMMAND_MAX_LEN];
|
||||
int rv;
|
||||
|
||||
va_start(args, format);
|
||||
|
||||
vsnprintf_check(command, sizeof(command), format, args);
|
||||
if (system(command) < 0)
|
||||
fail("tun: command \"%s\" failed", &command[0]);
|
||||
rv = system(command);
|
||||
if (rv != 0)
|
||||
fail("tun: command \"%s\" failed with code %d", &command[0], rv);
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
@ -238,9 +240,6 @@ int tunfd = -1;
|
||||
|
||||
static void initialize_tun(uint64_t pid)
|
||||
{
|
||||
if (getuid() != 0)
|
||||
return;
|
||||
|
||||
if (pid >= MAX_PIDS)
|
||||
fail("tun: no more than %d executors", MAX_PIDS);
|
||||
int id = pid;
|
||||
@ -282,6 +281,14 @@ static void initialize_tun(uint64_t pid)
|
||||
execute_command("ip link set %s up", iface);
|
||||
}
|
||||
|
||||
static void setup_tun(uint64_t pid, bool enable_tun)
|
||||
{
|
||||
#ifdef __NR_syz_emit_ethernet
|
||||
if (enable_tun)
|
||||
initialize_tun(pid);
|
||||
#endif
|
||||
}
|
||||
|
||||
static uintptr_t syz_emit_ethernet(uintptr_t a0, uintptr_t a1)
|
||||
{
|
||||
if (tunfd < 0)
|
||||
@ -436,7 +443,7 @@ static uintptr_t execute_syscall(int nr, uintptr_t a0, uintptr_t a1, uintptr_t a
|
||||
}
|
||||
}
|
||||
|
||||
static void setup_main_process(uint64_t pid, bool enable_tun)
|
||||
static void setup_main_process()
|
||||
{
|
||||
// Don't need that SIGCANCEL/SIGSETXID glibc stuff.
|
||||
// SIGCANCEL sent to main thread causes it to exit
|
||||
@ -448,11 +455,6 @@ static void setup_main_process(uint64_t pid, bool enable_tun)
|
||||
syscall(SYS_rt_sigaction, 0x21, &sa, NULL, 8);
|
||||
install_segv_handler();
|
||||
|
||||
#ifdef __NR_syz_emit_ethernet
|
||||
if (enable_tun)
|
||||
initialize_tun(pid);
|
||||
#endif
|
||||
|
||||
char tmpdir_template[] = "./syzkaller.XXXXXX";
|
||||
char* tmpdir = mkdtemp(tmpdir_template);
|
||||
if (!tmpdir)
|
||||
@ -488,25 +490,29 @@ static void sandbox_common()
|
||||
}
|
||||
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_SANDBOX_NONE)
|
||||
static int do_sandbox_none()
|
||||
static int do_sandbox_none(int executor_pid, bool enable_tun)
|
||||
{
|
||||
int pid = fork();
|
||||
if (pid)
|
||||
return pid;
|
||||
|
||||
sandbox_common();
|
||||
setup_tun(executor_pid, enable_tun);
|
||||
|
||||
loop();
|
||||
doexit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_SANDBOX_SETUID)
|
||||
static int do_sandbox_setuid()
|
||||
static int do_sandbox_setuid(int executor_pid, bool enable_tun)
|
||||
{
|
||||
int pid = fork();
|
||||
if (pid)
|
||||
return pid;
|
||||
|
||||
sandbox_common();
|
||||
setup_tun(executor_pid, enable_tun);
|
||||
|
||||
const int nobody = 65534;
|
||||
if (setgroups(0, NULL))
|
||||
@ -524,6 +530,8 @@ static int do_sandbox_setuid()
|
||||
#if defined(SYZ_EXECUTOR) || defined(SYZ_SANDBOX_NAMESPACE)
|
||||
static int real_uid;
|
||||
static int real_gid;
|
||||
static int epid;
|
||||
static bool etun;
|
||||
__attribute__((aligned(64 << 10))) static char sandbox_stack[1 << 20];
|
||||
|
||||
static bool write_file(const char* file, const char* what, ...)
|
||||
@ -558,6 +566,10 @@ static int namespace_sandbox_proc(void* arg)
|
||||
if (!write_file("/proc/self/gid_map", "0 %d 1\n", real_gid))
|
||||
fail("write of /proc/self/gid_map failed");
|
||||
|
||||
// For sandbox namespace we setup tun after initializing uid mapping,
|
||||
// otherwise ip commands fail.
|
||||
setup_tun(epid, etun);
|
||||
|
||||
if (mkdir("./syz-tmp", 0777))
|
||||
fail("mkdir(syz-tmp) failed");
|
||||
if (mount("", "./syz-tmp", "tmpfs", 0, NULL))
|
||||
@ -605,10 +617,12 @@ static int namespace_sandbox_proc(void* arg)
|
||||
doexit(1);
|
||||
}
|
||||
|
||||
static int do_sandbox_namespace()
|
||||
static int do_sandbox_namespace(int executor_pid, bool enable_tun)
|
||||
{
|
||||
real_uid = getuid();
|
||||
real_gid = getgid();
|
||||
epid = executor_pid;
|
||||
etun = enable_tun;
|
||||
mprotect(sandbox_stack, 4096, PROT_NONE); // to catch stack underflows
|
||||
return clone(namespace_sandbox_proc, &sandbox_stack[sizeof(sandbox_stack) - 8],
|
||||
CLONE_NEWUSER | CLONE_NEWPID | CLONE_NEWUTS | CLONE_NEWNET, NULL);
|
||||
|
@ -164,18 +164,18 @@ int main(int argc, char** argv)
|
||||
uint64_t executor_pid = *((uint64_t*)input_data + 1);
|
||||
|
||||
cover_open();
|
||||
setup_main_process(executor_pid, flag_enable_tun);
|
||||
setup_main_process();
|
||||
|
||||
int pid = -1;
|
||||
switch (flag_sandbox) {
|
||||
case sandbox_none:
|
||||
pid = do_sandbox_none();
|
||||
pid = do_sandbox_none(executor_pid, flag_enable_tun);
|
||||
break;
|
||||
case sandbox_setuid:
|
||||
pid = do_sandbox_setuid();
|
||||
pid = do_sandbox_setuid(executor_pid, flag_enable_tun);
|
||||
break;
|
||||
case sandbox_namespace:
|
||||
pid = do_sandbox_namespace();
|
||||
pid = do_sandbox_namespace(executor_pid, flag_enable_tun);
|
||||
break;
|
||||
default:
|
||||
fail("unknown sandbox type");
|
||||
|
Loading…
Reference in New Issue
Block a user