aboutsummaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
authorLiz Prucka <lizprucka@google.com>2023-05-16 16:05:06 -0500
committerAleksandr Nogikh <nogikh@google.com>2023-07-10 12:23:24 +0000
commit52ae002a69946d44626bb626463c27ea196a6551 (patch)
tree504173bfa84df7ff35629a481f4920bb937699a5 /pkg
parentd47e94ee5842166fa9b91e7affdeaa8dc4cfcd39 (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.go12
-rw-r--r--pkg/cover/canonicalizer_test.go57
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",