diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2018-06-21 14:53:21 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2018-06-22 16:40:45 +0200 |
| commit | 94ef62054cd1f18fb4deaff776695f5a1670a358 (patch) | |
| tree | 2d0232ec9f20e636b7c5fa12bcd22167948129f1 /pkg/kernel | |
| parent | 2a075d57ab619ae5333c823cc260a722ab0c47fe (diff) | |
pkg/build: move from pkg/kernel
Rename pkg/kernel to pkg/build and prepare for multi-OS support.
Diffstat (limited to 'pkg/kernel')
| -rw-r--r-- | pkg/kernel/generated.go | 113 | ||||
| -rw-r--r-- | pkg/kernel/kernel.go | 164 | ||||
| -rw-r--r-- | pkg/kernel/kernel_test.go | 30 |
3 files changed, 0 insertions, 307 deletions
diff --git a/pkg/kernel/generated.go b/pkg/kernel/generated.go deleted file mode 100644 index 9c8fe51e8..000000000 --- a/pkg/kernel/generated.go +++ /dev/null @@ -1,113 +0,0 @@ -// AUTOGENERATED FILE - -package kernel - -const createImageScript = `#!/bin/bash - - -set -eux - -CLEANUP="" -trap 'eval " $CLEANUP"' EXIT - -if [ ! -e $1/sbin/init ]; then - echo "usage: create-gce-image.sh /dir/with/user/space/system /path/to/bzImage" - exit 1 -fi - -if [ "$(basename $2)" != "bzImage" ]; then - echo "usage: create-gce-image.sh /dir/with/user/space/system /path/to/bzImage" - exit 1 -fi - -SYZ_VM_TYPE="${SYZ_VM_TYPE:-qemu}" -if [ "$SYZ_VM_TYPE" == "qemu" ]; then - : -elif [ "$SYZ_VM_TYPE" == "gce" ]; then - : -else - echo "SYZ_VM_TYPE has unsupported value $SYZ_VM_TYPE" - exit 1 -fi - -sudo umount disk.mnt || true -if [ "$SYZ_VM_TYPE" == "qemu" ]; then - : -elif [ "$SYZ_VM_TYPE" == "gce" ]; then - sudo modprobe nbd - sudo qemu-nbd -d /dev/nbd0 || true -fi -rm -rf disk.mnt disk.raw || true - -fallocate -l 2G disk.raw -if [ "$SYZ_VM_TYPE" == "qemu" ]; then - DISKDEV="$(sudo losetup -f --show -P disk.raw)" - CLEANUP="sudo losetup -d $DISKDEV; $CLEANUP" -elif [ "$SYZ_VM_TYPE" == "gce" ]; then - DISKDEV="/dev/nbd0" - sudo qemu-nbd -c $DISKDEV --format=raw disk.raw - CLEANUP="sudo qemu-nbd -d $DISKDEV; $CLEANUP" -fi -echo -en "o\nn\np\n1\n\n\na\nw\n" | sudo fdisk $DISKDEV -PARTDEV=$DISKDEV"p1" -until [ -e $PARTDEV ]; do sleep 1; done -sudo -E mkfs.ext4 $PARTDEV -mkdir -p disk.mnt -CLEANUP="rm -rf disk.mnt; $CLEANUP" -sudo mount $PARTDEV disk.mnt -CLEANUP="sudo umount disk.mnt; $CLEANUP" -sudo cp -a $1/. disk.mnt/. -sudo cp $2 disk.mnt/vmlinuz -sudo sed -i "/^root/ { s/:x:/::/ }" disk.mnt/etc/passwd -echo "T0:23:respawn:/sbin/getty -L ttyS0 115200 vt100" | sudo tee -a disk.mnt/etc/inittab -echo -en "auto lo\niface lo inet loopback\nauto eth0\niface eth0 inet dhcp\n" | sudo tee disk.mnt/etc/network/interfaces -echo "debugfs /sys/kernel/debug debugfs defaults 0 0" | sudo tee -a disk.mnt/etc/fstab -echo 'binfmt_misc /proc/sys/fs/binfmt_misc binfmt_misc defaults 0 0' | sudo tee -a disk.mnt/etc/fstab -for i in {0..31}; do - echo "KERNEL==\"binder$i\", NAME=\"binder$i\", MODE=\"0666\"" | \ - sudo tee -a disk.mnt/etc/udev/50-binder.rules -done -echo 'SELINUX=disabled' | sudo tee disk.mnt/etc/selinux/config - -echo "kernel.printk = 7 4 1 3" | sudo tee -a disk.mnt/etc/sysctl.conf -echo "debug.exception-trace = 0" | sudo tee -a disk.mnt/etc/sysctl.conf -SYZ_SYSCTL_FILE="${SYZ_SYSCTL_FILE:-}" -if [ "$SYZ_SYSCTL_FILE" != "" ]; then - cat $SYZ_SYSCTL_FILE | sudo tee -a disk.mnt/etc/sysctl.conf -fi - -echo -en "127.0.0.1\tlocalhost\n" | sudo tee disk.mnt/etc/hosts -echo "nameserver 8.8.8.8" | sudo tee -a disk.mnt/etc/resolve.conf -echo "ClientAliveInterval 420" | sudo tee -a disk.mnt/etc/ssh/sshd_config -echo "syzkaller" | sudo tee disk.mnt/etc/hostname -rm -f key key.pub -ssh-keygen -f key -t rsa -N "" -sudo mkdir -p disk.mnt/root/.ssh -sudo cp key.pub disk.mnt/root/.ssh/authorized_keys -sudo chown root disk.mnt/root/.ssh/authorized_keys -sudo mkdir -p disk.mnt/boot/grub - -CMDLINE="" -SYZ_CMDLINE_FILE="${SYZ_CMDLINE_FILE:-}" -if [ "$SYZ_CMDLINE_FILE" != "" ]; then - CMDLINE=$(awk '{printf("%s ", $0)}' $SYZ_CMDLINE_FILE) -fi - -cat << EOF | sudo tee disk.mnt/boot/grub/grub.cfg -terminal_input console -terminal_output console -set timeout=0 -menuentry 'linux' --class gnu-linux --class gnu --class os { - insmod vbe - insmod vga - insmod video_bochs - insmod video_cirrus - insmod gzio - insmod part_msdos - insmod ext2 - set root='(hd0,1)' - linux /vmlinuz root=/dev/sda1 console=ttyS0 earlyprintk=serial vsyscall=native rodata=n ftrace_dump_on_oops=orig_cpu oops=panic panic_on_warn=1 nmi_watchdog=panic panic=86400 $CMDLINE -} -EOF -sudo grub-install --target=i386-pc --boot-directory=disk.mnt/boot --no-floppy $DISKDEV -` diff --git a/pkg/kernel/kernel.go b/pkg/kernel/kernel.go deleted file mode 100644 index 5bcc0fc42..000000000 --- a/pkg/kernel/kernel.go +++ /dev/null @@ -1,164 +0,0 @@ -// Copyright 2017 syzkaller project authors. All rights reserved. -// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. - -//go:generate bash -c "echo -en '// AUTOGENERATED FILE\n\n' > generated.go" -//go:generate bash -c "echo -en 'package kernel\n\n' >> generated.go" -//go:generate bash -c "echo -en 'const createImageScript = `#!/bin/bash\n' >> generated.go" -//go:generate bash -c "cat ../../tools/create-gce-image.sh | grep -v '#' >> generated.go" -//go:generate bash -c "echo -en '`\n\n' >> generated.go" - -// Package kernel contains helper functions for working with Linux kernel -// (building kernel/image). -package kernel - -import ( - "bytes" - "fmt" - "io/ioutil" - "os" - "path/filepath" - "runtime" - "strconv" - "strings" - "time" - - "github.com/google/syzkaller/pkg/osutil" -) - -func Build(dir, compiler string, config []byte) error { - configFile := filepath.Join(dir, ".config") - if err := osutil.WriteFile(configFile, config); err != nil { - return fmt.Errorf("failed to write config file: %v", err) - } - if err := osutil.SandboxChown(configFile); err != nil { - return err - } - // 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). - cmd := osutil.Command("make", "oldconfig", "CC="+compiler) - if err := osutil.Sandbox(cmd, true, true); err != nil { - return err - } - cmd.Dir = dir - if _, err := osutil.Run(10*time.Minute, cmd); err != nil { - return err - } - // We build only bzImage as we currently don't use modules. - cpu := strconv.Itoa(runtime.NumCPU()) - cmd = osutil.Command("make", "bzImage", "-j", cpu, "CC="+compiler) - if err := osutil.Sandbox(cmd, true, true); err != nil { - return err - } - cmd.Dir = dir - // Build of a large kernel can take a while on a 1 CPU VM. - if _, err := osutil.Run(3*time.Hour, cmd); err != nil { - return extractRootCause(err) - } - return nil -} - -func Clean(dir string) error { - cpu := strconv.Itoa(runtime.NumCPU()) - cmd := osutil.Command("make", "distclean", "-j", cpu) - if err := osutil.Sandbox(cmd, true, true); err != nil { - return err - } - cmd.Dir = dir - _, err := osutil.Run(10*time.Minute, cmd) - return err -} - -// CreateImage creates a disk image that is suitable for syzkaller. -// Kernel is taken from kernelDir, userspace system is taken from userspaceDir. -// If cmdlineFile is not empty, contents of the file are appended to the kernel command line. -// If sysctlFile is not empty, contents of the file are appended to the image /etc/sysctl.conf. -// Produces image and root ssh key in the specified files. -func CreateImage(targetOS, targetArch, vmType, kernelDir, userspaceDir, cmdlineFile, sysctlFile, - image, sshkey string) error { - if targetOS != "linux" || targetArch != "amd64" { - return fmt.Errorf("only linux/amd64 is supported") - } - if vmType != "qemu" && vmType != "gce" { - return fmt.Errorf("images can be built only for qemu/gce machines") - } - tempDir, err := ioutil.TempDir("", "syz-build") - if err != nil { - return err - } - defer os.RemoveAll(tempDir) - scriptFile := filepath.Join(tempDir, "create.sh") - if err := osutil.WriteExecFile(scriptFile, []byte(createImageScript)); err != nil { - return fmt.Errorf("failed to write script file: %v", err) - } - bzImage := filepath.Join(kernelDir, filepath.FromSlash("arch/x86/boot/bzImage")) - cmd := osutil.Command(scriptFile, userspaceDir, bzImage) - 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), - ) - 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. - if err := osutil.CopyFile(filepath.Join(tempDir, "disk.raw"), image); err != nil { - return err - } - if err := osutil.CopyFile(filepath.Join(tempDir, "key"), sshkey); err != nil { - return err - } - if err := os.Chmod(sshkey, 0600); err != nil { - return err - } - return nil -} - -func CompilerIdentity(compiler string) (string, error) { - output, err := osutil.RunCmd(time.Minute, "", compiler, "--version") - if err != nil { - return "", err - } - if len(output) == 0 { - return "", fmt.Errorf("no output from compiler --version") - } - return strings.Split(string(output), "\n")[0], nil -} - -func extractRootCause(err error) error { - verr, ok := err.(*osutil.VerboseError) - if !ok { - return err - } - var cause []byte - for _, line := range bytes.Split(verr.Output, []byte{'\n'}) { - for _, pattern := range buildFailureCauses { - if pattern.weak && cause != nil { - continue - } - if bytes.Contains(line, pattern.pattern) { - cause = line - break - } - } - } - if cause != nil { - verr.Title = string(cause) - } - return verr -} - -type buildFailureCause struct { - pattern []byte - weak bool -} - -var buildFailureCauses = [...]buildFailureCause{ - {pattern: []byte(": error: ")}, - {pattern: []byte(": fatal error: ")}, - {pattern: []byte(": undefined reference to")}, - {weak: true, pattern: []byte(": final link failed: ")}, - {weak: true, pattern: []byte("collect2: error: ")}, -} diff --git a/pkg/kernel/kernel_test.go b/pkg/kernel/kernel_test.go deleted file mode 100644 index 18d7936d0..000000000 --- a/pkg/kernel/kernel_test.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2017 syzkaller project authors. All rights reserved. -// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. - -package kernel - -import ( - "os/exec" - "strings" - "testing" -) - -func TestCompilerIdentity(t *testing.T) { - compiler := "gcc" - if _, err := exec.LookPath(compiler); err != nil { - t.Skipf("compiler '%v' is not found: %v", compiler, err) - } - id, err := CompilerIdentity(compiler) - if err != nil { - t.Fatalf("failed: %v", err) - } - if len(id) == 0 { - t.Fatalf("identity is empty") - } - if strings.Contains(id, "\n") { - t.Fatalf("identity contains a new line") - } - // We don't know what's the right answer, - // so just print it for manual inspection. - t.Logf("id: '%v'", id) -} |
