diff options
| author | Liz Prucka <lizprucka@google.com> | 2023-05-16 16:05:06 -0500 |
|---|---|---|
| committer | Aleksandr Nogikh <nogikh@google.com> | 2023-07-10 12:23:24 +0000 |
| commit | 52ae002a69946d44626bb626463c27ea196a6551 (patch) | |
| tree | 504173bfa84df7ff35629a481f4920bb937699a5 /pkg | |
| parent | d47e94ee5842166fa9b91e7affdeaa8dc4cfcd39 (diff) | |
pkg/cover, syz-manager: support coverage filtering with modules
Apply module conversion to filter bitmap to support coverage
filtering when modules are used.
Coverage bitmap is decanonicalized to match each instance's
module PCs.
This was done by decanonicalizing the map of bitmap PCs before bitmap
creation to simplify conversion. I could convert the final bitmap or
pass in the canonicalization instance to createCoverageFilter() to
prevent this change.
The "coverFilter" used by the manager is only used on
canonicalized PCs, so it remains unchanged.
Diffstat (limited to 'pkg')
| -rw-r--r-- | pkg/cover/canonicalizer.go | 12 | ||||
| -rw-r--r-- | pkg/cover/canonicalizer_test.go | 57 |
2 files changed, 69 insertions, 0 deletions
diff --git a/pkg/cover/canonicalizer.go b/pkg/cover/canonicalizer.go index 48b1bb3df..758ab5593 100644 --- a/pkg/cover/canonicalizer.go +++ b/pkg/cover/canonicalizer.go @@ -117,6 +117,18 @@ func (ci *CanonicalizerInstance) Decanonicalize(cov []uint32, sign signal.Serial ci.decanonicalize.convertPCs(cov, sign) } +func (ci *CanonicalizerInstance) DecanonicalizeFilter(bitmap map[uint32]uint32) map[uint32]uint32 { + // Skip conversion if modules or filter are not used. + if ci.canonical.moduleKeys == nil || len(bitmap) == 0 { + return bitmap + } + instBitmap := make(map[uint32]uint32) + for pc, val := range bitmap { + instBitmap[ci.decanonicalize.convertPC(pc)] = val + } + return instBitmap +} + // Store sorted list of addresses. Used to binary search when converting PCs. func setModuleKeys(moduleKeys []uint32, modules []host.KernelModule) { for idx, module := range modules { diff --git a/pkg/cover/canonicalizer_test.go b/pkg/cover/canonicalizer_test.go index 78356535c..c9e208dcc 100644 --- a/pkg/cover/canonicalizer_test.go +++ b/pkg/cover/canonicalizer_test.go @@ -26,6 +26,8 @@ type Fuzzer struct { instModules *cover.CanonicalizerInstance cov []uint32 goalCov []uint32 + bitmap map[uint32]uint32 + goalBitmap map[uint32]uint32 sign signal.Serial goalSign signal.Serial } @@ -55,6 +57,31 @@ func TestNilModules(t *testing.T) { serv.fuzzers["f2"].sign = signal.FromRaw(serv.fuzzers["f2"].cov, 0).Serialize() serv.fuzzers["f2"].goalSign = signal.FromRaw(serv.fuzzers["f2"].goalCov, 0).Serialize() + serv.fuzzers["f1"].bitmap = map[uint32]uint32{ + 0x00010011: 1, + 0x00020FFF: 2, + 0x00030000: 3, + 0x00040000: 4, + } + serv.fuzzers["f1"].goalBitmap = map[uint32]uint32{ + 0x00010011: 1, + 0x00020FFF: 2, + 0x00030000: 3, + 0x00040000: 4, + } + serv.fuzzers["f2"].bitmap = map[uint32]uint32{ + 0x00010011: 1, + 0x00020FFF: 2, + 0x00030000: 3, + 0x00040000: 4, + } + serv.fuzzers["f2"].goalBitmap = map[uint32]uint32{ + 0x00010011: 1, + 0x00020FFF: 2, + 0x00030000: 3, + 0x00040000: 4, + } + if err := serv.runTest(Canonicalize); err != "" { t.Fatalf("failed in canonicalization: %v", err) } @@ -137,6 +164,31 @@ func TestModules(t *testing.T) { serv.fuzzers["f2"].sign = signal.FromRaw(serv.fuzzers["f2"].cov, 0).Serialize() serv.fuzzers["f2"].goalSign = signal.FromRaw(serv.fuzzers["f2"].goalCov, 0).Serialize() + serv.fuzzers["f1"].bitmap = map[uint32]uint32{ + 0x00010011: 1, + 0x00020FFF: 2, + 0x00030000: 3, + 0x00040000: 4, + } + serv.fuzzers["f1"].goalBitmap = map[uint32]uint32{ + 0x00010011: 1, + 0x00020FFF: 2, + 0x00030000: 3, + 0x00040000: 4, + } + serv.fuzzers["f2"].bitmap = map[uint32]uint32{ + 0x00010011: 1, + 0x00020FFF: 2, + 0x00030000: 3, + 0x00040000: 4, + } + serv.fuzzers["f2"].goalBitmap = map[uint32]uint32{ + 0x00010011: 1, + 0x00040FFF: 2, + 0x00045000: 3, + 0x00020000: 4, + } + if err := serv.runTest(Canonicalize); err != "" { t.Fatalf("failed in canonicalization: %v", err) } @@ -158,6 +210,11 @@ func (serv *RPCServer) runTest(val canonicalizeValue) string { fuzzer.instModules.Canonicalize(fuzzer.cov, fuzzer.sign) } else { fuzzer.instModules.Decanonicalize(fuzzer.cov, fuzzer.sign) + instBitmap := fuzzer.instModules.DecanonicalizeFilter(fuzzer.bitmap) + if !reflect.DeepEqual(instBitmap, fuzzer.goalBitmap) { + return fmt.Sprintf("failed in bitmap conversion. Fuzzer %v.\nExpected: 0x%x.\nReturned: 0x%x", + name, fuzzer.goalBitmap, instBitmap) + } } if !reflect.DeepEqual(fuzzer.cov, fuzzer.goalCov) { return fmt.Sprintf("failed in coverage conversion. Fuzzer %v.\nExpected: 0x%x.\nReturned: 0x%x", |
