diff options
| author | Liz Prucka <lizprucka@google.com> | 2023-05-12 17:04:20 -0500 |
|---|---|---|
| committer | Aleksandr Nogikh <wp32pw@gmail.com> | 2023-05-25 10:44:34 +0200 |
| commit | 51e154a0c54cd90de8e7f061a462420c69a58787 (patch) | |
| tree | 2fbb542d1a3a876bff03004c6c5b3392c099a922 /pkg/cover/canonicalizer_test.go | |
| parent | 4bce1a3e705a8b62de8194bdb28f5eef89c8feec (diff) | |
pkg/cover: disable canonicalization when modules change
Added a check to make sure instance's modules match the
canonical modules. If not, abort fuzzing.
Diffstat (limited to 'pkg/cover/canonicalizer_test.go')
| -rw-r--r-- | pkg/cover/canonicalizer_test.go | 132 |
1 files changed, 64 insertions, 68 deletions
diff --git a/pkg/cover/canonicalizer_test.go b/pkg/cover/canonicalizer_test.go index 4d004aa32..8965b45d9 100644 --- a/pkg/cover/canonicalizer_test.go +++ b/pkg/cover/canonicalizer_test.go @@ -7,6 +7,7 @@ package cover_test import ( "fmt" + "reflect" "strconv" "testing" @@ -22,37 +23,38 @@ type RPCServer struct { type Fuzzer struct { instModules *cover.CanonicalizerInstance + testCov []uint32 + goalOut []uint32 } +type canonicalizeValue int + +const ( + Canonicalize canonicalizeValue = iota + Decanonicalize +) + // Confirms there is no change to coverage if modules aren't instantiated. func TestNilModules(t *testing.T) { serv := &RPCServer{ fuzzers: make(map[string]*Fuzzer), } - serv.Connect("f1", nil) - serv.Connect("f2", nil) + serv.connect("f1", nil) + serv.connect("f2", nil) - testCov := []uint32{0x00010000, 0x00020000, 0x00030000, 0x00040000} - goalOut := []uint32{0x00010000, 0x00020000, 0x00030000, 0x00040000} + serv.fuzzers["f1"].testCov = []uint32{0x00010000, 0x00020000, 0x00030000, 0x00040000} + serv.fuzzers["f1"].goalOut = []uint32{0x00010000, 0x00020000, 0x00030000, 0x00040000} - for name, fuzzer := range serv.fuzzers { - fuzzer.instModules.Canonicalize(testCov) - for idx, cov := range testCov { - if cov != goalOut[idx] { - failMsg := fmt.Errorf("fuzzer %v.\nExpected: 0x%x.\nReturned: 0x%x", - name, goalOut[idx], cov) - t.Fatalf("failed in canonicalization. %v", failMsg) - } - } + serv.fuzzers["f2"].testCov = []uint32{0x00010000, 0x00020000, 0x00030000, 0x00040000} + serv.fuzzers["f2"].goalOut = []uint32{0x00010000, 0x00020000, 0x00030000, 0x00040000} + if err := serv.runTest(Canonicalize); err != "" { + t.Fatalf("failed in canonicalization: %v", err) + } - fuzzer.instModules.Decanonicalize(testCov) - for idx, cov := range testCov { - if cov != goalOut[idx] { - failMsg := fmt.Errorf("fuzzer %v.\nExpected: 0x%x.\nReturned: 0x%x", - name, goalOut[idx], cov) - t.Fatalf("failed in decanonicalization. %v", failMsg) - } - } + serv.fuzzers["f1"].goalOut = []uint32{0x00010000, 0x00020000, 0x00030000, 0x00040000} + serv.fuzzers["f2"].goalOut = []uint32{0x00010000, 0x00020000, 0x00030000, 0x00040000} + if err := serv.runTest(Decanonicalize); err != "" { + t.Fatalf("failed in decanonicalization: %v", err) } } @@ -63,76 +65,58 @@ func TestModules(t *testing.T) { } // Create modules at the specified address offsets. - var f1Modules, f2Modules []host.KernelModule f1ModuleAddresses := []uint64{0x00015000, 0x00020000, 0x00030000, 0x00040000, 0x00045000} f1ModuleSizes := []uint64{0x5000, 0x5000, 0x10000, 0x5000, 0x10000} + f1Modules := initModules(f1ModuleAddresses, f1ModuleSizes) + serv.connect("f1", f1Modules) f2ModuleAddresses := []uint64{0x00015000, 0x00040000, 0x00045000, 0x00020000, 0x00030000} f2ModuleSizes := []uint64{0x5000, 0x5000, 0x10000, 0x5000, 0x10000} - for idx, address := range f1ModuleAddresses { - f1Modules = append(f1Modules, host.KernelModule{ - Name: strconv.FormatInt(int64(idx), 10), - Addr: address, - Size: f1ModuleSizes[idx], - }) - } - for idx, address := range f2ModuleAddresses { - f2Modules = append(f2Modules, host.KernelModule{ - Name: strconv.FormatInt(int64(idx), 10), - Addr: address, - Size: f2ModuleSizes[idx], - }) - } - - serv.Connect("f1", f1Modules) - serv.Connect("f2", f2Modules) - - testCov := make(map[string][]uint32) - goalOutCanonical := make(map[string][]uint32) - goalOutDecanonical := make(map[string][]uint32) + f2Modules := initModules(f2ModuleAddresses, f2ModuleSizes) + serv.connect("f2", f2Modules) // f1 is the "canonical" fuzzer as it is first one instantiated. // This means that all coverage output should be the same as the inputs. - testCov["f1"] = []uint32{0x00010000, 0x00015000, 0x00020000, 0x00025000, 0x00030000, - 0x00035000, 0x00040000, 0x00045000, 0x00050000, 0x00055000} - goalOutCanonical["f1"] = []uint32{0x00010000, 0x00015000, 0x00020000, 0x00025000, 0x00030000, + serv.fuzzers["f1"].testCov = []uint32{0x00010000, 0x00015000, 0x00020000, 0x00025000, 0x00030000, 0x00035000, 0x00040000, 0x00045000, 0x00050000, 0x00055000} - goalOutDecanonical["f1"] = []uint32{0x00010000, 0x00015000, 0x00020000, 0x00025000, 0x00030000, + serv.fuzzers["f1"].goalOut = []uint32{0x00010000, 0x00015000, 0x00020000, 0x00025000, 0x00030000, 0x00035000, 0x00040000, 0x00045000, 0x00050000, 0x00055000} // The modules addresss are inverted between: (2 and 4), (3 and 5), // affecting the output canonical coverage values in these ranges. - testCov["f2"] = []uint32{0x00010000, 0x00015000, 0x00020000, 0x00025000, 0x00030000, + serv.fuzzers["f2"].testCov = []uint32{0x00010000, 0x00015000, 0x00020000, 0x00025000, 0x00030000, 0x00035000, 0x00040000, 0x00045000, 0x00050000, 0x00055000} - goalOutCanonical["f2"] = []uint32{0x00010000, 0x00015000, 0x00040000, 0x00025000, 0x00045000, + serv.fuzzers["f2"].goalOut = []uint32{0x00010000, 0x00015000, 0x00040000, 0x00025000, 0x00045000, 0x0004a000, 0x00020000, 0x00030000, 0x0003b000, 0x00055000} - goalOutDecanonical["f2"] = []uint32{0x00010000, 0x00015000, 0x00020000, 0x00025000, 0x00030000, + if err := serv.runTest(Canonicalize); err != "" { + t.Fatalf("failed in canonicalization: %v", err) + } + + serv.fuzzers["f1"].goalOut = []uint32{0x00010000, 0x00015000, 0x00020000, 0x00025000, 0x00030000, 0x00035000, 0x00040000, 0x00045000, 0x00050000, 0x00055000} + serv.fuzzers["f2"].goalOut = []uint32{0x00010000, 0x00015000, 0x00020000, 0x00025000, 0x00030000, + 0x00035000, 0x00040000, 0x00045000, 0x00050000, 0x00055000} + if err := serv.runTest(Decanonicalize); err != "" { + t.Fatalf("failed in decanonicalization: %v", err) + } +} +func (serv *RPCServer) runTest(val canonicalizeValue) string { for name, fuzzer := range serv.fuzzers { - // Test address conversion from instance to canonical. - fuzzer.instModules.Canonicalize(testCov[name]) - for idx, cov := range testCov[name] { - if cov != goalOutCanonical[name][idx] { - failMsg := fmt.Errorf("fuzzer %v.\nExpected: 0x%x.\nReturned: 0x%x", - name, goalOutCanonical[name][idx], cov) - t.Fatalf("failed in canonicalization. %v", failMsg) - } + if val == Canonicalize { + fuzzer.instModules.Canonicalize(fuzzer.testCov) + } else { + fuzzer.instModules.Decanonicalize(fuzzer.testCov) } - - // Test address conversion from canonical to instance. - fuzzer.instModules.Decanonicalize(testCov[name]) - for idx, cov := range testCov[name] { - if cov != goalOutDecanonical[name][idx] { - failMsg := fmt.Errorf("fuzzer %v.\nExpected: 0x%x.\nReturned: 0x%x", - name, goalOutDecanonical[name][idx], cov) - t.Fatalf("failed in decanonicalization. %v", failMsg) - } + if !reflect.DeepEqual(fuzzer.testCov, fuzzer.goalOut) { + return fmt.Sprintf("fuzzer %v.\nExpected: 0x%x.\nReturned: 0x%x", + name, fuzzer.goalOut, fuzzer.testCov) } } + return "" } -func (serv *RPCServer) Connect(name string, modules []host.KernelModule) { +func (serv *RPCServer) connect(name string, modules []host.KernelModule) { if !serv.modulesInitialized { serv.canonicalModules = cover.NewCanonicalizer(modules) serv.modulesInitialized = true @@ -142,3 +126,15 @@ func (serv *RPCServer) Connect(name string, modules []host.KernelModule) { instModules: serv.canonicalModules.NewInstance(modules), } } + +func initModules(addrs, sizes []uint64) []host.KernelModule { + var modules []host.KernelModule + for idx, addr := range addrs { + modules = append(modules, host.KernelModule{ + Name: strconv.FormatInt(int64(idx), 10), + Addr: addr, + Size: sizes[idx], + }) + } + return modules +} |
