diff options
Diffstat (limited to 'pkg')
| -rw-r--r-- | pkg/csource/common.go | 10 | ||||
| -rw-r--r-- | pkg/csource/csource.go | 11 | ||||
| -rw-r--r-- | pkg/csource/csource_test.go | 5 | ||||
| -rw-r--r-- | pkg/csource/generated.go | 14 | ||||
| -rw-r--r-- | pkg/csource/options.go | 4 | ||||
| -rw-r--r-- | pkg/csource/options_test.go | 10 | ||||
| -rw-r--r-- | pkg/instance/instance_test.go | 11 | ||||
| -rw-r--r-- | pkg/ipc/ipc.go | 4 | ||||
| -rw-r--r-- | pkg/ipc/ipc_test.go | 2 | ||||
| -rw-r--r-- | pkg/ipc/ipcconfig/ipcconfig.go | 5 | ||||
| -rw-r--r-- | pkg/repro/repro.go | 9 | ||||
| -rw-r--r-- | pkg/repro/repro_test.go | 1 | ||||
| -rw-r--r-- | pkg/runtest/run.go | 5 |
13 files changed, 43 insertions, 48 deletions
diff --git a/pkg/csource/common.go b/pkg/csource/common.go index a1525e24f..7e396931c 100644 --- a/pkg/csource/common.go +++ b/pkg/csource/common.go @@ -91,23 +91,23 @@ func defineList(p, mmapProg *prog.Prog, opts Options) (defines []string) { func commonDefines(p *prog.Prog, opts Options) map[string]bool { sysTarget := targets.Get(p.Target.OS, p.Target.Arch) - bitmasks, csums := prog.RequiredFeatures(p) + features := p.RequiredFeatures() return map[string]bool{ "GOOS_" + p.Target.OS: true, "GOARCH_" + p.Target.Arch: true, "HOSTGOOS_" + runtime.GOOS: true, - "SYZ_USE_BITMASKS": bitmasks, - "SYZ_USE_CHECKSUMS": csums, + "SYZ_USE_BITMASKS": features.Bitmasks, + "SYZ_USE_CHECKSUMS": features.Csums, "SYZ_SANDBOX_NONE": opts.Sandbox == sandboxNone, "SYZ_SANDBOX_SETUID": opts.Sandbox == sandboxSetuid, "SYZ_SANDBOX_NAMESPACE": opts.Sandbox == sandboxNamespace, "SYZ_SANDBOX_ANDROID": opts.Sandbox == sandboxAndroid, "SYZ_THREADED": opts.Threaded, - "SYZ_COLLIDE": opts.Collide, + "SYZ_ASYNC": features.Async, "SYZ_REPEAT": opts.Repeat, "SYZ_REPEAT_TIMES": opts.RepeatTimes > 1, "SYZ_MULTI_PROC": opts.Procs > 1, - "SYZ_FAULT": p.HasFaultInjection(), + "SYZ_FAULT": features.FaultInjection, "SYZ_LEAK": opts.Leak, "SYZ_NET_INJECTION": opts.NetInjection, "SYZ_NET_DEVICES": opts.NetDevices, diff --git a/pkg/csource/csource.go b/pkg/csource/csource.go index 68f961526..32e01ff1e 100644 --- a/pkg/csource/csource.go +++ b/pkg/csource/csource.go @@ -115,6 +115,17 @@ func (ctx *context) generateSource() ([]byte, error) { } } replacements["CALL_TIMEOUT_MS"] = timeoutExpr + if ctx.p.RequiredFeatures().Async { + conditions := []string{} + for idx, call := range ctx.p.Calls { + if !call.Props.Async { + continue + } + conditions = append(conditions, fmt.Sprintf("call == %v", idx)) + } + replacements["ASYNC_CONDITIONS"] = strings.Join(conditions, " || ") + } + result, err := createCommonHeader(ctx.p, mmapProg, replacements, ctx.opts) if err != nil { return nil, err diff --git a/pkg/csource/csource_test.go b/pkg/csource/csource_test.go index aa242e876..885d75f67 100644 --- a/pkg/csource/csource_test.go +++ b/pkg/csource/csource_test.go @@ -70,10 +70,13 @@ func testTarget(t *testing.T, target *prog.Target, full bool) { p.Calls = append(p.Calls, minimized.Calls...) opts = allOptionsPermutations(target.OS) } + // Test fault injection and async call generation as well. if len(p.Calls) > 0 { - // Test fault injection code generation as well. p.Calls[0].Props.FailNth = 1 } + if len(p.Calls) > 1 { + p.Calls[1].Props.Async = true + } for opti, opts := range opts { if testing.Short() && opts.HandleSegv { // HandleSegv can radically increase compilation time/memory consumption on large programs. diff --git a/pkg/csource/generated.go b/pkg/csource/generated.go index 728806967..851bf935a 100644 --- a/pkg/csource/generated.go +++ b/pkg/csource/generated.go @@ -10457,10 +10457,6 @@ static void loop(void) fprintf(stderr, "### start\n"); #endif int i, call, thread; -#if SYZ_COLLIDE - int collide = 0; -again: -#endif for (call = 0; call < /*{{{NUM_CALLS}}}*/; call++) { for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0])); thread++) { struct thread_t* th = &threads[thread]; @@ -10477,8 +10473,8 @@ again: th->call = call; __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED); event_set(&th->ready); -#if SYZ_COLLIDE - if (collide && (call % 2) == 0) +#if SYZ_ASYNC + if (/*{{{ASYNC_CONDITIONS}}}*/) break; #endif event_timedwait(&th->done, /*{{{CALL_TIMEOUT_MS}}}*/); @@ -10490,12 +10486,6 @@ again: #if SYZ_HAVE_CLOSE_FDS close_fds(); #endif -#if SYZ_COLLIDE - if (!collide) { - collide = 1; - goto again; - } -#endif } #endif diff --git a/pkg/csource/options.go b/pkg/csource/options.go index 36490c8b8..3fc549282 100644 --- a/pkg/csource/options.go +++ b/pkg/csource/options.go @@ -19,7 +19,6 @@ import ( // Dashboard also provides serialized Options along with syzkaller reproducers. type Options struct { Threaded bool `json:"threaded,omitempty"` - Collide bool `json:"collide,omitempty"` Repeat bool `json:"repeat,omitempty"` RepeatTimes int `json:"repeat_times,omitempty"` // if non-0, repeat that many times Procs int `json:"procs"` @@ -55,6 +54,7 @@ type Options struct { // These are legacy options, they remain only for the sake of backward compatibility. type LegacyOptions struct { + Collide bool `json:"collide,omitempty"` Fault bool `json:"fault,omitempty"` FaultCall int `json:"fault_call,omitempty"` FaultNth int `json:"fault_nth,omitempty"` @@ -158,7 +158,6 @@ func (opts Options) checkLinuxOnly(OS string) error { func DefaultOpts(cfg *mgrconfig.Config) Options { opts := Options{ Threaded: true, - Collide: true, Repeat: true, Procs: cfg.Procs, Slowdown: cfg.Timeouts.Slowdown, @@ -322,7 +321,6 @@ func PrintAvailableFeaturesFlags() { // This is the main configuration used by executor, only for testing. var ExecutorOpts = Options{ Threaded: true, - Collide: true, Repeat: true, Procs: 2, Slowdown: 1, diff --git a/pkg/csource/options_test.go b/pkg/csource/options_test.go index ba31e4c95..5e971a9d1 100644 --- a/pkg/csource/options_test.go +++ b/pkg/csource/options_test.go @@ -34,7 +34,6 @@ func TestParseOptionsCanned(t *testing.T) { "netdev":true,"resetnet":true, "segv":true,"waitrepeat":true,"debug":true,"repro":true}`: { Threaded: true, - Collide: true, Repeat: true, Procs: 10, Slowdown: 1, @@ -49,6 +48,7 @@ func TestParseOptionsCanned(t *testing.T) { HandleSegv: true, Repro: true, LegacyOptions: LegacyOptions{ + Collide: true, Fault: true, FaultCall: 1, FaultNth: 2, @@ -59,7 +59,6 @@ func TestParseOptionsCanned(t *testing.T) { "netdev":true,"resetnet":true, "segv":true,"waitrepeat":true,"debug":true,"repro":true}`: { Threaded: true, - Collide: true, Repeat: true, Procs: 10, Slowdown: 1, @@ -74,6 +73,7 @@ func TestParseOptionsCanned(t *testing.T) { HandleSegv: true, Repro: true, LegacyOptions: LegacyOptions{ + Collide: true, Fault: true, FaultCall: 1, FaultNth: 2, @@ -81,7 +81,6 @@ func TestParseOptionsCanned(t *testing.T) { }, "{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, Slowdown: 1, @@ -94,6 +93,7 @@ func TestParseOptionsCanned(t *testing.T) { HandleSegv: true, Repro: false, LegacyOptions: LegacyOptions{ + Collide: true, Fault: false, FaultCall: -1, FaultNth: 0, @@ -101,7 +101,6 @@ func TestParseOptionsCanned(t *testing.T) { }, "{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, Slowdown: 1, @@ -114,6 +113,7 @@ func TestParseOptionsCanned(t *testing.T) { HandleSegv: true, Repro: false, LegacyOptions: LegacyOptions{ + Collide: true, Fault: false, FaultCall: -1, FaultNth: 0, @@ -121,7 +121,6 @@ func TestParseOptionsCanned(t *testing.T) { }, "{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}": { Threaded: false, - Collide: true, Repeat: true, Procs: 1, Slowdown: 1, @@ -134,6 +133,7 @@ func TestParseOptionsCanned(t *testing.T) { HandleSegv: true, Repro: false, LegacyOptions: LegacyOptions{ + Collide: true, Fault: false, FaultCall: -1, FaultNth: 0, diff --git a/pkg/instance/instance_test.go b/pkg/instance/instance_test.go index 5b0bcd4e6..e27361091 100644 --- a/pkg/instance/instance_test.go +++ b/pkg/instance/instance_test.go @@ -91,12 +91,15 @@ func TestExecprogCmd(t *testing.T) { flagFaultNth := flags.Int("fault_nth", 0, "inject fault on n-th operation (0-based)") flagExecutor := flags.String("executor", "./syz-executor", "path to executor binary") flagThreaded := flags.Bool("threaded", true, "use threaded mode in executor") - flagCollide := flags.Bool("collide", true, "collide syscalls to provoke data races") + // In the older syzkaller versions `collide` flag defaulted to `true`, but in this + // test we can change it to false (new default), because syzkaller always explicitly + // sets this flag and never relies on the default value. + flagCollide := flags.Bool("collide", false, "collide syscalls to provoke data races") flagSignal := flags.Bool("cover", false, "collect feedback signals (coverage)") flagSandbox := flags.String("sandbox", "none", "sandbox for fuzzing (none/setuid/namespace)") flagSlowdown := flags.Int("slowdown", 1, "") cmdLine := ExecprogCmd(os.Args[0], "/myexecutor", targets.FreeBSD, targets.I386, - "namespace", true, false, false, 7, 2, 3, true, 10, "myprog") + "namespace", true, false, true, 7, 2, 3, true, 10, "myprog") args := strings.Split(cmdLine, " ")[1:] if err := tool.ParseFlags(flags, args); err != nil { t.Fatal(err) @@ -134,8 +137,8 @@ func TestExecprogCmd(t *testing.T) { if *flagThreaded { t.Errorf("bad threaded: %v, want: %v", *flagThreaded, false) } - if *flagCollide { - t.Errorf("bad collide: %v, want: %v", *flagCollide, false) + if !*flagCollide { + t.Errorf("bad collide: %v, want: %v", *flagCollide, true) } if *flagSlowdown != 10 { t.Errorf("bad slowdown: %v, want: %v", *flagSlowdown, 10) diff --git a/pkg/ipc/ipc.go b/pkg/ipc/ipc.go index 03b28e4ce..5bf4738ca 100644 --- a/pkg/ipc/ipc.go +++ b/pkg/ipc/ipc.go @@ -49,11 +49,11 @@ const ( type ExecFlags uint64 const ( - FlagCollectCover ExecFlags = 1 << iota // collect coverage + FlagCollectSignal ExecFlags = 1 << iota // collect feedback signals + FlagCollectCover // collect coverage FlagDedupCover // deduplicate coverage in executor FlagCollectComps // collect KCOV comparisons FlagThreaded // use multiple threads to mitigate blocked syscalls - FlagCollide // collide syscalls to provoke data races FlagEnableCoverageFilter // setup and use bitmap to do coverage filter ) diff --git a/pkg/ipc/ipc_test.go b/pkg/ipc/ipc_test.go index 44fdb67bd..bb110e388 100644 --- a/pkg/ipc/ipc_test.go +++ b/pkg/ipc/ipc_test.go @@ -87,7 +87,7 @@ func TestExecute(t *testing.T) { bin := buildExecutor(t, target) defer os.Remove(bin) - flags := []ExecFlags{0, FlagThreaded, FlagThreaded | FlagCollide} + flags := []ExecFlags{0, FlagThreaded} for _, flag := range flags { t.Logf("testing flags 0x%x\n", flag) cfg := &Config{ diff --git a/pkg/ipc/ipcconfig/ipcconfig.go b/pkg/ipc/ipcconfig/ipcconfig.go index 3791322f2..5be4d4b39 100644 --- a/pkg/ipc/ipcconfig/ipcconfig.go +++ b/pkg/ipc/ipcconfig/ipcconfig.go @@ -14,7 +14,6 @@ import ( var ( flagExecutor = flag.String("executor", "./syz-executor", "path to executor binary") flagThreaded = flag.Bool("threaded", true, "use threaded mode in executor") - flagCollide = flag.Bool("collide", true, "collide syscalls to provoke data races") flagSignal = flag.Bool("cover", false, "collect feedback signals (coverage)") flagSandbox = flag.String("sandbox", "none", "sandbox for fuzzing (none/setuid/namespace/android)") flagDebug = flag.Bool("debug", false, "debug output from executor") @@ -46,8 +45,8 @@ func Default(target *prog.Target) (*ipc.Config, *ipc.ExecOpts, error) { if *flagThreaded { opts.Flags |= ipc.FlagThreaded } - if *flagCollide { - opts.Flags |= ipc.FlagCollide + if *flagSignal { + opts.Flags |= ipc.FlagCollectSignal } return c, opts, nil diff --git a/pkg/repro/repro.go b/pkg/repro/repro.go index 8eebb5c6d..06afec8c2 100644 --- a/pkg/repro/repro.go +++ b/pkg/repro/repro.go @@ -442,7 +442,7 @@ func (ctx *context) minimizeProg(res *Result) (*Result, error) { return res, nil } -// Simplify repro options (threaded, collide, sandbox, etc). +// Simplify repro options (threaded, sandbox, etc). func (ctx *context) simplifyProg(res *Result) (*Result, error) { ctx.reproLogf(2, "simplifying guilty program options") start := time.Now() @@ -784,13 +784,6 @@ type Simplify func(opts *csource.Options) bool var progSimplifies = []Simplify{ func(opts *csource.Options) bool { - if !opts.Collide { - return false - } - opts.Collide = false - return true - }, - func(opts *csource.Options) bool { if opts.Collide || !opts.Threaded { return false } diff --git a/pkg/repro/repro_test.go b/pkg/repro/repro_test.go index 9b639cd7d..d02ea6d67 100644 --- a/pkg/repro/repro_test.go +++ b/pkg/repro/repro_test.go @@ -79,7 +79,6 @@ func TestBisect(t *testing.T) { func TestSimplifies(t *testing.T) { opts := csource.Options{ Threaded: true, - Collide: true, Repeat: true, Procs: 10, Sandbox: "namespace", diff --git a/pkg/runtest/run.go b/pkg/runtest/run.go index 1d3412cb0..87634a3dc 100644 --- a/pkg/runtest/run.go +++ b/pkg/runtest/run.go @@ -403,7 +403,7 @@ func (ctx *Context) createSyzTest(p *prog.Prog, sandbox string, threaded, cov bo } cfg.Flags |= sandboxFlags if threaded { - opts.Flags |= ipc.FlagThreaded | ipc.FlagCollide + opts.Flags |= ipc.FlagThreaded } if cov { cfg.Flags |= ipc.FlagSignal @@ -447,7 +447,6 @@ func (ctx *Context) createSyzTest(p *prog.Prog, sandbox string, threaded, cov bo func (ctx *Context) createCTest(p *prog.Prog, sandbox string, threaded bool, times int) (*RunRequest, error) { opts := csource.Options{ Threaded: threaded, - Collide: false, Repeat: times > 1, RepeatTimes: times, Procs: 1, @@ -485,7 +484,7 @@ func (ctx *Context) createCTest(p *prog.Prog, sandbox string, threaded bool, tim } var ipcFlags ipc.ExecFlags if threaded { - ipcFlags |= ipc.FlagThreaded | ipc.FlagCollide + ipcFlags |= ipc.FlagThreaded } req := &RunRequest{ P: p, |
