Syzkaller: Coverage-guided Kernel Fuzzer
Syzkaller is a coverage-guided fuzzer for Linux kernel, it was mainly developed by Dmitry Vyukov, and with many other developers, it’s under active development and have found many bugs and the latest reported bugs are listed on the dashboard of syzbot.
Syzkaller was first created for Linux kernels and now supporting many other OS kernels, but for this post, we’ll be only focusing on Android kernel fuzzing.
Build and Setup for Android
Syzkall was written in go, so first thing we need to do is get go compiler, I use below snippets to setup syzkaller environment on my ARM64 box.
machine=$(uname -m)
if [ "${machine}" = "aarch64" ]; then
ARCH=arm64
elif [ "${machine}" = "x86_64" ]; then
ARCH=amd64
fi
wget -c https://dl.google.com/go/go1.14.6.linux-${ARCH}.tar.gz
tar -xf go1.14.6.linux-${ARCH}.tar.gz
mv go $HOME/go/goroot
mkdir -p $HOME/go/gopath
cat << EOT >> .oh-my-zsh/custom/path.zsh
export GOPATH=$HOME/go/gopath
export GOROOT=$HOME/go/goroot
export PATH=$GOPATH/bin:$PATH
export PATH=$GOROOT/bin:$PATH
EOT
go get -u -d github.com/google/syzkaller/prog
cd $GOPATH/src/github.com/google/syzkaller/
make TARGETOS=linux TARGETARCH=arm64
I first build syzkaller on Ubuntu with Intel CPU without any problem, and later I switched an ARM64-based box as develop machine with 2GB RAM, which caused OOM when build syzkaller, you need to add a swap partition or swap file, 2GB will be OK for this.
Configuration for Android
In order to use syzkaller, we need to create a config file. syzkall use adb to communicate to the target board, if serial console is connected, it will associate adb with this serial console, you can find example config here, this is my config file based on that:
{
"target": "linux/arm64",
"http": "192.168.2.21:56789",
"workdir": "/home/fdbai/go/gopath/src/github.com/google/syzkaller/workdir",
"kernel_obj": "/opt/lineageos/kernel/kernel_rpi/",
"syzkaller": "/home/fdbai/go/gopath/src/github.com/google/syzkaller",
"sandbox": "none",
"procs": 8,
"type": "adb",
"cover": true,
"vm": {
"devices": ["192.168.2.7:5555"],
"timeout": 120,
"battery_check": false
}
}
For more config options refer to config.go.
Running syzkaller on Raspberry Pi will end up with adb push timeout, I created a patch adding timeout config option for these low-end embedded devices.
Kernel Configuration
As mentioned before, syzkaller is coverage-guided, therefor KCOV must be enabled, I made my list of configs based on this:
CONFIG_DEBUG_INFO=y
CONFIG_GDB_SCRIPTS=y
CONFIG_DEBUG_INFO_DWARF4=y
CONFIG_CRASH_DUMP=y
CONFIG_KEXEC=y
CONFIG_PROC_KCORE=y
CONFIG_KCOV=y
CONFIG_KCOV_ENABLE_COMPARISONS=y
CONFIG_KCOV_INSTRUMENT_ALL=y
CONFIG_DEBUG_KMEMLEAK=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
CONFIG_NAMESPACES=y
CONFIG_UTS_NS=y
CONFIG_IPC_NS=y
CONFIG_USER_NS=y
CONFIG_PID_NS=y
CONFIG_NET_NS=y
CONFIG_MEMCG=y
CONFIG_CGROUP_PIDS=y
CONFIG_UBSAN=y
CONFIG_KASAN=y
CONFIG_KASAN_INLINE=y
CONFIG_DEBUG_KMEMLEAK=y
CONFIG_SECURITYFS=y
CONFIG_FAULT_INJECTION=y
CONFIG_FAILSLAB=y
CONFIG_FAIL_PAGE_ALLOC=y
CONFIG_FAIL_MAKE_REQUEST=y
CONFIG_FAIL_IO_TIMEOUT=y
CONFIG_FAIL_FUTEX=y
CONFIG_FAULT_INJECTION_DEBUG_FS=y
CONFIG_LOCKDEP=y
CONFIG_PROVE_LOCKING=y
CONFIG_DEBUG_ATOMIC_SLEEP=y
CONFIG_PROVE_RCU=y
CONFIG_DEBUG_VM=y
CONFIG_REFCOUNT_FULL=y
CONFIG_FORTIFY_SOURCE=y
CONFIG_HARDENED_USERCOPY=y
CONFIG_LOCKUP_DETECTOR=y
CONFIG_SOFTLOCKUP_DETECTOR=y
CONFIG_HARDLOCKUP_DETECTOR=y
CONFIG_BOOTPARAM_HARDLOCKUP_PANIC=y
CONFIG_DETECT_HUNG_TASK=y
CONFIG_WQ_WATCHDOG=y
CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=140
CONFIG_RCU_CPU_STALL_TIMEOUT=100
How to Use syzkaller
Now, we have everything needed, execute syz-manager
with config file:
./bin/syz-manager -config=android.cfg
If there is something wrong with running above command, try to append -debug
option to enable debug mode to see what’s happening there.
Web Interface
After the syzkall is up and running, you can view the realtime stats via it’s web interface which will be similar to this one:
Troubleshooting
make error
************************************************************************************
Executor will not be built
Native cross-compiler is missing/broken:
aarch64-linux-gnu-gcc: error trying to exec 'cc1plus': execvp: No such file or directory
************************************************************************************
sudo apt install gcc-8-aarch64-linux-gnu -y
sudo apt install g++-8-aarch64-linux-gnu -y
Failed to parse config file when running syz-manager
2020/07/24 10:01:46 failed to parse config file: invalid character ‘o’ in literal null (expecting ‘u’)
"sandbox": "none",
A: add double quote to none.
Failed to copy binary: timedout
2020/07/24 21:02:21 failed to copy binary: timedout ["adb" "-s" "192.168.1.7:5555" "push" "/home/fdbai/go/gopath/src/github.com/google/syzkaller/bin/linux_arm64/syz-fuzzer" "/data/syz-fuzzer"]
Kcsan does not exist
2019/08/03 09:23:32 concurrency sanitizer: /sys/kernel/debug/kcsan does not exist
Kernel Concurrency Sanitizer (KCSAN) was not supported by kernel v4.19.