Note: fuzzing the kernel on a real Android device may brick it.
This document details the steps involved in setting up a syzkaller instance fuzzing an arm32/64
linux kernel on an Android device.
Some features of syzkaller may not yet work properly on arm32
. For example, not all debugging and test coverage features are available in the Linux kernel for arm32
, limiting the efficacy of syskaller in finding bugs fast.
These were tested on an NXP Pico-Pi-IMX7D following the instructions here.
You may find additional details in syzkaller's adb
vm implementation here.
Follow the instructions for your board to install Android and make sure the device boots properly.
Set up the adb bridge so that adb and fastboot work.
Set up a serial port, following the instructions for your device so that you can monitor kernel log messages. On Android-based boards the serial port is typically exposed as a USB (or some custom) port, or over GPIO pins. On phones you can use Android Serial Cable or Suzy-Q. syzkaller can work without a dedicated serial port as well (by falling back to adb shell dmesg -w
), but that is unreliable and turns lots of crashes into "lost connection to test machine" crashes with no additional info.
Get the proper compiler toolchain for your device.
Recompile and reinstall the Linux kernel with debugging kernel options available on your board. You might benefit from backporting KCOV or KASAN patches.
Get syzkaller as described here.
Then build it for either arm
or arm64
target architecture depending on the device you're using.
make TARGETOS=linux TARGETARCH=arm
make TARGETOS=linux TARGETARCH=arm64
In case you have old Android /dev/ion
driver (kernel <= 3.18) before building syzkaller copy old /dev/ion
descriptions:
cp sys/android/* sys/linux
Create a manager config android.cfg
:
{
"target": "linux/arm",
"http": "127.0.0.1:56741",
"workdir": "$GOPATH/src/github.com/google/syzkaller/workdir",
"kernel_obj": "$KERNEL",
"syzkaller": "$GOPATH/src/github.com/google/syzkaller",
"cover": true,
"type": "adb",
"vm": {
"devices": [$DEVICES],
"battery_check": true
}
}
Replace the variables $GOPATH
, $KERNEL
(path to kernel build directory), and $DEVICES
(the device ID for your board as reported by adb devices, e.g. ABCD000010
) with their actual values.
For arm64
use "target": "linux/arm64"
.
If your kernel doesn't support coverage collection (e.g. arm32
without KCOV patches) set "cover": false
.
Turn off battery_check
if your device doesn't have battery service, see the comment here for details.
Run syzkaller manager:
./bin/syz-manager -config=android.cfg
Now syzkaller should be running, you can check manager status with your web browser at 127.0.0.1:56741
.
If you get issues after syz-manager
starts, consider running it with the -debug
flag.
Also see this page for troubleshooting tips and Building a Pixel kernel with KASAN+KCOV or Building a PH-1 kernel with KASAN+KCOV for kernel build/boot instructions.