From ffc74dde6eae7038c8d03e59f7d0dd77b2283994 Mon Sep 17 00:00:00 2001 From: Andrey Konovalov Date: Wed, 14 Jun 2017 13:56:18 +0200 Subject: docs: move setup pages from wiki --- ...setup_linux-host_android-device_arm64-kernel.md | 44 +++ docs/setup_linux-host_qemu-vm_arm64-kernel.md | 151 ++++++++++ ...tup_ubuntu-host_odroid-c2-board_arm64-kernel.md | 332 +++++++++++++++++++++ docs/setup_ubuntu-host_qemu-vm_x86-64-kernel.md | 234 +++++++++++++++ 4 files changed, 761 insertions(+) create mode 100644 docs/setup_linux-host_android-device_arm64-kernel.md create mode 100644 docs/setup_linux-host_qemu-vm_arm64-kernel.md create mode 100644 docs/setup_ubuntu-host_odroid-c2-board_arm64-kernel.md create mode 100644 docs/setup_ubuntu-host_qemu-vm_x86-64-kernel.md (limited to 'docs') diff --git a/docs/setup_linux-host_android-device_arm64-kernel.md b/docs/setup_linux-host_android-device_arm64-kernel.md new file mode 100644 index 000000000..e7ba1788c --- /dev/null +++ b/docs/setup_linux-host_android-device_arm64-kernel.md @@ -0,0 +1,44 @@ +# Setup: Linux host, Android device, arm64 kernel + +Prerequisites: + - go1.8+ toolchain (can be downloaded from [here](https://golang.org/dl/)) + - Android NDK (tested with r12b) (can be downloaded from [here](https://developer.android.com/ndk/downloads/index.html)) + - [Suzy-Q](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/docs/case_closed_debugging.md) device to capture console output (support for other development boards is possible, but it not implemented yet) + +From `syzkaller` checkout: + - Build `syz-manager` for host: +``` +go build -o bin/syz-manager ./syz-manager +``` + + - Build `syz-fuzzer` and `syz-execprog` for arm64: +``` +GOARCH=arm64 go build -o bin/syz-fuzzer ./syz-fuzzer +GOARCH=arm64 go build -o bin/syz-execprog ./tools/syz-execprog +``` + + - Build `syz-executor` for arm64: +``` +/android-ndk-r12b/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-g++ \ + -I/android-ndk-r12b/sources/cxx-stl/llvm-libc++/libcxx/include \ + --sysroot=/android-ndk-r12b/platforms/android-22/arch-arm64 \ + executor/executor.cc -O1 -g -Wall -static -o bin/syz-executor +``` + + - Create config with `"type": "adb"` and specify adb devices to use. For example: +``` +{ + "http": "localhost:50000", + "workdir": "/gopath/src/github.com/google/syzkaller/workdir", + "syzkaller": "/gopath/src/github.com/google/syzkaller", + "vmlinux": "-", + "sandbox": "none", + "procs": 8, + "type": "adb", + "vm": { + "devices": ["ABCD000010"] + } +} +``` + + - Start `syz-manager -config adb.cfg` as usual. diff --git a/docs/setup_linux-host_qemu-vm_arm64-kernel.md b/docs/setup_linux-host_qemu-vm_arm64-kernel.md new file mode 100644 index 000000000..11ffdebc1 --- /dev/null +++ b/docs/setup_linux-host_qemu-vm_arm64-kernel.md @@ -0,0 +1,151 @@ +# Setup: Linux host, QEMU vm, arm64 kernel + +This document will detail the steps involved in setting up a Syzkaller instance fuzzing any ARM64 linux kernel of your choice. + +## Create a disk image + +We will use buildroot to create the disk image. +You can obtain buildroot from [here](https://buildroot.uclibc.org/download.html). +Extract the tarball and perform a `make menuconfig` inside it. +Choose the following options. + + Target options + Target Architecture - Aarch64 (little endian) + Toolchain type + External toolchain - Linaro AArch64 + System Configuration + [*] Enable root login with password + ( ) Root password ⇐= set your password using this option + [*] Run a getty (login prompt) after boot ---> + TTY port - ttyAMA0 + Target packages + [*] Show packages that are also provided by busybox + Networking applications + [*] dhcpcd + [*] openssh + Filesystem images + [*] ext2/3/4 root filesystem + ext2/3/4 variant - ext3 + exact size in blocks - 6000000 + [*] tar the root filesystem + +Run `make`. After the build, confirm that `output/images/rootfs.ext3` exists. + +## Get the ARM64 toolchain from Linaro + +You will require an ARM64 kernel with gcc plugin support. +If not, obtain the ARM64 toolchain from Linaro. +Get `gcc-linaro-6.1.1-2016.08-x86_64_aarch64-linux-gnu.tar.xz` from [here](https://releases.linaro.org/components/toolchain/binaries/latest/aarch64-linux-gnu/). +Extract and add its `bin/` to your `PATH`. +If you have another ARM64 toolchain on your machine, ensure that this newly downloaded toolchain takes precedence. + +## Compile the kernel + +Once you have obtained the source code for the linux kernel you wish to fuzz, do the following. + + $ ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- make defconfig + $ vim .config + +Change the following options : +``` + CONFIG_KCOV=y + CONFIG_KASAN=y + CONFIG_DEBUG_INFO=y + CONFIG_CMDLINE=”console=ttyAMA0” + CONFIG_KCOV_INSTRUMENT_ALL=y + CONFIG_DEBUG_FS=y + CONFIG_NET_9P=y + CONFIG_NET_9P_VIRTIO=y + CONFIG_CROSS_COMPILE="aarch64-linux-gnu-" +``` +``` + $ ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- make -j40 +``` + +If the build was successful, you should have a `arch/arm64/boot/Image` file. + +## Obtain qemu for ARM64 + +Obtain the QEMU source from git or from the latest source release. + + $ ./configure + $ make -j40 + +If the build was successful, you should have a `aarch64-softmmu/qemu-system-aarch64` binary. + +## Boot up manually + +You should be able to start up the kernel as follows. + + $ /path/to/aarch64-softmmu/qemu-system-aarch64 \ + -machine virt \ + -cpu cortex-a57 \ + -nographic -smp 1 \ + -hda /path/to/rootfs.ext3 \ + -kernel /path/to/arch/arm64/boot/Image \ + -append "console=ttyAMA0 root=/dev/vda oops=panic panic_on_warn=1 panic=-1 ftrace_dump_on_oops=orig_cpu debug earlyprintk=serial slub_debug=UZ" \ + -m 2048 \ + -net user,hostfwd=tcp::10023-:22 -net nic + +At this point, you should be able to see a login prompt. + +## Set up the QEMU disk + +Now that we have a shell, let us add a few lines to existing init scripts so that they are executed each time Syzkaller brings up the VM. + +At the top of /etc/init.d/S50sshd add the following lines: + + ifconfig eth0 up + dhcpcd + mount -t debugfs none /sys/kernel/debug + chmod 777 /sys/kernel/debug/kcov + +Comment out the line + + /usr/bin/ssh-keygen -A + +Next we set up ssh. Create an ssh keypair locally and copy the public key to `/authorized_keys` in `/`. Ensure that you do not set a passphrase when creating this key. + +Open `/etc/ssh/sshd_config` and modify the following lines as shown below. + + PermitRootLogin yes + PubkeyAuthentication yes + AuthorizedKeysFile /authorized_keys + PasswordAuthentication yes + +Reboot the machine, and ensure that you can ssh from host to guest as. + + $ ssh -i /path/to/id_rsa root@localhost -P10023 + +## Build syzkaller + +Instructions can be found [here](https://github.com/google/syzkaller/blob/master/README.md). + +## Modify your config file and start off syzkaller + +A sample config file that exercises the required options are shown below. Modify according to your needs. + +``` +{ + "name": "QEMU-aarch64", + "http": ":56700", + "workdir": "/path/to/a/dir/to/store/syzkaller/corpus”, + "vmlinux": “/path/to/vmlinux", + "syzkaller": "/path/to/syzkaller/arm64/", + "image": "/path/to/rootfs.ext3", + "procs": 8, + "type": "qemu", + "vm": { + "count": 1, + "qemu": "/path/to/qemu-system-aarch64", + "qemu_args": "-machine virt -cpu cortex-a57", + "cmdline": "console=ttyAMA0 root=/dev/vda", + "kernel": “/path/to/Image", + "sshkey": "/path/to/ida_rsa", + "cpu": 2, + "mem": 2048 + } +} +``` + +At this point, you should be able to visit `localhost:56700` and view the results of the fuzzing. diff --git a/docs/setup_ubuntu-host_odroid-c2-board_arm64-kernel.md b/docs/setup_ubuntu-host_odroid-c2-board_arm64-kernel.md new file mode 100644 index 000000000..7dd510f2a --- /dev/null +++ b/docs/setup_ubuntu-host_odroid-c2-board_arm64-kernel.md @@ -0,0 +1,332 @@ +# Setup: Ubuntu host, Odroid C2 board, arm64 kernel + +These are the instructions on how to fuzz the kernel on an [Odroid C2](http://www.hardkernel.com/main/products/prdt_info.php) board using Ubuntu 14.04 on the host machine and Ubuntu on the Odroid. + +## Hardware setup + +### Required hardware + +Your hardware setup must satisfy the following requirements: + +1. Host machine should be able to read the Odroid kernel log. +2. Host machine should be able to ssh to the Odroid board. +3. Host machine should be able to forcefully reboot the Odroid. + +The particular setup described below requires the following hardware: + +1. [Odroid C2 board](http://www.hardkernel.com/main/products/prdt_info.php) +2. SD card (8 GB should be enough) +3. SD card reader (like [this one](https://www.amazon.de/gp/product/B009D79VH4/ref=oh_aui_detailpage_o06_s00?ie=UTF8&psc=1)) +4. [USB-UART cable](http://www.hardkernel.com/main/products/prdt_info.php?g_code=G134111883934) +5. USB Ethernet adapter (like [this one](https://www.amazon.de/Apple-MC704LL-A-USB-Ethernet-Adapter/dp/B00W7W9FK0/ref=dp_ob_title_ce)) +6. Ethernet cable +7. USB hub with [Per Port Power Switching support](http://www.gniibe.org/development/ac-power-control-by-USB-hub/index.html) (like D-Link DUB H7, **silver** edition). +8. [USB-DC Plug Cable](http://www.hardkernel.com/main/products/prdt_info.php?g_code=G141637559827) + +If you decide to use a different setup, you will need to update [Odroid-related code](https://github.com/google/syzkaller/blob/master/vm/odroid/odroid.go) in syzkaller manager. + +### Setup Odroid + +1. Download and flash [Ubuntu image](http://odroid.com/dokuwiki/doku.php?id=en:c2_release_linux_ubuntu) onto SD card as described [here](http://odroid.com/dokuwiki/doku.php?id=en:odroid_flashing_tools). +2. Connect USB-UART cable and install minicom as described [here](http://odroid.com/dokuwiki/doku.php?id=en:usb_uart_kit). +3. Connect power plug, Odroid will start booting, make sure you see bootloader and kernel logs in minicom. +4. Make sure you can login through minicom as user `odroid` with password `odroid`. This user is a sudoer. + +When `systemd` starts Odroid stops sending kernel logs to UART. +To fix this login to the Odroid board and add `kernel.printk = 7 4 1 3` line to `/etc/sysctl.conf` and then do `sysctl -p`: +``` bash +$ cat /etc/sysctl.conf | tail -n 1 +kernel.printk = 7 4 1 3 +$ sudo sysctl -p +kernel.printk = 7 4 1 3 +``` + +Now make sure you can see kernel messages in minicom: +``` +$ echo "Some message" | sudo tee /dev/kmsg +Some message +[ 233.128597] Some message +``` + +### Setup network + +1. Connect USB Ethernet adapter to the host machine. +2. Use Ethernet cable to connect Odroid and the host adapter. +3. Use minicom to modify `/etc/network/interfaces` on Odroid: + + ``` + auto eth0 + iface eth0 inet static + address 172.16.0.31 + gateway 172.16.0.1 + netmask 255.255.255.0 + ``` + +4. Reboot Odroid. + +5. Setup the interface on the host machine (though Network Manager or via `/etc/network/interfaces`): + + ``` + auto eth1 + iface eth1 inet static + address 172.16.0.30 + gateway 172.16.0.1 + netmask 255.255.255.0 + ``` + +6. You should now be able to ssh to Odroid (user `root`, password `odroid`): + + ``` bash + $ ssh root@172.16.0.31 + root@172.16.0.31's password: + ... + Last login: Thu Feb 11 11:30:51 2016 + root@odroid64:~# + ``` + +### Setup USB hub + +To perform a hard reset of the Odroid board (by turning off power) I used a D-Link DUB H7 USB hub (**silver** edition, not the black one). +This hub has support for a feature called [Per Port Power Switching](http://www.gniibe.org/development/ac-power-control-by-USB-hub/index.html), which allows to turn off power on a selected port on the hub remotely (via USB connection to the host machine) . + +[To be able to open the hub device entry](http://www.janosgyerik.com/adding-udev-rules-for-usb-debugging-android-devices/) under `/dev/` without being root, add the following file to `/etc/udev/rules.d/` on the host machine: +``` bash +$ cat /etc/udev/rules.d/10-local.rules +SUBSYSTEM=="usb", ATTR{idVendor}=="2001", ATTR{idProduct}=="f103", MODE="0664", GROUP="plugdev" +``` + +`idVendor` and `idProduct` should correspond to the hub vendor and product id (can be seen via `lsusb`). +Don't forget to replug the hub after you add this file. + +``` bash +$ lsusb +... +Bus 003 Device 026: ID 2001:f103 D-Link Corp. DUB-H7 7-port USB 2.0 hub +... +``` + +Communication with the hub is done by sending USB control messages, which requires `libusb`: +``` bash +sudo apt-get install libusb-dev libusb-1.0-0-dev +``` + +Now plug in the hub and try to switch power on some of it's ports. +For that you can use the [hub-ctrl.c](https://github.com/codazoda/hub-ctrl.c) tool by Niibe Yutaka or it's [ simplified Go analog](https://gist.github.com/xairy/37264952ff35da6e7dcf51ef486368e5): +``` bash +$ go run hub.go -bus=3 -device=26 -port=6 -power=0 +Power turned off on port 6 +$ go run hub.go -bus=3 -device=26 -port=6 -power=1 +Power turned on on port 6 +``` + +Note, that the DUB-H7 hub has a weird port numbering: `5, 6, 1, 2, 7, 3, 4` from left to right. + +Connect the Odroid board with a power plug to one of the USB hub ports and make sure you can forcefully reboot the Odroid by turning the power off and back on on this port. + +## Cross-compiler + +You need to compile full GCC cross-compiler tool-chain for aarch64 as described [here](http://preshing.com/20141119/how-to-build-a-gcc-cross-compiler/) (including the standard libraries). +Use GCC revision 242378 (newer revisions should work as well, but weren't tested). +The result should be a `$PREFIX` directory with cross-compiler, standard library headers, etc. +``` +$ ls $PREFIX +aarch64-linux bin include lib libexec share +``` + +## Kernel + +Set environment variables, they will be detected and used during kernel compilation: +``` bash +export PATH="$PREFIX/bin:$PATH" +export ARCH=arm64 +export CROSS_COMPILE=aarch64-linux- +``` + +Clone the linux-next kernel into `$KERNEL`: +``` bash +git clone https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git $KERNEL +cd $KERNEL +``` + +Apply the following patch, otherwise building the kernel with newer GCC fails (the patch is taken from [here](https://patchwork.kernel.org/patch/9380181/)): +``` makefile +diff --git a/Makefile b/Makefile +index 165cf9783a5d..ff8b40dca9e2 100644 +--- a/Makefile ++++ b/Makefile +@@ -653,6 +653,11 @@ KBUILD_CFLAGS += $(call cc-ifversion, -lt, 0409, \ + # Tell gcc to never replace conditional load with a non-conditional one + KBUILD_CFLAGS += $(call cc-option,--param=allow-store-data-races=0) + ++# Stop gcc from converting switches into a form that defeats dead code ++# elimination and can subsequently lead to calls to intentionally ++# undefined functions appearing in the final link. ++KBUILD_CFLAGS += $(call cc-option,--param=max-fsm-thread-path-insns=1) ++ + include scripts/Makefile.gcc-plugins + + ifdef CONFIG_READABLE_ASM +``` + +Apply the following patch to disable KASAN bug detection on stack and globals (kernel doesn't boot, KASAN needs to be fixed): +``` makefile +diff --git a/scripts/Makefile.kasan b/scripts/Makefile.kasan +index 9576775a86f6..8bc4eb36fc1b 100644 +--- a/scripts/Makefile.kasan ++++ b/scripts/Makefile.kasan +@@ -11,7 +11,6 @@ CFLAGS_KASAN_MINIMAL := -fsanitize=kernel-address + + CFLAGS_KASAN := $(call cc-option, -fsanitize=kernel-address \ + -fasan-shadow-offset=$(KASAN_SHADOW_OFFSET) \ +- --param asan-stack=1 --param asan-globals=1 \ + --param asan-instrumentation-with-call-threshold=$(call_threshold)) + + ifeq ($(call cc-option, $(CFLAGS_KASAN_MINIMAL) -Werror),) +``` + +Configure the kernel (you might wan't to enable more configs as listed [here](docs/linux_kernel_configs.md)): +``` bash +make defconfig +# Edit .config to enable the following configs: +# CONFIG_KCOV=y +# CONFIG_KASAN=y +# CONFIG_KASAN_INLINE=y +# CONFIG_TEST_KASAN=m +# CONFIG_PANIC_ON_OOPS=y +make oldconfig +``` + +Build the kernel: +``` bash +make -j48 dtbs Image modules LOCALVERSION=-xc2 +``` + +## Installation + +Install the `mkimage` util with arm64 support (part of the `u-boot-tools` package). +You might have it by default, but it's not available on Ubuntu 14.04 in the default package repos. +In this case download the package from [here](https://launchpad.net/ubuntu/xenial/amd64/u-boot-tools/2016.01+dfsg1-2ubuntu1) and use `sudo dpkg -i` to install. + +Insert the SD card reader with the SD card inside into the host machine. +You should see two partitions automounted (or mount them manually), for example `sdb1` mounted at `$MOUNT_PATH/boot` and `sdb2` mounted at `$MOUNT_PATH/rootfs`. + +Build the kernel image: +``` bash +mkimage -A arm64 -O linux -T kernel -C none -a 0x1080000 -e 0x1080000 -n linux-next -d arch/arm64/boot/Image ./uImage +``` + +Copy the kernel image, modules and device tree: +``` bash +KERNEL_VERSION=`cat ./include/config/kernel.release` +cp ./uImage $MOUNT_PATH/boot/uImage-$KERNEL_VERSION +make modules_install LOCALVERSION=-xc2 INSTALL_MOD_PATH=$MOUNT_PATH/rootfs/ +cp ./arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dtb $MOUNT_PATH/boot/meson-gxbb-odroidc2-$KERNEL_VERSION.dtb +cp .config $MOUNT_PATH/boot/config-$KERNEL_VERSION +``` + +Backup the old bootloader config; if something doesn't work with the new kernel, you can always roll back to the old one by restoring `boot.ini`: +``` bash +cd $MOUNT_PATH/boot/ +cp boot.ini boot.ini.orig +``` + +Replace the bootloader config `boot.ini` (based on the one taken from [here](http://forum.odroid.com/viewtopic.php?p=162045#p162045)) with the following; don't forget to update `version`: +``` +ODROIDC2-UBOOT-CONFIG + +# Set version to $KERNEL_VERSION +setenv version 4.11.0-rc1-next-20170308-xc2-dirty +setenv uImage uImage-${version} +setenv fdtbin meson-gxbb-odroidc2-${version}.dtb + +setenv initrd_high 0xffffffff +setenv fdt_high 0xffffffff +setenv uimage_addr_r 0x01080000 +setenv fdtbin_addr_r 0x01000000 + +# You might need to use root=/dev/mmcblk0p2 below, try booting and see if the current one works. +setenv bootargs "console=ttyAML0,115200 root=/dev/mmcblk1p2 rootwait ro fsck.mode=force fsck.repair=yes net.ifnames=0 oops=panic panic_on_warn=1 panic=86400 systemd.show_status=no" + +fatload mmc 0:1 ${fdtbin_addr_r} ${fdtbin} +fatload mmc 0:1 ${uimage_addr_r} ${uImage} +bootm ${uimage_addr_r} - ${fdtbin_addr_r} +``` + +Sync and unmount: +``` bash +sync +umount $MOUNT_PATH/boot +umount $MOUNT_PATH/rootfs +``` + +Now plug the SD card into the Odroid board and boot. +The new kernel should now be used. +It makes sense to ensure that you still can ssh to Odroid. + +## Syzkaller + +Generate ssh key and copy it to Odroid: +``` bash +mkdir ssh +ssh-keygen -f ssh/id_rsa -t rsa -N '' +ssh root@172.16.0.31 "mkdir /root/.ssh/" +scp ./ssh/id_rsa.pub root@172.16.0.31:/root/.ssh/authorized_keys +``` + +Now make sure you can ssh with the key: +``` bash +ssh -i ./ssh/id_rsa root@172.16.0.31 +``` + +Build syzkaller on you host machine as you do usually. + +Build `syz-manager` and `syz-repro` with `odroid` build tag: +``` bash +go build -tags odroid -o ./bin/syz-manager ./syz-manager +go build -tags odroid -o ./bin/syz-repro ./tools/syz-repro +``` + +Cross compile `syz-fuzzer`, `syz-execprog` and `syz-executor` binaries for arm64: +``` bash +GOARCH=arm64 go build -o bin/syz-fuzzer ./syz-fuzzer +GOARCH=arm64 go build -o bin/syz-execprog ./tools/syz-execprog +$PREFIX/bin/aarch64-linux-gcc executor/executor.cc -O1 -g -Wall -static -o bin/syz-executor -lpthread +``` + +Use the following config: +``` +{ + "http": "127.0.0.1:56741", + "workdir": "/syzkaller/workdir", + "vmlinux": "/linux-next/vmlinux", + "syzkaller": "/go/src/github.com/google/syzkaller", + "rpc": "172.16.0.30:0", + "sandbox": "namespace", + "reproduce": false, + "procs": 8, + "type": "odroid", + "vm": { + "sshkey": "/odroid/ssh/id_rsa", + "host_addr": "172.16.0.30", + "slave_addr": "172.16.0.31", + "console": "/dev/ttyUSB0", + "hub_bus": 3, + "hub_device": 26, + "hub_port": 5 + } +} +``` + +Don't forget to update: + - `workdir` (path to the workdir) + - `vmlinux` (path to the `vmlinux` binary) + - `vm.sshkey` (path to the generated ssh private key) + - `vm.console` (serial device you used in `minicom`) + - `vm.hub_bus` (number of the bus to which USB hub is connected, view with `lsusb`) + - `vm.hub_device` (device number for the USB hub, view with `lsusb`) + - `vm.hub_port` (number of the USB hub port to which Odroid power plug is connected) + +Now start syzkaller: +``` bash +./bin/syz-manager -config=odroid.cfg +``` diff --git a/docs/setup_ubuntu-host_qemu-vm_x86-64-kernel.md b/docs/setup_ubuntu-host_qemu-vm_x86-64-kernel.md new file mode 100644 index 000000000..023b7cb22 --- /dev/null +++ b/docs/setup_ubuntu-host_qemu-vm_x86-64-kernel.md @@ -0,0 +1,234 @@ +# Setup: Ubuntu host, QEMU vm, x86-64 kernel + +These are the instructions on how to fuzz the x86-64 kernel in a QEMU with Ubuntu 14.04 on the host machine and Debian Wheezy in the QEMU instances. + +## GCC + +Since syzkaller requires coverage support in GCC, we need to use a recent GCC version. To checkout GCC 7.1.0 sources to `$GCC` dir: +``` bash +svn checkout svn://gcc.gnu.org/svn/gcc/trunk $GCC +cd $GCC +svn ls -v ^/tags | grep gcc_7_1_0_release +svn up -r 247494 +``` + +Unfortunately there's a typo in `gcc_7_1_0_release`. Apply [this fix](https://patchwork.ozlabs.org/patch/757421/): +``` c +diff --git a/gcc/tree.h b/gcc/tree.h +index 3bca90a..fdaa7af 100644 +--- a/gcc/tree.h ++++ b/gcc/tree.h +@@ -897,8 +897,8 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int, + /* If this is true, we should insert a __cilk_detach call just before + this function call. */ + #define EXPR_CILK_SPAWN(NODE) \ +- (tree_check2 (NODE, __FILE__, __LINE__, __FUNCTION__, \ +- CALL_EXPR, AGGR_INIT_EXPR)->base.u.bits.unsigned_flag) ++ (TREE_CHECK2 (NODE, CALL_EXPR, \ ++ AGGR_INIT_EXPR)->base.u.bits.unsigned_flag) + + /* In a RESULT_DECL, PARM_DECL and VAR_DECL, means that it is + passed by invisible reference (and the TREE_TYPE is a pointer to the true +``` + +Install GCC prerequisites: +``` +sudo apt-get install flex bison libc6-dev libc6-dev-i386 linux-libc-dev linux-libc-dev:i386 libgmp3-dev libmpfr-dev libmpc-dev +``` + +Build GCC: +``` bash +mkdir build +mkdir install +cd build/ +../configure --enable-languages=c,c++ --disable-bootstrap --enable-checking=no --with-gnu-as --with-gnu-ld --with-ld=/usr/bin/ld.bfd --disable-multilib --prefix=$GCC/install/ +make -j64 +make install +``` + +Now you should have GCC binaries in `$GCC/install/bin/`: +``` bash +$ ls $GCC/install/bin/ +c++ gcc-ar gcov-tool x86_64-pc-linux-gnu-gcc-7.0.0 +cpp gcc-nm x86_64-pc-linux-gnu-c++ x86_64-pc-linux-gnu-gcc-ar +g++ gcc-ranlib x86_64-pc-linux-gnu-g++ x86_64-pc-linux-gnu-gcc-nm +gcc gcov x86_64-pc-linux-gnu-gcc x86_64-pc-linux-gnu-gcc-ranlib +``` + +## Kernel + +Checkout Linux kernel source: +``` bash +git clone https://github.com/torvalds/linux.git $KERNEL +``` + +Generate default configs: +``` bash +cd $KERNEL +make defconfig +make kvmconfig +``` + +Now we need to enable some config options required for syzkaller. +Edit `.config` file manually and enable: +``` +CONFIG_KCOV=y +CONFIG_DEBUG_INFO=y +CONFIG_KASAN=y +CONFIG_KASAN_INLINE=y +``` + +You might also want to enable some other kernel configs as described [here](docs/linux-kernel-configs.md). + +Since enabling these options results in more sub options being available, we need to regenerate config. Run this and press enter each time when prompted for some config value to leave it as default: +``` bash +make oldconfig +``` + +Build the kernel with previously built GCC: +``` +make CC='$GCC/install/bin/gcc' -j64 +``` + +Now you should have `vmlinux` (kernel binary) and `bzImage` (packed kernel image): +``` bash +$ ls $KERNEL/vmlinux +$KERNEL/vmlinux +$ ls $KERNEL/arch/x86/boot/bzImage +$KERNEL/arch/x86/boot/bzImage +``` + +## Image + +Install debootstrap: +``` bash +sudo apt-get install debootstrap +``` + +Use [this script](https://github.com/google/syzkaller/blob/master/tools/create-image.sh) to create a minimal Debian-wheezy Linux image. +The result should be `$IMAGE/wheezy.img` disk image. + +Sometimes it's useful to have some additional packages and tools available in the VM even though they are not required to run syzkaller. +The instructions to install some useful tools are below. +They should obviously be executed before packing the `.img` file. + +To install other packages (not required to run syzkaller): +``` bash +sudo chroot wheezy /bin/bash -c "apt-get update; apt-get install -y curl tar time strace gcc make sysbench git vim screen usbutils" +``` + +To install Trinity (not required to run syzkaller): +``` bash +sudo chroot wheezy /bin/bash -c "mkdir -p ~; cd ~/; wget https://github.com/kernelslacker/trinity/archive/v1.5.tar.gz -O trinity-1.5.tar.gz; tar -xf trinity-1.5.tar.gz" +sudo chroot wheezy /bin/bash -c "cd ~/trinity-1.5 ; ./configure.sh ; make -j16 ; make install" +``` + +To install perf (not required to run syzkaller): +``` bash +cp -r $KERNEL wheezy/tmp/ +sudo chroot wheezy /bin/bash -c "apt-get update; apt-get install -y flex bison python-dev libelf-dev libunwind7-dev libaudit-dev libslang2-dev libperl-dev binutils-dev liblzma-dev libnuma-dev" +sudo chroot wheezy /bin/bash -c "cd /tmp/linux/tools/perf/; make" +sudo chroot wheezy /bin/bash -c "cp /tmp/linux/tools/perf/perf /usr/bin/" +rm -r wheezy/tmp/linux +``` + +## QEMU + +Install `QEMU`: +``` bash +sudo apt-get install kvm qemu-kvm +``` + +Make sure the kernel boots and `sshd` starts: +``` bash +qemu-system-x86_64 \ + -kernel $KERNEL/arch/x86/boot/bzImage \ + -append "console=ttyS0 root=/dev/sda debug earlyprintk=serial slub_debug=QUZ"\ + -hda $IMAGE/wheezy.img \ + -net user,hostfwd=tcp::10021-:22 -net nic \ + -enable-kvm \ + -nographic \ + -m 2G \ + -smp 2 \ + -pidfile vm.pid \ + 2>&1 | tee vm.log +``` + +``` +early console in setup code +early console in extract_kernel +input_data: 0x0000000005d9e276 +input_len: 0x0000000001da5af3 +output: 0x0000000001000000 +output_len: 0x00000000058799f8 +kernel_total_size: 0x0000000006b63000 + +Decompressing Linux... Parsing ELF... done. +Booting the kernel. +[ 0.000000] Linux version 4.12.0-rc3+ ... +[ 0.000000] Command line: console=ttyS0 root=/dev/sda debug earlyprintk=serial +... +[ ok ] Starting enhanced syslogd: rsyslogd. +[ ok ] Starting periodic command scheduler: cron. +[ ok ] Starting OpenBSD Secure Shell server: sshd. +``` + +After that you should be able to ssh to QEMU instance in another terminal: +``` bash +ssh -i $IMAGE/ssh/id_rsa -p 10021 -o "StrictHostKeyChecking no" root@localhost +``` + +To kill the running QEMU instance: +``` bash +kill $(cat vm.pid) +``` + +## Go + +Install Go 1.8.1: +``` bash +wget https://storage.googleapis.com/golang/go1.8.1.linux-amd64.tar.gz +tar -xf go1.8.1.linux-amd64.tar.gz +mv go goroot +export GOROOT=`pwd`/goroot +export PATH=$PATH:$GOROOT/bin +mkdir gopath +export GOPATH=`pwd`/gopath +``` + +## syzkaller + +Get and build syzkaller: +``` bash +go get -u -d github.com/google/syzkaller/... +cd gopath/src/github.com/google/syzkaller/ +mkdir workdir +make +``` + +Create manager config like this: +``` +{ + "http": "127.0.0.1:56741", + "workdir": "/gopath/src/github.com/google/syzkaller/workdir", + "vmlinux": "/linux/upstream/vmlinux", + "image": "/image/wheezy.img", + "syzkaller": "/gopath/src/github.com/google/syzkaller", + "procs": 8, + "type": "qemu", + "vm": { + "count": 4, + "kernel": "/linux/arch/x86/boot/bzImage", + "sshkey": "/image/ssh/id_rsa", + "cpu": 2, + "mem": 2048 + } +} +``` + +Run syzkaller manager: +``` bash +./bin/syz-manager -config=my.cfg +``` + +Now syzkaller should be running, you can check manager status with your web browser at `127.0.0.1:56741`. -- cgit mrf-deployment