diff options
| author | Aleksandr Nogikh <nogikh@google.com> | 2021-09-03 16:20:07 +0000 |
|---|---|---|
| committer | Aleksandr Nogikh <wp32pw@gmail.com> | 2021-09-22 15:40:02 +0200 |
| commit | 1c202847db0380015a8920bfd21375c2d9f28ddb (patch) | |
| tree | 6693da3a936398a9ac6678842ac181c5f0e3e429 /pkg/csource | |
| parent | a7ce77be27d8e3728b97122a005bc5b23298cfc3 (diff) | |
all: refactor fault injection into call props
Now that call properties mechanism is implemented, we can refactor
fault injection.
Unfortunately, it is impossible to remove all traces of the previous apprach.
In reprolist and while performing syz-ci jobs, syzkaller still needs to
parse the old format.
Remove the old prog options-based approach whenever possible and replace
it with the use of call properties.
Diffstat (limited to 'pkg/csource')
| -rw-r--r-- | pkg/csource/common.go | 2 | ||||
| -rw-r--r-- | pkg/csource/csource.go | 4 | ||||
| -rw-r--r-- | pkg/csource/csource_test.go | 4 | ||||
| -rw-r--r-- | pkg/csource/generated.go | 12 | ||||
| -rw-r--r-- | pkg/csource/options.go | 12 | ||||
| -rw-r--r-- | pkg/csource/options_test.go | 46 |
6 files changed, 51 insertions, 29 deletions
diff --git a/pkg/csource/common.go b/pkg/csource/common.go index a0d119bed..a1525e24f 100644 --- a/pkg/csource/common.go +++ b/pkg/csource/common.go @@ -107,7 +107,7 @@ func commonDefines(p *prog.Prog, opts Options) map[string]bool { "SYZ_REPEAT": opts.Repeat, "SYZ_REPEAT_TIMES": opts.RepeatTimes > 1, "SYZ_MULTI_PROC": opts.Procs > 1, - "SYZ_FAULT": opts.Fault, + "SYZ_FAULT": p.HasFaultInjection(), "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 c30db6b9d..5d0d4efd1 100644 --- a/pkg/csource/csource.go +++ b/pkg/csource/csource.go @@ -203,8 +203,8 @@ func (ctx *context) generateCalls(p prog.ExecProg, trace bool) ([]string, []uint ctx.copyin(w, &csumSeq, copyin) } - if ctx.opts.Fault && ctx.opts.FaultCall == ci { - fmt.Fprintf(w, "\tinject_fault(%v);\n", ctx.opts.FaultNth) + if call.Props.FailNth > 0 { + fmt.Fprintf(w, "\tinject_fault(%v);\n", call.Props.FailNth) } // Call itself. callName := call.Meta.CallName diff --git a/pkg/csource/csource_test.go b/pkg/csource/csource_test.go index 9e6fd1a59..ebf22d5f9 100644 --- a/pkg/csource/csource_test.go +++ b/pkg/csource/csource_test.go @@ -58,6 +58,10 @@ func testTarget(t *testing.T, target *prog.Target, full bool) { // Testing 2 programs takes too long since we have lots of options permutations and OS/arch. // So we use the as-is in short tests and minimized version in full tests. syzProg := target.GenerateAllSyzProg(rs) + if len(syzProg.Calls) > 0 { + // Test fault injection generation as well. + p.Calls[0].Props.FailNth = 1 + } var opts []Options if !full || testing.Short() { p.Calls = append(p.Calls, syzProg.Calls...) diff --git a/pkg/csource/generated.go b/pkg/csource/generated.go index b4880f989..27a7bc132 100644 --- a/pkg/csource/generated.go +++ b/pkg/csource/generated.go @@ -238,13 +238,19 @@ static void __attribute__((noinline)) remove_dir(const char* dir) #endif #if !GOOS_linux && !GOOS_netbsd -#if SYZ_EXECUTOR +#if SYZ_EXECUTOR || SYZ_FAULT static int inject_fault(int nth) { return 0; } #endif +#if SYZ_FAULT +static void setup_fault() +{ +} +#endif + #if SYZ_EXECUTOR static int fault_injected(int fail_fd) { @@ -1600,7 +1606,7 @@ static int inject_fault(int nth) en.scope = FAULT_SCOPE_LWP; en.mode = 0; - en.nth = nth + 2; + en.nth = nth + 1; if (ioctl(fd, FAULT_IOC_ENABLE, &en) != 0) failmsg("FAULT_IOC_ENABLE failed", "nth=%d", nth); @@ -9348,7 +9354,7 @@ static int inject_fault(int nth) if (fd == -1) exitf("failed to open /proc/thread-self/fail-nth"); char buf[16]; - sprintf(buf, "%d", nth + 1); + sprintf(buf, "%d", nth); if (write(fd, buf, strlen(buf)) != (ssize_t)strlen(buf)) exitf("failed to write /proc/thread-self/fail-nth"); return fd; diff --git a/pkg/csource/options.go b/pkg/csource/options.go index a0e1fe7ac..36490c8b8 100644 --- a/pkg/csource/options.go +++ b/pkg/csource/options.go @@ -26,10 +26,6 @@ type Options struct { Slowdown int `json:"slowdown"` Sandbox string `json:"sandbox"` - Fault bool `json:"fault,omitempty"` // inject fault into FaultCall/FaultNth - FaultCall int `json:"fault_call,omitempty"` - FaultNth int `json:"fault_nth,omitempty"` - Leak bool `json:"leak,omitempty"` // do leak checking // These options allow for a more fine-tuned control over the generated C code. @@ -54,6 +50,14 @@ type Options struct { // which allows to detect hangs. Repro bool `json:"repro,omitempty"` Trace bool `json:"trace,omitempty"` + LegacyOptions +} + +// These are legacy options, they remain only for the sake of backward compatibility. +type LegacyOptions struct { + Fault bool `json:"fault,omitempty"` + FaultCall int `json:"fault_call,omitempty"` + FaultNth int `json:"fault_nth,omitempty"` } // Check checks if the opts combination is valid or not. diff --git a/pkg/csource/options_test.go b/pkg/csource/options_test.go index 758e91ea1..ba31e4c95 100644 --- a/pkg/csource/options_test.go +++ b/pkg/csource/options_test.go @@ -27,7 +27,7 @@ func TestParseOptions(t *testing.T) { func TestParseOptionsCanned(t *testing.T) { // Dashboard stores csource options with syzkaller reproducers, // so we need to be able to parse old formats. - // nolint: lll + // nolint: lll, dupl 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, @@ -39,9 +39,6 @@ func TestParseOptionsCanned(t *testing.T) { Procs: 10, Slowdown: 1, Sandbox: "namespace", - Fault: true, - FaultCall: 1, - FaultNth: 2, NetInjection: true, NetDevices: true, NetReset: true, @@ -51,6 +48,11 @@ func TestParseOptionsCanned(t *testing.T) { UseTmpDir: true, HandleSegv: true, Repro: true, + LegacyOptions: LegacyOptions{ + Fault: true, + FaultCall: 1, + FaultNth: 2, + }, }, `{"threaded":true,"collide":true,"repeat":true,"procs":10,"sandbox":"android", "fault":true,"fault_call":1,"fault_nth":2,"tun":true,"tmpdir":true,"cgroups":true, @@ -62,9 +64,6 @@ func TestParseOptionsCanned(t *testing.T) { Procs: 10, Slowdown: 1, Sandbox: "android", - Fault: true, - FaultCall: 1, - FaultNth: 2, NetInjection: true, NetDevices: true, NetReset: true, @@ -74,6 +73,11 @@ func TestParseOptionsCanned(t *testing.T) { UseTmpDir: true, HandleSegv: true, Repro: true, + LegacyOptions: LegacyOptions{ + Fault: true, + FaultCall: 1, + FaultNth: 2, + }, }, "{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, @@ -82,9 +86,6 @@ func TestParseOptionsCanned(t *testing.T) { Procs: 1, Slowdown: 1, Sandbox: "none", - Fault: false, - FaultCall: -1, - FaultNth: 0, NetInjection: true, Cgroups: false, BinfmtMisc: false, @@ -92,6 +93,11 @@ func TestParseOptionsCanned(t *testing.T) { UseTmpDir: true, HandleSegv: true, Repro: false, + LegacyOptions: LegacyOptions{ + Fault: false, + FaultCall: -1, + FaultNth: 0, + }, }, "{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, @@ -100,9 +106,6 @@ func TestParseOptionsCanned(t *testing.T) { Procs: 1, Slowdown: 1, Sandbox: "", - Fault: false, - FaultCall: -1, - FaultNth: 0, NetInjection: true, Cgroups: false, BinfmtMisc: false, @@ -110,6 +113,11 @@ func TestParseOptionsCanned(t *testing.T) { UseTmpDir: true, HandleSegv: true, Repro: false, + LegacyOptions: LegacyOptions{ + Fault: false, + FaultCall: -1, + FaultNth: 0, + }, }, "{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, @@ -118,9 +126,6 @@ func TestParseOptionsCanned(t *testing.T) { Procs: 1, Slowdown: 1, Sandbox: "namespace", - Fault: false, - FaultCall: -1, - FaultNth: 0, NetInjection: true, Cgroups: true, BinfmtMisc: false, @@ -128,6 +133,11 @@ func TestParseOptionsCanned(t *testing.T) { UseTmpDir: true, HandleSegv: true, Repro: false, + LegacyOptions: LegacyOptions{ + Fault: false, + FaultCall: -1, + FaultNth: 0, + }, }, } for data, want := range canned { @@ -211,9 +221,7 @@ func enumerateField(OS string, opt Options, field int) []Options { fld.SetInt(val) opts = append(opts, opt) } - } else if fldName == "FaultCall" { - opts = append(opts, opt) - } else if fldName == "FaultNth" { + } else if fldName == "LegacyOptions" { opts = append(opts, opt) } else if fld.Kind() == reflect.Bool { for _, v := range []bool{false, true} { |
