github.com/google/syzkaller@v0.0.0-20251211124644-a066d2bc4b02/pkg/corpus/minimize.go (about) 1 // Copyright 2024 syzkaller project authors. All rights reserved. 2 // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. 3 4 package corpus 5 6 import ( 7 "sort" 8 9 "github.com/google/syzkaller/pkg/signal" 10 ) 11 12 func (corpus *Corpus) Minimize(cover bool) { 13 corpus.mu.Lock() 14 defer corpus.mu.Unlock() 15 16 inputs := make([]signal.Context, 0, len(corpus.progs)) 17 for _, inp := range corpus.progsMap { 18 inputs = append(inputs, signal.Context{ 19 Signal: inp.Signal, 20 Context: inp, 21 }) 22 } 23 24 // Note: inputs are unsorted (based on map iteration). 25 // This gives some intentional non-determinism during minimization. 26 // However, we want to give preference to non-squashed inputs, 27 // so let's sort by this criteria. 28 // We also want to give preference to smaller corpus programs: 29 // - they are faster to execute, 30 // - minimization occasionally fails, so we need to clean it up over time. 31 sort.SliceStable(inputs, func(i, j int) bool { 32 first := inputs[i].Context.(*Item) 33 second := inputs[j].Context.(*Item) 34 if first.HasAny != second.HasAny { 35 return !first.HasAny 36 } 37 return len(first.Prog.Calls) < len(second.Prog.Calls) 38 }) 39 40 corpus.progsMap = make(map[string]*Item) 41 42 // Overwrite the program lists. 43 corpus.ProgramsList = &ProgramsList{} 44 for _, area := range corpus.focusAreas { 45 area.ProgramsList = &ProgramsList{} 46 } 47 for _, ctx := range signal.Minimize(inputs) { 48 inp := ctx.(*Item) 49 corpus.progsMap[inp.Sig] = inp 50 corpus.saveProgram(inp.Prog, inp.Signal) 51 for area := range inp.areas { 52 area.saveProgram(inp.Prog, inp.Signal) 53 } 54 } 55 }