aboutsummaryrefslogtreecommitdiff
path: root/pkg/build/linux.go
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2019-11-13 19:53:59 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2019-11-13 19:53:59 +0000
commit4be8363327b1283d9a06abbbae57be7f3a69ad89 (patch)
tree3abf13f01a970379dcd4f65d3674be4bb5832a2a /pkg/build/linux.go
parent3ca947b438679edac8de3e298789344194adb37b (diff)
parent7775171a9b00ea7c7ecaff772d35cc1cd87520e4 (diff)
downloadsyzkaller-4be8363327b1283d9a06abbbae57be7f3a69ad89.tar.gz
Merge "Upgrade syzkaller to d797d2018f9550530c469ce03b5ae36cfa1ebd23"HEADmastermain
Diffstat (limited to 'pkg/build/linux.go')
-rw-r--r--pkg/build/linux.go74
1 files changed, 51 insertions, 23 deletions
diff --git a/pkg/build/linux.go b/pkg/build/linux.go
index 3c1051ff9..a74f056c0 100644
--- a/pkg/build/linux.go
+++ b/pkg/build/linux.go
@@ -10,7 +10,11 @@
package build
import (
+ "crypto/sha1"
+ "debug/elf"
+ "encoding/hex"
"fmt"
+ "io"
"io/ioutil"
"os"
"path/filepath"
@@ -22,21 +26,19 @@ import (
type linux struct{}
-func (linux linux) build(targetArch, vmType, kernelDir, outputDir, compiler, userspaceDir,
- cmdlineFile, sysctlFile string, config []byte) error {
- if err := linux.buildKernel(targetArch, kernelDir, outputDir, compiler, config); err != nil {
+func (linux linux) build(params *Params) error {
+ if err := linux.buildKernel(params); err != nil {
return err
}
- if err := linux.createImage(targetArch, vmType, kernelDir, outputDir, userspaceDir, cmdlineFile,
- sysctlFile); err != nil {
+ if err := linux.createImage(params); err != nil {
return err
}
return nil
}
-func (linux) buildKernel(targetArch, kernelDir, outputDir, compiler string, config []byte) error {
- configFile := filepath.Join(kernelDir, ".config")
- if err := osutil.WriteFile(configFile, config); err != nil {
+func (linux) buildKernel(params *Params) error {
+ configFile := filepath.Join(params.KernelDir, ".config")
+ if err := osutil.WriteFile(configFile, params.Config); err != nil {
return fmt.Errorf("failed to write config file: %v", err)
}
if err := osutil.SandboxChown(configFile); err != nil {
@@ -45,34 +47,34 @@ func (linux) buildKernel(targetArch, kernelDir, outputDir, compiler string, conf
// One would expect olddefconfig here, but olddefconfig is not present in v3.6 and below.
// oldconfig is the same as olddefconfig if stdin is not set.
// Note: passing in compiler is important since 4.17 (at the very least it's noted in the config).
- if err := runMake(kernelDir, "oldconfig", "CC="+compiler); err != nil {
+ if err := runMake(params.KernelDir, "oldconfig", "CC="+params.Compiler); err != nil {
return err
}
// Write updated kernel config early, so that it's captured on build failures.
- outputConfig := filepath.Join(outputDir, "kernel.config")
+ outputConfig := filepath.Join(params.OutputDir, "kernel.config")
if err := osutil.CopyFile(configFile, outputConfig); err != nil {
return err
}
// We build only zImage/bzImage as we currently don't use modules.
var target string
- switch targetArch {
+ switch params.TargetArch {
case "386", "amd64":
target = "bzImage"
case "ppc64le":
target = "zImage"
}
- if err := runMake(kernelDir, target, "CC="+compiler); err != nil {
+ if err := runMake(params.KernelDir, target, "CC="+params.Compiler); err != nil {
return err
}
- vmlinux := filepath.Join(kernelDir, "vmlinux")
- outputVmlinux := filepath.Join(outputDir, "obj", "vmlinux")
+ vmlinux := filepath.Join(params.KernelDir, "vmlinux")
+ outputVmlinux := filepath.Join(params.OutputDir, "obj", "vmlinux")
if err := osutil.Rename(vmlinux, outputVmlinux); err != nil {
return fmt.Errorf("failed to rename vmlinux: %v", err)
}
return nil
}
-func (linux) createImage(targetArch, vmType, kernelDir, outputDir, userspaceDir, cmdlineFile, sysctlFile string) error {
+func (linux) createImage(params *Params) error {
tempDir, err := ioutil.TempDir("", "syz-build")
if err != nil {
return err
@@ -84,30 +86,30 @@ func (linux) createImage(targetArch, vmType, kernelDir, outputDir, userspaceDir,
}
var kernelImage string
- switch targetArch {
+ switch params.TargetArch {
case "386", "amd64":
kernelImage = "arch/x86/boot/bzImage"
case "ppc64le":
kernelImage = "arch/powerpc/boot/zImage.pseries"
}
- kernelImagePath := filepath.Join(kernelDir, filepath.FromSlash(kernelImage))
- cmd := osutil.Command(scriptFile, userspaceDir, kernelImagePath, targetArch)
+ kernelImagePath := filepath.Join(params.KernelDir, filepath.FromSlash(kernelImage))
+ cmd := osutil.Command(scriptFile, params.UserspaceDir, kernelImagePath, params.TargetArch)
cmd.Dir = tempDir
cmd.Env = append([]string{}, os.Environ()...)
cmd.Env = append(cmd.Env,
- "SYZ_VM_TYPE="+vmType,
- "SYZ_CMDLINE_FILE="+osutil.Abs(cmdlineFile),
- "SYZ_SYSCTL_FILE="+osutil.Abs(sysctlFile),
+ "SYZ_VM_TYPE="+params.VMType,
+ "SYZ_CMDLINE_FILE="+osutil.Abs(params.CmdlineFile),
+ "SYZ_SYSCTL_FILE="+osutil.Abs(params.SysctlFile),
)
if _, err = osutil.Run(time.Hour, cmd); err != nil {
return fmt.Errorf("image build failed: %v", err)
}
// Note: we use CopyFile instead of Rename because src and dst can be on different filesystems.
- imageFile := filepath.Join(outputDir, "image")
+ imageFile := filepath.Join(params.OutputDir, "image")
if err := osutil.CopyFile(filepath.Join(tempDir, "disk.raw"), imageFile); err != nil {
return err
}
- keyFile := filepath.Join(outputDir, "key")
+ keyFile := filepath.Join(params.OutputDir, "key")
if err := osutil.CopyFile(filepath.Join(tempDir, "key"), keyFile); err != nil {
return err
}
@@ -141,3 +143,29 @@ func runMake(kernelDir string, args ...string) error {
_, err := osutil.Run(time.Hour, cmd)
return err
}
+
+// elfBinarySignature calculates signature of an elf binary aiming at runtime behavior
+// (text/data, debug info is ignored).
+func elfBinarySignature(bin string) (string, error) {
+ f, err := os.Open(bin)
+ if err != nil {
+ return "", fmt.Errorf("failed to open binary for signature: %v", err)
+ }
+ ef, err := elf.NewFile(f)
+ if err != nil {
+ return "", fmt.Errorf("failed to open elf binary: %v", err)
+ }
+ hasher := sha1.New()
+ for _, sec := range ef.Sections {
+ // Hash allocated sections (e.g. no debug info as it's not allocated)
+ // with file data (e.g. no bss). We also ignore .notes section as it
+ // contains some small changing binary blob that seems irrelevant.
+ // It's unclear if it's better to check NOTE type,
+ // or ".notes" name or !PROGBITS type.
+ if sec.Flags&elf.SHF_ALLOC == 0 || sec.Type == elf.SHT_NOBITS || sec.Type == elf.SHT_NOTE {
+ continue
+ }
+ io.Copy(hasher, sec.Open())
+ }
+ return hex.EncodeToString(hasher.Sum(nil)), nil
+}