aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleksandr Nogikh <nogikh@google.com>2022-01-31 16:06:41 +0000
committerAleksandr Nogikh <wp32pw@gmail.com>2022-02-04 16:42:39 +0100
commite13a05ed99be3112220ed09062bd52e1c0a2ffb6 (patch)
treec7531338a36dd596fbacb57eaa7ac7a0411fb7ee
parentba85f78eaa5355d3f47bd5a11663d614b2c1fa2d (diff)
syz-manager: retriage disabled progs
There are some syscalls (e.g. perf_event_open) which do not really affect the behavior of other calls, but affect their coverage. Therefore, they appear quite often in the corpus and when we disable them, we might drop a significant share of it. Give such dropped programs a second chance by removing disabled calls from them and then re-minimizing the leftover in syz-fuzzer.
-rw-r--r--syz-manager/manager.go28
1 files changed, 28 insertions, 0 deletions
diff --git a/syz-manager/manager.go b/syz-manager/manager.go
index 2a983c929..b5d068a02 100644
--- a/syz-manager/manager.go
+++ b/syz-manager/manager.go
@@ -536,6 +536,18 @@ func (mgr *Manager) loadProg(data []byte, minimized, smashed bool) bool {
// We won't execute it, but remember its hash so
// it is not deleted during minimization.
mgr.disabledHashes[hash.String(data)] = struct{}{}
+ } else {
+ // We cut out the disabled syscalls and let syz-fuzzer retriage and
+ // minimize what remains from the prog. The original prog will be
+ // deleted from the corpus.
+ leftover := programLeftover(mgr.target, mgr.targetEnabledSyscalls, data)
+ if len(leftover) > 0 {
+ mgr.candidates = append(mgr.candidates, rpctype.Candidate{
+ Prog: leftover,
+ Minimized: false,
+ Smashed: smashed,
+ })
+ }
}
return true
}
@@ -547,6 +559,22 @@ func (mgr *Manager) loadProg(data []byte, minimized, smashed bool) bool {
return true
}
+func programLeftover(target *prog.Target, enabled map[*prog.Syscall]bool, data []byte) []byte {
+ p, err := target.Deserialize(data, prog.NonStrict)
+ if err != nil {
+ panic(fmt.Sprintf("subsequent deserialization failed: %s", data))
+ }
+ for i := 0; i < len(p.Calls); {
+ c := p.Calls[i]
+ if !enabled[c.Meta] {
+ p.RemoveCall(i)
+ continue
+ }
+ i++
+ }
+ return p.Serialize()
+}
+
func checkProgram(target *prog.Target, enabled map[*prog.Syscall]bool, data []byte) (bad, disabled bool) {
p, err := target.Deserialize(data, prog.NonStrict)
if err != nil {