TrevorChan1 / qemu

Official QEMU mirror. Please see https://www.qemu.org/contribute/ for how to submit changes to QEMU. Pull Requests are ignored. Please only use release tarballs from the QEMU website.

Home Page:http://www.qemu.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

QEMU Automated Virtual Device State Analyzer for Leaking State

The MORPHUZZ (2022) paper found that QEMU was improperly saving / loading virtual device state with its snapshotting mechanism, which was leading to state leakage between snapshot loads. The goal of this project is to automate a method for saving, fuzzing, and analyzing virtual device state information to detect if state information is being improperly saved / loaded by different QEMU virtual devices. This repository is a fork of the original QEMU repo, with modifications to the instrumented files and build process.

More in-depth information on the motivation, steps taken, results, and documentation of this project can be found on this slide deck. A repository with just the modified / source code used for this project can be found here

Project Summary

The code within this repo contains the scripts, function files, and altered QEMU source code for the E1000 (network device), AM53C974 (storage device), and CCID-Card-Passthru (smart card) devices that enables the virtual device state fuzzing and analysis setup. The virtual device code utilizes QEMU's VMState macros to save the raw state data for each field defined in the respective virtual device state data structure right before a snapshot is saved (in pre_save) and right after a snapshot is loaded (in post_load). These files include metadata that enable individual state fields to be compared to detect any differences between what each state field was when it was saved vs. when it was loaded by the snapshot (to detect any possible state leaks). The altered virtual device code also define a pre_load function to randomize virtual device state before loading the snapshot (to fuzz the state before the load and help detect possible sources of state leakage).

This code also includes a fuzzing script that automates saving, fuzzing, loading, and analyzing the saved vs. loaded states by connecting to QEMU Monitor (via socket), running savevm, then looping to loadvm and compare the saved vs. loaded state files generated by pre_save and post_load.

The project also includes a script dedicated to automatically generating the changes implemented for the 3 specified virtual devices here. This script isn't fully finished. It is currently able to scrape QEMU virtual device source code for all virtual device field information from QEMU .c and .h source files where the state struct includes 'state' in its name, with the next steps being to further generalize this method then use the Jinja2 library to generate (or append to if they already exist) the pre_save, post_load, and pre_load functions made in qemu_source.

How to Run Code

The following is instructions on how to replicate the setup used throughout the project.

Create a QEMU Ubuntu x86_64 Virtual Machine

Documentation on how to install QEMU dependencies needed for creating a QEMU VM can be found on the QEMU GitHub page and here

For setting up an Ubuntu VM, you will also need to install an Ubuntu iso file (throughout the project I used Ubuntu Desktop 20.04, but Tiny Core Linux should also work).

// Create a qcow2 QEMU image file
qemu-img create -f qcow2 test_vm.qcow2 16G

// Boot up VM with the installed iso file
qemu-system-x86_64 -m 1024 -enable-kvm \
-drive if=virtio,file=test_vm.qcow2,cache=none \
-cdrom ubuntu-20.04.6-desktop-amd64.iso

// Go through setup process for Ubuntu OS

Install QEMU and Modify Build Process to Include Function Files

Install QEMU source code and dependencies (instructions from QEMU docs)

// Clone repo
git clone https://github.com/TrevorChan1/qemu.git
cd qemu
git submodule init
git submodule update --recursive

// Build QEMU executable with modified source code
./configure --enable-sdl --enable-smartcard --extra-cflags="-g" --target-list=x86_64-softmmu
make

Run VM and Fuzz Script

The following are the commands I used when testing for running the QEMU VM and running the fuzz script

// Compile fuzzing script to an executable
gcc ./trev_monitor.c -o fuzz_qemu

// Run QEMU with necessary attached devices and monitor on a socket
// (If the qemu-system-x86_64 executable is not in this location, it may be in ./build/x86_64-softmmu/qemu-system-x86_64)
./build/qemu-system-x86_64 -hda ./trevor_test.img -m 6G -smp cores=6 -display sdl -chardev socket,server=on,host=0.0.0.0,port=2001,id=ccid,wait=off -usb -device usb-ccid -device ccid-card-passthru,chardev=ccid -device am53c974,id=scsi0 -monitor unix:/tmp/qemu-monitor.sock,server,nowait


// Run fuzz script in a separate terminal as QEMUi s running (takes text file with list of devices to check comparison for)
./fuzz_qemu /path/to/QEMU-statecompare/fuzz_scripts/device_inputs.txt

// Output will be written to ./fuzz_log.txt

Helpful Documentation

If you're just getting started with QEMU, here are a few helpful links:

Links to documentation taken throughout the project:

QEMU README

QEMU is a generic and open source machine & userspace emulator and virtualizer.

QEMU is capable of emulating a complete machine in software without any need for hardware virtualization support. By using dynamic translation, it achieves very good performance. QEMU can also integrate with the Xen and KVM hypervisors to provide emulated hardware while allowing the hypervisor to manage the CPU. With hypervisor support, QEMU can achieve near native performance for CPUs. When QEMU emulates CPUs directly it is capable of running operating systems made for one machine (e.g. an ARMv7 board) on a different machine (e.g. an x86_64 PC board).

QEMU is also capable of providing userspace API virtualization for Linux and BSD kernel interfaces. This allows binaries compiled against one architecture ABI (e.g. the Linux PPC64 ABI) to be run on a host using a different architecture ABI (e.g. the Linux x86_64 ABI). This does not involve any hardware emulation, simply CPU and syscall emulation.

QEMU aims to fit into a variety of use cases. It can be invoked directly by users wishing to have full control over its behaviour and settings. It also aims to facilitate integration into higher level management layers, by providing a stable command line interface and monitor API. It is commonly invoked indirectly via the libvirt library when using open source applications such as oVirt, OpenStack and virt-manager.

QEMU as a whole is released under the GNU General Public License, version 2. For full licensing details, consult the LICENSE file.

Documentation

Documentation can be found hosted online at <https://www.qemu.org/documentation/>. The documentation for the current development version that is available at <https://www.qemu.org/docs/master/> is generated from the docs/ folder in the source tree, and is built by Sphinx <https://www.sphinx-doc.org/en/master/>_.

About

Official QEMU mirror. Please see https://www.qemu.org/contribute/ for how to submit changes to QEMU. Pull Requests are ignored. Please only use release tarballs from the QEMU website.

http://www.qemu.org

License:Other


Languages

Language:C 80.4%Language:C++ 11.8%Language:Python 4.0%Language:Shell 1.5%Language:Assembly 0.6%Language:Meson 0.5%Language:Haxe 0.4%Language:Perl 0.2%Language:Objective-C 0.1%Language:Makefile 0.1%Language:SourcePawn 0.1%Language:POV-Ray SDL 0.1%Language:SmPL 0.0%Language:Yacc 0.0%Language:Pawn 0.0%Language:Lex 0.0%Language:NASL 0.0%Language:NSIS 0.0%Language:Dockerfile 0.0%Language:GLSL 0.0%Language:GDB 0.0%Language:Vim Script 0.0%Language:Emacs Lisp 0.0%