aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2018-05-17 19:57:54 +0200
committerDmitry Vyukov <dvyukov@google.com>2018-05-17 19:57:54 +0200
commit738d58ade0f41fb8ab33066dc0dd486d86383ef5 (patch)
tree1a924306f9af60f1067aa0c9ca0859664d8f3319
parent3717901c109694be56bb24593db945e4367ecf14 (diff)
pkg/csource: minimize netdevices and net reset
Add separate options to minimize netdevices setup and net namespace reset. Fixes #581
-rw-r--r--executor/common_linux.h41
-rw-r--r--pkg/csource/common.go9
-rw-r--r--pkg/csource/linux_common.go38
-rw-r--r--pkg/csource/options.go14
-rw-r--r--pkg/csource/options_test.go7
-rw-r--r--pkg/repro/repro.go22
-rw-r--r--pkg/repro/repro_test.go2
-rw-r--r--tools/syz-execprog/execprog.go3
-rw-r--r--tools/syz-prog2c/prog2c.go34
9 files changed, 113 insertions, 57 deletions
diff --git a/executor/common_linux.h b/executor/common_linux.h
index 45a74e36f..ae83e5d46 100644
--- a/executor/common_linux.h
+++ b/executor/common_linux.h
@@ -58,7 +58,7 @@
#include <sys/mman.h>
#include <sys/mount.h>
#endif
-#if defined(SYZ_EXECUTOR) || defined(SYZ_TUN_ENABLE)
+#if defined(SYZ_EXECUTOR) || defined(SYZ_TUN_ENABLE) || defined(SYZ_ENABLE_NETDEV)
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
@@ -261,7 +261,7 @@ static void use_temporary_dir()
}
#endif
-#if defined(SYZ_EXECUTOR) || defined(SYZ_TUN_ENABLE)
+#if defined(SYZ_EXECUTOR) || defined(SYZ_TUN_ENABLE) || defined(SYZ_ENABLE_NETDEV)
static void vsnprintf_check(char* str, size_t size, const char* format, va_list args)
{
int rv;
@@ -273,15 +273,6 @@ static void vsnprintf_check(char* str, size_t size, const char* format, va_list
fail("tun: string '%s...' doesn't fit into buffer", str);
}
-static void snprintf_check(char* str, size_t size, const char* format, ...)
-{
- va_list args;
-
- va_start(args, format);
- vsnprintf_check(str, size, format, args);
- va_end(args);
-}
-
#define COMMAND_MAX_LEN 128
#define PATH_PREFIX "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin "
#define PATH_PREFIX_LEN (sizeof(PATH_PREFIX) - 1)
@@ -306,7 +297,9 @@ static void execute_command(bool panic, const char* format, ...)
debug("command '%s': %d\n", &command[0], rv);
}
}
+#endif
+#if defined(SYZ_EXECUTOR) || defined(SYZ_TUN_ENABLE)
static int tunfd = -1;
static int tun_frags_enabled;
@@ -393,12 +386,24 @@ static void initialize_tun(void)
REMOTE_IPV6, REMOTE_MAC, TUN_IFACE);
execute_command(1, "ip link set dev %s up", TUN_IFACE);
}
+#endif
+
+#if defined(SYZ_EXECUTOR) || defined(SYZ_ENABLE_NETDEV)
// Addresses are chosen to be in the same subnet as tun addresses.
#define DEV_IPV4 "172.20.20.%d"
#define DEV_IPV6 "fe80::%02hx"
#define DEV_MAC "aa:aa:aa:aa:aa:%02hx"
+static void snprintf_check(char* str, size_t size, const char* format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+ vsnprintf_check(str, size, format, args);
+ va_end(args);
+}
+
// We test in a separate namespace, which does not have any network devices initially (even lo).
// Create/up as many as we can.
static void initialize_netdevices(void)
@@ -415,10 +420,6 @@ static void initialize_netdevices(void)
"veth0_to_team", "veth1_to_team"};
const char* devmasters[] = {"bridge", "bond", "team"};
-#ifdef SYZ_EXECUTOR
- if (!flag_enable_tun)
- return;
-#endif
for (i = 0; i < sizeof(devtypes) / (sizeof(devtypes[0])); i++)
execute_command(0, "ip link add dev %s0 type %s", devtypes[i], devtypes[i]);
// This adds connected veth0 and veth1 devices.
@@ -1202,10 +1203,10 @@ static int do_sandbox_none(void)
}
#if defined(SYZ_EXECUTOR) || defined(SYZ_TUN_ENABLE)
initialize_tun();
- // TODO(dvyukov): this should be separated from tun and minimized by csource separately.
+#endif
+#if defined(SYZ_EXECUTOR) || defined(SYZ_ENABLE_NETDEV)
initialize_netdevices();
#endif
-
loop();
doexit(1);
}
@@ -1231,7 +1232,8 @@ static int do_sandbox_setuid(void)
fail("unshare(CLONE_NEWNET)");
#if defined(SYZ_EXECUTOR) || defined(SYZ_TUN_ENABLE)
initialize_tun();
- // TODO(dvyukov): this should be separated from tun and minimized by csource separately.
+#endif
+#if defined(SYZ_EXECUTOR) || defined(SYZ_ENABLE_NETDEV)
initialize_netdevices();
#endif
@@ -1279,7 +1281,8 @@ static int namespace_sandbox_proc(void* arg)
// However, IFF_NAPI_FRAGS will fail as we are not root already.
// There does not seem to be a call sequence that would satisfy all of that.
initialize_tun();
- // TODO(dvyukov): this should be separated from tun and minimized by csource separately.
+#endif
+#if defined(SYZ_EXECUTOR) || defined(SYZ_ENABLE_NETDEV)
initialize_netdevices();
#endif
diff --git a/pkg/csource/common.go b/pkg/csource/common.go
index 27caac40d..e8fce42a6 100644
--- a/pkg/csource/common.go
+++ b/pkg/csource/common.go
@@ -92,6 +92,12 @@ func defineList(p *prog.Prog, opts Options) ([]string, error) {
if opts.EnableCgroups {
defines = append(defines, "SYZ_ENABLE_CGROUPS")
}
+ if opts.EnableNetdev {
+ defines = append(defines, "SYZ_ENABLE_NETDEV")
+ }
+ if opts.ResetNet {
+ defines = append(defines, "SYZ_RESET_NET_NAMESPACE")
+ }
if opts.UseTmpDir {
defines = append(defines, "SYZ_USE_TMP_DIR")
}
@@ -100,9 +106,6 @@ func defineList(p *prog.Prog, opts Options) ([]string, error) {
}
if opts.WaitRepeat {
defines = append(defines, "SYZ_WAIT_REPEAT")
- // TODO(dvyukov): this should have a separate option,
- // but for now it's bundled with WaitRepeat.
- defines = append(defines, "SYZ_RESET_NET_NAMESPACE")
}
if opts.Debug {
defines = append(defines, "SYZ_DEBUG")
diff --git a/pkg/csource/linux_common.go b/pkg/csource/linux_common.go
index 77ba9b36f..4d168e661 100644
--- a/pkg/csource/linux_common.go
+++ b/pkg/csource/linux_common.go
@@ -60,7 +60,7 @@ var commonHeaderLinux = `
#include <sys/mman.h>
#include <sys/mount.h>
#endif
-#if defined(SYZ_EXECUTOR) || defined(SYZ_TUN_ENABLE)
+#if defined(SYZ_EXECUTOR) || defined(SYZ_TUN_ENABLE) || defined(SYZ_ENABLE_NETDEV)
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
@@ -422,7 +422,7 @@ static void use_temporary_dir()
}
#endif
-#if defined(SYZ_EXECUTOR) || defined(SYZ_TUN_ENABLE)
+#if defined(SYZ_EXECUTOR) || defined(SYZ_TUN_ENABLE) || defined(SYZ_ENABLE_NETDEV)
static void vsnprintf_check(char* str, size_t size, const char* format, va_list args)
{
int rv;
@@ -434,15 +434,6 @@ static void vsnprintf_check(char* str, size_t size, const char* format, va_list
fail("tun: string '%s...' doesn't fit into buffer", str);
}
-static void snprintf_check(char* str, size_t size, const char* format, ...)
-{
- va_list args;
-
- va_start(args, format);
- vsnprintf_check(str, size, format, args);
- va_end(args);
-}
-
#define COMMAND_MAX_LEN 128
#define PATH_PREFIX "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin "
#define PATH_PREFIX_LEN (sizeof(PATH_PREFIX) - 1)
@@ -464,7 +455,9 @@ static void execute_command(bool panic, const char* format, ...)
debug("command '%s': %d\n", &command[0], rv);
}
}
+#endif
+#if defined(SYZ_EXECUTOR) || defined(SYZ_TUN_ENABLE)
static int tunfd = -1;
static int tun_frags_enabled;
@@ -541,11 +534,23 @@ static void initialize_tun(void)
REMOTE_IPV6, REMOTE_MAC, TUN_IFACE);
execute_command(1, "ip link set dev %s up", TUN_IFACE);
}
+#endif
+
+#if defined(SYZ_EXECUTOR) || defined(SYZ_ENABLE_NETDEV)
#define DEV_IPV4 "172.20.20.%d"
#define DEV_IPV6 "fe80::%02hx"
#define DEV_MAC "aa:aa:aa:aa:aa:%02hx"
+static void snprintf_check(char* str, size_t size, const char* format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+ vsnprintf_check(str, size, format, args);
+ va_end(args);
+}
+
static void initialize_netdevices(void)
{
unsigned i;
@@ -559,10 +564,6 @@ static void initialize_netdevices(void)
"veth0_to_team", "veth1_to_team"};
const char* devmasters[] = {"bridge", "bond", "team"};
-#ifdef SYZ_EXECUTOR
- if (!flag_enable_tun)
- return;
-#endif
for (i = 0; i < sizeof(devtypes) / (sizeof(devtypes[0])); i++)
execute_command(0, "ip link add dev %s0 type %s", devtypes[i], devtypes[i]);
execute_command(0, "ip link add type veth");
@@ -2243,9 +2244,10 @@ static int do_sandbox_none(void)
}
#if defined(SYZ_EXECUTOR) || defined(SYZ_TUN_ENABLE)
initialize_tun();
+#endif
+#if defined(SYZ_EXECUTOR) || defined(SYZ_ENABLE_NETDEV)
initialize_netdevices();
#endif
-
loop();
doexit(1);
}
@@ -2271,6 +2273,8 @@ static int do_sandbox_setuid(void)
fail("unshare(CLONE_NEWNET)");
#if defined(SYZ_EXECUTOR) || defined(SYZ_TUN_ENABLE)
initialize_tun();
+#endif
+#if defined(SYZ_EXECUTOR) || defined(SYZ_ENABLE_NETDEV)
initialize_netdevices();
#endif
@@ -2308,6 +2312,8 @@ static int namespace_sandbox_proc(void* arg)
fail("unshare(CLONE_NEWNET)");
#if defined(SYZ_EXECUTOR) || defined(SYZ_TUN_ENABLE)
initialize_tun();
+#endif
+#if defined(SYZ_EXECUTOR) || defined(SYZ_ENABLE_NETDEV)
initialize_netdevices();
#endif
diff --git a/pkg/csource/options.go b/pkg/csource/options.go
index 7b9ed7050..fd89abcb6 100644
--- a/pkg/csource/options.go
+++ b/pkg/csource/options.go
@@ -27,6 +27,8 @@ type Options struct {
EnableTun bool `json:"tun,omitempty"`
UseTmpDir bool `json:"tmpdir,omitempty"`
EnableCgroups bool `json:"cgroups,omitempty"`
+ EnableNetdev bool `json:"netdev,omitempty"`
+ ResetNet bool `json:"resetnet,omitempty"`
HandleSegv bool `json:"segv,omitempty"`
WaitRepeat bool `json:"waitrepeat,omitempty"`
Debug bool `json:"debug,omitempty"`
@@ -66,6 +68,18 @@ func (opts Options) Check() error {
if opts.EnableCgroups && !opts.UseTmpDir {
return errors.New("EnableCgroups without UseTmpDir")
}
+ if opts.EnableCgroups && !opts.WaitRepeat {
+ return errors.New("EnableCgroups without WaitRepeat")
+ }
+ if opts.EnableNetdev && opts.Sandbox == "" {
+ return errors.New("EnableNetdev without sandbox")
+ }
+ if opts.ResetNet && opts.Sandbox == "" {
+ return errors.New("ResetNet without sandbox")
+ }
+ if opts.ResetNet && !opts.WaitRepeat {
+ return errors.New("ResetNet without WaitRepeat")
+ }
return nil
}
diff --git a/pkg/csource/options_test.go b/pkg/csource/options_test.go
index 9aee780a3..4cccf1c6e 100644
--- a/pkg/csource/options_test.go
+++ b/pkg/csource/options_test.go
@@ -27,7 +27,10 @@ func TestParseOptionsCanned(t *testing.T) {
// so we need to be able to parse old formats.
// nolint: lll
canned := map[string]Options{
- `{"threaded":true,"collide":true,"repeat":true,"procs":10,"sandbox":"namespace","fault":true,"fault_call":1,"fault_nth":2,"tun":true,"tmpdir":true,"cgroups":true,"segv":true,"waitrepeat":true,"debug":true,"repro":true}`: Options{
+ `{"threaded":true,"collide":true,"repeat":true,"procs":10,"sandbox":"namespace",
+ "fault":true,"fault_call":1,"fault_nth":2,"tun":true,"tmpdir":true,"cgroups":true,
+ "netdev":true,"resetnet":true,
+ "segv":true,"waitrepeat":true,"debug":true,"repro":true}`: Options{
Threaded: true,
Collide: true,
Repeat: true,
@@ -39,6 +42,8 @@ func TestParseOptionsCanned(t *testing.T) {
EnableTun: true,
UseTmpDir: true,
EnableCgroups: true,
+ EnableNetdev: true,
+ ResetNet: true,
HandleSegv: true,
WaitRepeat: true,
Debug: true,
diff --git a/pkg/repro/repro.go b/pkg/repro/repro.go
index 07214a630..3b6b190e1 100644
--- a/pkg/repro/repro.go
+++ b/pkg/repro/repro.go
@@ -298,6 +298,8 @@ func (ctx *context) createDefaultOps() csource.Options {
Sandbox: ctx.cfg.Sandbox,
EnableTun: true,
EnableCgroups: true,
+ EnableNetdev: true,
+ ResetNet: true,
UseTmpDir: true,
HandleSegv: true,
WaitRepeat: true,
@@ -795,6 +797,8 @@ var progSimplifies = []Simplify{
}
opts.Repeat = false
opts.WaitRepeat = false
+ opts.EnableCgroups = false
+ opts.ResetNet = false
opts.Procs = 1
return true
},
@@ -822,6 +826,8 @@ var cSimplifies = append(progSimplifies, []Simplify{
opts.Sandbox = ""
opts.EnableTun = false
opts.EnableCgroups = false
+ opts.EnableNetdev = false
+ opts.ResetNet = false
return true
},
func(opts *csource.Options) bool {
@@ -839,6 +845,20 @@ var cSimplifies = append(progSimplifies, []Simplify{
return true
},
func(opts *csource.Options) bool {
+ if !opts.EnableNetdev {
+ return false
+ }
+ opts.EnableNetdev = false
+ return true
+ },
+ func(opts *csource.Options) bool {
+ if !opts.ResetNet {
+ return false
+ }
+ opts.ResetNet = false
+ return true
+ },
+ func(opts *csource.Options) bool {
if !opts.UseTmpDir || opts.Sandbox == "namespace" || opts.EnableCgroups {
return false
}
@@ -857,6 +877,8 @@ var cSimplifies = append(progSimplifies, []Simplify{
return false
}
opts.WaitRepeat = false
+ opts.EnableCgroups = false
+ opts.ResetNet = false
return true
},
}...)
diff --git a/pkg/repro/repro_test.go b/pkg/repro/repro_test.go
index 8f0440784..0a437e713 100644
--- a/pkg/repro/repro_test.go
+++ b/pkg/repro/repro_test.go
@@ -74,6 +74,8 @@ func TestSimplifies(t *testing.T) {
Sandbox: "namespace",
EnableTun: true,
EnableCgroups: true,
+ EnableNetdev: true,
+ ResetNet: true,
UseTmpDir: true,
HandleSegv: true,
WaitRepeat: true,
diff --git a/tools/syz-execprog/execprog.go b/tools/syz-execprog/execprog.go
index 40aa521ce..ff7e6d838 100644
--- a/tools/syz-execprog/execprog.go
+++ b/tools/syz-execprog/execprog.go
@@ -226,8 +226,5 @@ func createConfig(entries []*prog.LogEntry) (*ipc.Config, *ipc.ExecOpts) {
handled[call.Meta.CallName] = true
}
}
- if handled["syz_emit_ethernet"] || handled["syz_extract_tcp_res"] {
- config.Flags |= ipc.FlagEnableTun
- }
return config, execOpts
}
diff --git a/tools/syz-prog2c/prog2c.go b/tools/syz-prog2c/prog2c.go
index 9eaf5fefe..b7f13f971 100644
--- a/tools/syz-prog2c/prog2c.go
+++ b/tools/syz-prog2c/prog2c.go
@@ -28,9 +28,11 @@ var (
flagFaultNth = flag.Int("fault_nth", 0, "inject fault on n-th operation (0-based)")
flagEnableTun = flag.Bool("tun", false, "set up TUN/TAP interface")
flagUseTmpDir = flag.Bool("tmpdir", false, "create a temporary dir and execute inside it")
+ flagCgroups = flag.Bool("cgroups", false, "enable cgroups support")
+ flagNetdev = flag.Bool("netdev", false, "setup various net devices")
+ flagResetNet = flag.Bool("resetnet", false, "reset net namespace after each test")
flagHandleSegv = flag.Bool("segv", false, "catch and ignore SIGSEGV")
flagWaitRepeat = flag.Bool("waitrepeat", false, "wait for each repeat attempt")
- flagCgroups = flag.Bool("cgroups", false, "enable cgroups support")
flagDebug = flag.Bool("debug", false, "generate debug printfs")
)
@@ -56,21 +58,23 @@ func main() {
os.Exit(1)
}
opts := csource.Options{
- Threaded: *flagThreaded,
- Collide: *flagCollide,
- Repeat: *flagRepeat,
- Procs: *flagProcs,
- Sandbox: *flagSandbox,
- Fault: *flagFaultCall >= 0,
- FaultCall: *flagFaultCall,
- FaultNth: *flagFaultNth,
- EnableTun: *flagEnableTun,
- UseTmpDir: *flagUseTmpDir,
+ Threaded: *flagThreaded,
+ Collide: *flagCollide,
+ Repeat: *flagRepeat,
+ Procs: *flagProcs,
+ Sandbox: *flagSandbox,
+ Fault: *flagFaultCall >= 0,
+ FaultCall: *flagFaultCall,
+ FaultNth: *flagFaultNth,
+ EnableTun: *flagEnableTun,
+ UseTmpDir: *flagUseTmpDir,
EnableCgroups: *flagCgroups,
- HandleSegv: *flagHandleSegv,
- WaitRepeat: *flagWaitRepeat,
- Debug: *flagDebug,
- Repro: false,
+ EnableNetdev: *flagNetdev,
+ ResetNet: *flagResetNet,
+ HandleSegv: *flagHandleSegv,
+ WaitRepeat: *flagWaitRepeat,
+ Debug: *flagDebug,
+ Repro: false,
}
src, err := csource.Write(p, opts)
if err != nil {