Obtain s390x-linux-gnu-gcc
at least GCC version 9. The latest Debian/Ubuntu/Fedora distributions
should provide a recent enough version of a cross-compiler in the gcc-s390x-linux-gnu
package.
Checkout Linux kernel source:
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git $KERNEL
Generate default configs:
cd $KERNEL
make ARCH=s390 CROSS_COMPILE=s390x-linux-gnu- defconfig
make ARCH=s390 CROSS_COMPILE=s390x-linux-gnu- kvm_guest.config
Enable kernel config options required for syzkaller as described here.
./scripts/config --file .config \
-d MODULES \
-e KCOV \
-e KCOV_INSTRUMENT_ALL \
-e KCOV_ENABLE_COMPARISONS \
-e KASAN \
-e KASAN_INLINE \
-e CONFIGFS_FS \
-e SECURITYFS \
-e DEBUG_INFO \
-e GDB_SCRIPTS \
-e PRINTK \
-e EARLY_PRINTK \
-e DEVTMPFS \
-e TUN \
-e VIRTIO_PCI \
-e VIRTIO_NET \
-e NET_9P_VIRTIO \
-e NET_9P \
-e 9P_FS \
-e BINFMT_MISC \
-e FAULT_INJECTION \
-e FAILSLAB \
-e FAIL_PAGE_ALLOC \
-e FAIL_MAKE_REQUEST \
-e FAIL_IO_TIMEOUT \
-e FAIL_FUTEX \
-e FAULT_INJECTION_DEBUG_FS \
-e FAULT_INJECTION_STACKTRACE_FILTER \
-e DEBUG_KMEMLEAK
Edit .config
file manually and enable them (or do that through make menuconfig
if you prefer).
Since enabling these options results in more sub options being available, we need to regenerate config:
make ARCH=s390 CROSS_COMPILE=s390x-linux-gnu- olddefconfig
Build the kernel:
make ARCH=s390 CROSS_COMPILE=s390x-linux-gnu- -j$(nproc)
Now you should have vmlinux
(kernel binary) and bzImage
(packed kernel image):
$ ls $KERNEL/vmlinux
$KERNEL/vmlinux
$ ls $KERNEL/arch/s390/boot/bzImage
$KERNEL/arch/s390/boot/bzImage
To create a Debian Buster Linux image with the minimal set of required packages do:
cd $IMAGE/
wget https://raw.githubusercontent.com/google/syzkaller/master/tools/create-image.sh -O create-image.sh
chmod +x create-image.sh
./create-image.sh -a s390x -d buster
The result should be $IMAGE/buster.img
disk image.
For additional options of create-image.sh
, please refer to ./create-image.sh -h
Run:
qemu-system-s390x \
-M s390-ccw-virtio -cpu max,zpci=on -m 4G -smp 2 \
-kernel $KERNEL/arch/s390/boot/bzImage \
-drive file=$IMAGE/buster.img,if=virtio,format=raw \
-append "rootwait root=/dev/vda net.ifnames=0 biosdevname=0" \
-net nic,model=virtio -net user,host=10.0.2.10,hostfwd=tcp:127.0.0.1:10021-:22 \
-display none -serial mon:stdio \
-pidfile vm.pid 2>&1 | tee vm.log
After that you should be able to ssh to QEMU instance in another terminal:
ssh -i $IMAGE/buster.id_rsa -p 10021 -o "StrictHostKeyChecking no" root@localhost
If this fails with "too many tries", ssh may be passing default keys before
the one explicitly passed with -i
. Append option -o "IdentitiesOnly yes"
.
To kill the running QEMU instance press Ctrl+A
and then X
or run:
kill $(cat vm.pid)
If QEMU works, the kernel boots and ssh succeeds, you can shutdown QEMU and try to run syzkaller.
Build syzkaller as described here, with s390x
target:
make TARGETOS=linux TARGETARCH=s390x
Then create a manager config like the following, replacing the environment
variables $GOPATH
, $KERNEL
and $IMAGE
with their actual values.
{
"target": "linux/s390x",
"http": "127.0.0.1:56741",
"workdir": "$GOPATH/src/github.com/google/syzkaller/workdir",
"kernel_obj": "$KERNEL",
"image": "$IMAGE/buster.img",
"sshkey": "$IMAGE/buster.id_rsa",
"syzkaller": "$GOPATH/src/github.com/google/syzkaller",
"procs": 8,
"type": "qemu",
"vm": {
"count": 4,
"kernel": "$KERNEL/arch/s390/boot/bzImage",
"cpu": 2,
"mem": 2048
}
}
Run syzkaller manager:
mkdir workdir
./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
.
If you get issues after syz-manager
starts, consider running it with the -debug
flag.
Also see this page for troubleshooting tips.