diff options
| author | Aleksandr Nogikh <nogikh@google.com> | 2022-01-31 16:06:41 +0000 |
|---|---|---|
| committer | Aleksandr Nogikh <wp32pw@gmail.com> | 2022-02-04 16:42:39 +0100 |
| commit | e13a05ed99be3112220ed09062bd52e1c0a2ffb6 (patch) | |
| tree | c7531338a36dd596fbacb57eaa7ac7a0411fb7ee | |
| parent | ba85f78eaa5355d3f47bd5a11663d614b2c1fa2d (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.go | 28 |
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 { |
