From 7d5020531b93ad5bdf442b60c12806254d1a9e4a Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Thu, 23 Jun 2022 16:34:02 +0200 Subject: pkg/build: support debug tracing Add ability to trace build process and save debug artefacts. Add tracing of ELF signature calculation. Useful for debugging of #2297. --- pkg/build/android.go | 2 +- pkg/build/build.go | 5 +++++ pkg/build/linux.go | 18 ++++++++++++++---- pkg/build/linux_test.go | 3 ++- 4 files changed, 22 insertions(+), 6 deletions(-) (limited to 'pkg') diff --git a/pkg/build/android.go b/pkg/build/android.go index 5f5472724..352f4739e 100644 --- a/pkg/build/android.go +++ b/pkg/build/android.go @@ -122,7 +122,7 @@ func (a android) build(params Params) (ImageDetails, error) { return details, err } - details.Signature, err = elfBinarySignature(vmlinux) + details.Signature, err = elfBinarySignature(vmlinux, params.Tracer) if err != nil { return details, fmt.Errorf("failed to generate signature: %s", err) } diff --git a/pkg/build/build.go b/pkg/build/build.go index d72fe9072..025de57c3 100644 --- a/pkg/build/build.go +++ b/pkg/build/build.go @@ -13,6 +13,7 @@ import ( "strings" "time" + "github.com/google/syzkaller/pkg/debugtracer" "github.com/google/syzkaller/pkg/osutil" "github.com/google/syzkaller/pkg/report" "github.com/google/syzkaller/pkg/vcs" @@ -32,6 +33,7 @@ type Params struct { CmdlineFile string SysctlFile string Config []byte + Tracer debugtracer.DebugTracer } // Information that is returned from the Image function. @@ -61,6 +63,9 @@ type ImageDetails struct { // the version of the compiler/toolchain that was used to build the kernel. // The CompilerID field is not guaranteed to be non-empty. func Image(params Params) (details ImageDetails, err error) { + if params.Tracer == nil { + params.Tracer = &debugtracer.NullTracer{} + } var builder builder builder, err = getBuilder(params.TargetOS, params.TargetArch, params.VMType) if err != nil { diff --git a/pkg/build/linux.go b/pkg/build/linux.go index 775991664..be9a38377 100644 --- a/pkg/build/linux.go +++ b/pkg/build/linux.go @@ -10,7 +10,6 @@ import ( "debug/elf" "encoding/hex" "fmt" - "io" "io/ioutil" "os" "path" @@ -19,6 +18,7 @@ import ( "runtime" "time" + "github.com/google/syzkaller/pkg/debugtracer" "github.com/google/syzkaller/pkg/osutil" "github.com/google/syzkaller/sys/targets" ) @@ -58,7 +58,8 @@ func (linux linux) build(params Params) (ImageDetails, error) { } else if err := embedLinuxKernel(params, kernelPath); err != nil { return details, err } - details.Signature, err = elfBinarySignature(filepath.Join(params.OutputDir, "obj", "vmlinux")) + vmlinux := filepath.Join(params.OutputDir, "obj", "vmlinux") + details.Signature, err = elfBinarySignature(vmlinux, params.Tracer) return details, err } @@ -243,7 +244,7 @@ func queryLinuxCompiler(kernelDir string) (string, error) { // elfBinarySignature calculates signature of an elf binary aiming at runtime behavior // (text/data, debug info is ignored). -func elfBinarySignature(bin string) (string, error) { +func elfBinarySignature(bin string, tracer debugtracer.DebugTracer) (string, error) { f, err := os.Open(bin) if err != nil { return "", fmt.Errorf("failed to open binary for signature: %v", err) @@ -262,7 +263,16 @@ func elfBinarySignature(bin string) (string, error) { if sec.Flags&elf.SHF_ALLOC == 0 || sec.Type == elf.SHT_NOBITS || sec.Type == elf.SHT_NOTE { continue } - io.Copy(hasher, sec.Open()) + data, err := sec.Data() + if err != nil { + return "", fmt.Errorf("failed to read ELF section %v: %v", sec.Name, err) + } + hasher1 := sha256.New() + hasher1.Write(data) + hash := hasher1.Sum(nil) + hasher.Write(hash) + tracer.Log("section %v: size %v signature %v", sec.Name, len(data), hex.EncodeToString(hash[:8])) + tracer.SaveFile(sec.Name, data) } return hex.EncodeToString(hasher.Sum(nil)), nil } diff --git a/pkg/build/linux_test.go b/pkg/build/linux_test.go index 63614e023..af719427c 100644 --- a/pkg/build/linux_test.go +++ b/pkg/build/linux_test.go @@ -14,6 +14,7 @@ import ( "testing" "text/template" + "github.com/google/syzkaller/pkg/debugtracer" "github.com/google/syzkaller/pkg/osutil" ) @@ -86,7 +87,7 @@ func sign(t *testing.T, flags []string, changed, comment bool) string { if err != nil { t.Fatalf("compiler failed: %v\n%s\n\n%s", err, src, out) } - sign, err := elfBinarySignature(bin) + sign, err := elfBinarySignature(bin, &debugtracer.TestTracer{T: t}) if err != nil { t.Fatal(err) } -- cgit mrf-deployment