diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2017-12-08 11:33:30 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2017-12-08 11:33:30 +0100 |
| commit | 5e7b20cfc3d38b457f3282bf8227737a8ee4eecd (patch) | |
| tree | 7a2e57c7f699f9e088b79d5f2c1c374cad6b8623 /prog/hints.go | |
| parent | 4016fc5ad7f3a4760c28fa7c6c3c1fa30e2ba1de (diff) | |
prog: fix a data race
The race initially showed up on the new benchmark (see race report below).
The race indicated a wrong call passed to replaceArg,
as the result we sanitized the wrong call and left the new call un-sanitized.
Fix this.
Add test that exposes this.
Run benchmarks in race mode during presubmit
(benchmarks have higher chances of uncovering races than tests).
WARNING: DATA RACE
Write at 0x00c42000d3f0 by goroutine 18:
github.com/google/syzkaller/sys/linux.(*arch).sanitizeCall()
sys/linux/init.go:155 +0x256
github.com/google/syzkaller/sys/linux.(*arch).(github.com/google/syzkaller/sys/linux.sanitizeCall)-fm()
sys/linux/init.go:42 +0x4b
github.com/google/syzkaller/prog.(*Prog).replaceArg()
prog/prog.go:357 +0x239
github.com/google/syzkaller/prog.generateHints.func2()
prog/hints.go:105 +0x124
github.com/google/syzkaller/prog.checkConstArg()
prog/hints.go:128 +0xf3
github.com/google/syzkaller/prog.generateHints()
prog/hints.go:120 +0x495
github.com/google/syzkaller/prog.(*Prog).MutateWithHints.func1()
prog/hints.go:72 +0x67
github.com/google/syzkaller/prog.foreachSubargImpl.func1()
prog/analysis.go:86 +0x9f
github.com/google/syzkaller/prog.foreachSubargImpl()
prog/analysis.go:104 +0xc8
github.com/google/syzkaller/prog.foreachArgArray()
prog/analysis.go:113 +0x89
github.com/google/syzkaller/prog.foreachArg()
prog/analysis.go:121 +0x50
github.com/google/syzkaller/prog.(*Prog).MutateWithHints()
prog/hints.go:71 +0x18e
github.com/google/syzkaller/prog.BenchmarkHints.func1()
prog/hints_test.go:477 +0x77
testing.(*B).RunParallel.func1()
testing/benchmark.go:626 +0x156
Previous read at 0x00c42000d3f0 by goroutine 17:
github.com/google/syzkaller/prog.clone()
prog/clone.go:38 +0xbaa
github.com/google/syzkaller/prog.(*Prog).cloneImpl()
prog/clone.go:21 +0x17f
github.com/google/syzkaller/prog.generateHints()
prog/hints.go:95 +0xd0
github.com/google/syzkaller/prog.(*Prog).MutateWithHints.func1()
prog/hints.go:72 +0x67
github.com/google/syzkaller/prog.foreachSubargImpl.func1()
prog/analysis.go:86 +0x9f
github.com/google/syzkaller/prog.foreachSubargImpl()
prog/analysis.go:104 +0xc8
github.com/google/syzkaller/prog.foreachArgArray()
prog/analysis.go:113 +0x89
github.com/google/syzkaller/prog.foreachArg()
prog/analysis.go:121 +0x50
github.com/google/syzkaller/prog.(*Prog).MutateWithHints()
prog/hints.go:71 +0x18e
github.com/google/syzkaller/prog.BenchmarkHints.func1()
prog/hints_test.go:477 +0x77
testing.(*B).RunParallel.func1()
testing/benchmark.go:626 +0x156
Diffstat (limited to 'prog/hints.go')
| -rw-r--r-- | prog/hints.go | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/prog/hints.go b/prog/hints.go index 065e9f8ba..dabb722da 100644 --- a/prog/hints.go +++ b/prog/hints.go @@ -69,11 +69,11 @@ func (p *Prog) MutateWithHints(callIndex int, comps CompMap, exec func(newP *Pro return } foreachArg(c, func(arg, _ Arg, _ *[]Arg) { - generateHints(p, comps, c, arg, exec) + generateHints(p, comps, callIndex, arg, exec) }) } -func generateHints(p *Prog, compMap CompMap, c *Call, arg Arg, exec func(p *Prog)) { +func generateHints(p *Prog, compMap CompMap, callIndex int, arg Arg, exec func(p *Prog)) { if arg.Type().Dir() == DirOut { return } @@ -93,6 +93,7 @@ func generateHints(p *Prog, compMap CompMap, c *Call, arg Arg, exec func(p *Prog } newP, argMap := p.cloneImpl(true) + newCall := newP.Calls[callIndex] validateExec := func() { if err := newP.validate(); err != nil { panic(fmt.Sprintf("invalid hints candidate: %v", err)) @@ -102,9 +103,9 @@ func generateHints(p *Prog, compMap CompMap, c *Call, arg Arg, exec func(p *Prog var originalArg Arg constArgCandidate := func(newArg Arg) { oldArg := argMap[arg] - newP.replaceArg(c, oldArg, newArg, nil) + newP.replaceArg(newCall, oldArg, newArg, nil) validateExec() - newP.replaceArg(c, oldArg, originalArg, nil) + newP.replaceArg(newCall, oldArg, originalArg, nil) } dataArgCandidate := func() { |
