executor: don't try to open tun if it's not enabled

This commit is contained in:
Andrey Konovalov 2016-12-02 13:18:42 +01:00
parent e4bf587846
commit 346fb4e5e9
6 changed files with 31 additions and 10 deletions

View File

@ -34,6 +34,7 @@ var commonHeader = `
#include <setjmp.h>
#include <signal.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
@ -161,7 +162,7 @@ static void execute_command(const char* format, ...)
va_end(args);
}
int tunfd;
int tunfd = -1;
#define ADDR_MAX_LEN 32
@ -222,6 +223,9 @@ static void initialize_tun(uint64_t pid)
static uintptr_t syz_emit_ethernet(uintptr_t a0, uintptr_t a1)
{
if (tunfd < 0)
return (uintptr_t)-1;
int64_t length = a0;
char* data = (char*)a1;
return write(tunfd, data, length);
@ -351,7 +355,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)
static void setup_main_process(uint64_t pid, bool enable_tun)
{
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
@ -361,7 +365,8 @@ static void setup_main_process(uint64_t pid)
install_segv_handler();
#ifdef __NR_syz_emit_ethernet
initialize_tun(pid);
if (enable_tun)
initialize_tun(pid);
#endif
char tmpdir_template[] = "./syzkaller.XXXXXX";

View File

@ -45,6 +45,11 @@ func Write(p *prog.Prog, opts Options) ([]byte, error) {
}
fmt.Fprintf(w, "\n")
enableTun := "false"
if _, ok := handled["syz_emit_ethernet"]; ok {
enableTun = "true"
}
hdr, err := preprocessCommonHeader(opts, handled)
if err != nil {
return nil, err
@ -59,7 +64,7 @@ func Write(p *prog.Prog, opts Options) ([]byte, error) {
generateTestFunc(w, opts, calls, "loop")
fmt.Fprint(w, "int main()\n{\n")
fmt.Fprint(w, "\tsetup_main_process(0);\n")
fmt.Fprintf(w, "\tsetup_main_process(0, %v);\n", enableTun)
fmt.Fprintf(w, "\tint pid = do_sandbox_%v();\n", opts.Sandbox)
fmt.Fprint(w, "\tint status = 0;\n")
fmt.Fprint(w, "\twhile (waitpid(pid, &status, __WALL) != pid) {}\n")
@ -68,7 +73,7 @@ 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.Fprint(w, "\tsetup_main_process(0);\n")
fmt.Fprintf(w, "\tsetup_main_process(0, %v);\n", enableTun)
fmt.Fprintf(w, "\tint pid = do_sandbox_%v();\n", opts.Sandbox)
fmt.Fprint(w, "\tint status = 0;\n")
fmt.Fprint(w, "\twhile (waitpid(pid, &status, __WALL) != pid) {}\n")
@ -78,7 +83,7 @@ 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.Fprint(w, "\t\t\tsetup_main_process(i);\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.Fprint(w, "\t\t}\n")
fmt.Fprint(w, "\t}\n")

View File

@ -33,6 +33,7 @@
#include <setjmp.h>
#include <signal.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
@ -163,7 +164,7 @@ static void execute_command(const char* format, ...)
va_end(args);
}
int tunfd;
int tunfd = -1;
#define ADDR_MAX_LEN 32
@ -224,6 +225,9 @@ static void initialize_tun(uint64_t pid)
static uintptr_t syz_emit_ethernet(uintptr_t a0, uintptr_t a1)
{
if (tunfd < 0)
return (uintptr_t)-1;
int64_t length = a0;
char* data = (char*)a1;
return write(tunfd, data, length);
@ -361,7 +365,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)
static void setup_main_process(uint64_t pid, bool enable_tun)
{
// Don't need that SIGCANCEL/SIGSETXID glibc stuff.
// SIGCANCEL sent to main thread causes it to exit
@ -374,7 +378,8 @@ static void setup_main_process(uint64_t pid)
install_segv_handler();
#ifdef __NR_syz_emit_ethernet
initialize_tun(pid);
if (enable_tun)
initialize_tun(pid);
#endif
char tmpdir_template[] = "./syzkaller.XXXXXX";

View File

@ -73,6 +73,7 @@ bool flag_collide;
bool flag_deduplicate;
bool flag_sandbox_privs;
sandbox_type flag_sandbox;
bool flag_enable_tun;
__attribute__((aligned(64 << 10))) char input_data[kMaxInput];
__attribute__((aligned(64 << 10))) char output_data[kMaxOutput];
@ -161,10 +162,11 @@ int main(int argc, char** argv)
flag_sandbox = sandbox_namespace;
if (!flag_threaded)
flag_collide = false;
flag_enable_tun = flags & (1 << 7);
uint64_t executor_pid = *((uint64_t*)input_data + 1);
cover_open();
setup_main_process(executor_pid);
setup_main_process(executor_pid, flag_enable_tun);
int pid = -1;
switch (flag_sandbox) {

View File

@ -46,6 +46,7 @@ const (
FlagDedupCover // deduplicate coverage in executor
FlagSandboxSetuid // impersonate nobody user
FlagSandboxNamespace // use namespaces for sandboxing
FlagEnableTun // initialize and use tun in executor
)
var (

View File

@ -136,6 +136,9 @@ func main() {
if err != nil {
panic(err)
}
if _, ok := calls[sys.CallMap["syz_emit_ethernet"]]; ok {
flags |= ipc.FlagEnableTun
}
noCover = flags&ipc.FlagCover == 0
leakCallback := func() {
if atomic.LoadUint32(&allTriaged) != 0 {