From 3222d10cbe77bbedb5a7c455e5bcb6b7081a63b7 Mon Sep 17 00:00:00 2001 From: Alexander Potapenko Date: Tue, 28 Nov 2023 11:33:46 +0100 Subject: tools/syz-execprog: use more precise addresses when collecting coverage Make two improvements to addresses obtained from kcov: - call backend.PreviousInstructionPC() so that they point to the __sanitizer_cov_trace_pc calls; - read the top 32 bits of the kernel addresses from /proc/kallsyms instead of using the hardcoded 0xffffffff value --- tools/syz-execprog/execprog.go | 50 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/syz-execprog/execprog.go b/tools/syz-execprog/execprog.go index 70d0eee81..4d5e3d096 100644 --- a/tools/syz-execprog/execprog.go +++ b/tools/syz-execprog/execprog.go @@ -11,10 +11,12 @@ import ( "fmt" "os" "runtime" + "strconv" "sync" "time" "github.com/google/syzkaller/pkg/cover" + "github.com/google/syzkaller/pkg/cover/backend" "github.com/google/syzkaller/pkg/csource" "github.com/google/syzkaller/pkg/db" "github.com/google/syzkaller/pkg/host" @@ -25,6 +27,7 @@ import ( "github.com/google/syzkaller/pkg/tool" "github.com/google/syzkaller/prog" _ "github.com/google/syzkaller/sys" + "github.com/google/syzkaller/sys/targets" ) var ( @@ -72,6 +75,7 @@ func main() { if err != nil { log.Fatalf("%v", err) } + progs := loadPrograms(target, flag.Args()) if len(progs) == 0 { return @@ -102,13 +106,17 @@ func main() { } } } + sysTarget := targets.Get(*flagOS, *flagArch) + upperBase := getKernelUpperBase(sysTarget) ctx := &Context{ - progs: progs, - config: config, - execOpts: execOpts, - gate: ipc.NewGate(2**flagProcs, gateCallback), - shutdown: make(chan struct{}), - repeat: *flagRepeat, + progs: progs, + config: config, + execOpts: execOpts, + gate: ipc.NewGate(2**flagProcs, gateCallback), + shutdown: make(chan struct{}), + repeat: *flagRepeat, + target: sysTarget, + upperBase: upperBase, } var wg sync.WaitGroup wg.Add(*flagProcs) @@ -134,6 +142,8 @@ type Context struct { repeat int pos int lastPrint time.Time + target *targets.Target + upperBase uint32 } func (ctx *Context) run(pid int) { @@ -251,13 +261,39 @@ func (ctx *Context) printHints(p *prog.Prog, info *ipc.ProgInfo) { log.Logf(0, "ncomps=%v ncandidates=%v", ncomps, ncandidates) } +func getKernelUpperBase(target *targets.Target) uint32 { + defaultRet := uint32(0xffffffff) + if target.OS == targets.Linux { + // Read the first 8 bytes from /proc/kallsyms. + f, err := os.Open("/proc/kallsyms") + if err != nil { + log.Logf(1, "could not get kernel fixup address: %v", err) + return defaultRet + } + defer f.Close() + data := make([]byte, 8) + _, err = f.ReadAt(data, 0) + if err != nil { + log.Logf(1, "could not get kernel fixup address: %v", err) + return defaultRet + } + value, err := strconv.ParseUint(string(data), 16, 32) + if err != nil { + log.Logf(1, "could not get kernel fixup address: %v", err) + return defaultRet + } + return uint32(value) + } + return defaultRet +} + func (ctx *Context) dumpCallCoverage(coverFile string, info *ipc.CallInfo) { if len(info.Cover) == 0 { return } buf := new(bytes.Buffer) for _, pc := range info.Cover { - fmt.Fprintf(buf, "0x%x\n", cover.RestorePC(pc, 0xffffffff)) + fmt.Fprintf(buf, "0x%x\n", backend.PreviousInstructionPC(ctx.target, cover.RestorePC(pc, ctx.upperBase))) } err := osutil.WriteFile(coverFile, buf.Bytes()) if err != nil { -- cgit mrf-deployment