QEMU escape: Part 2 Debugging Environment Set-up



In the previous part, I give an introduction on how to create an ubuntu image for QEMU. However, after beginning to analyse the qemu vulnerability I feel the debugging process is very uncomfortable. What I prefer is just a terminal of QEMU with a guest running on that. This makes me recall what I do on Syzkaller fuzzer.
In this post, I just list the necessary steps to create a much more friendly debugging environment.

Set Up Environment

Step 1: Download Linux Kernel
Go to https://www.kernel.org/ and download the latest version of linux kernel. In this post, I use linux-4.15.7 for building. Then go to the kernel directory and build the kernel

make defconfig
make kvmconfig
make -j 4

Step 2: Create Debian-Stretch Linux image
Install debootstrap first.

sudo apt-get install debootstrap

Then install the necessary utilities for Debian Image

mkdir qemu
sudo debootstrap --include=openssh-server,curl,tar,gcc,\
selinux-utils,policycoreutils,checkpolicy,selinux-policy-default \
stretch qemu

Next create the debian image

set -eux

# Set some defaults and enable promtless ssh to the machine for root.
sudo sed -i '/^root/ { s/:x:/::/ }' qemu/etc/passwd
echo 'T0:23:respawn:/sbin/getty -L ttyS0 115200 vt100' | sudo tee -a qemu/etc/inittab
printf '\nauto enp0s3\niface enp0s3 inet dhcp\n' | sudo tee -a qemu/etc/network/interfaces
echo 'debugfs /sys/kernel/debug debugfs defaults 0 0' | sudo tee -a qemu/etc/fstab
echo "kernel.printk = 7 4 1 3" | sudo tee -a qemu/etc/sysctl.conf
echo 'debug.exception-trace = 0' | sudo tee -a qemu/etc/sysctl.conf
echo "net.core.bpf_jit_enable = 1" | sudo tee -a qemu/etc/sysctl.conf
echo "net.core.bpf_jit_harden = 2" | sudo tee -a qemu/etc/sysctl.conf
echo "net.ipv4.ping_group_range = 0 65535" | sudo tee -a qemu/etc/sysctl.conf
echo -en "\tlocalhost\n" | sudo tee qemu/etc/hosts
echo "nameserver" | sudo tee -a qemu/etc/resolve.conf
echo "ubuntu" | sudo tee qemu/etc/hostname
sudo mkdir -p qemu/root/.ssh/
rm -rf ssh
mkdir -p ssh
ssh-keygen -f ssh/id_rsa -t rsa -N ''
cat ssh/id_rsa.pub | sudo tee qemu/root/.ssh/authorized_keys

# Build a disk image
dd if=/dev/zero of=qemu.img bs=1M seek=2047 count=1
sudo mkfs.ext4 -F qemu.img
sudo mkdir -p /mnt/qemu
sudo mount -o loop qemu.img /mnt/qemu
sudo cp -a qemu/. /mnt/qemu/.
sudo umount /mnt/qemu

Step 3: Run QEMU
I use the following script to start up the virtual machine hosted by QEMU for debugging.

../Security/qemu/bin/debug/build/x86_64-softmmu/qemu-system-x86_64   \
-kernel /home/dango/Kernel/linux-4.15.7/arch/x86/boot/bzImage  \
-append "console=ttyS0 root=/dev/sda rw"  \
-hda /home/dango/Kernel/Image/image03/qemu.img  \
-enable-kvm -m 2G -nographic \
-netdev user,id=t0, -device rtl8139,netdev=t0,id=nic0 \
-netdev user,id=t1, -device pcnet,netdev=t1,id=nic1

After running the guest OS in the terminal, we can simply use copy-and-paste to share the text between the guest and host. To pass large file to virtual machine, we can use the SimpleHTTPServer module in python as mentioned in [2].

Final Step: Expected Result
Pass the mmu.c file to the guest machine, compile and run. We can get the same result as the previous post.

Some notes on the set-up
I make some modifications in the script given in [1].

The first point is adding “rw” in the -append option. Without this option, the file system of guest machine will be read-only with error message ” Failed to start Create Volatile Files and Directories.”

The second point is using “printf ‘\nauto enp0s3\niface enp0s3 inet dhcp\n'” in image creation. The name of the network interface seems to be dependent on the machine.


Except for the friendly debugging environment, another good point of such set-up is the separation of kernel and drive. Since many QEMU vulnerabilities involve the driver operation in the guest, we easily replace the kernel image with the required version and kernel support.


[1] https://github.com/google/syzkaller/blob/master/docs/linux/setup_ubuntu-host_qemu-vm_x86-64-kernel.md
[2] http://blog.vmsplice.net/2011/09/how-to-share-files-instantly-between.html

7 thoughts on “QEMU escape: Part 2 Debugging Environment Set-up

  1. Thanks to your help,i made great progess.but i still met a problem,i do not know how to use gdb connect the qemu.,can you help me solve this problem


    • 真是不好意思又要打扰你了。我不知道你是怎么做到“Pass the mmu.c file to the guest machine”,你可以告诉我具体怎么操作吗


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.