/actor

Source code for ACTOR, an action-guided kernel fuzzer (USENIX 2023 paper)

Primary LanguageGo

ACTOR: Action-Guided Kernel Fuzzing

ACTOR, our action-guided kernel fuzzing framework, deviates from traditional methods. Instead of focusing on code coverage optimization, our approach generates fuzzer programs (inputs) that leverage our understanding of triggered actions and their temporal relationships. Specifically, we first capture actions that potentially operate on shared data structures at different times. Then, we synthesize programs using those actions as building blocks, guided by bug templates expressed in our domain-specific language.

For more details, please refer to our paper. This repo contains all necessary sources and instructions to setup and run ACTOR.

Setup

Follow the steps below to get ACTOR up and running!

  1. Check out this repo.
git clone https://github.com/ucsb-seclab/actor.git
cd actor

Dependencies

You will need to build a Linux kernel, syzkaller. Make sure you have all build dependencies for these tools installed (check their official websites). Additionally, the static analysis requires docker.

Static Analysis

  1. Check out the target kernel you want to fuzz (we provide the instrumentation for v5.17 and v6.2-rc5), e.g. for v6.2-rc5
git clone https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
cd linux
git checkout 2241ab53cbb5cdb08a6b2d4688feb13971058f65
  1. [Optional] If it is not one of the kernel versions with provided instrumentation, adapt the instrumentation to work with the target kernel version. For this, check out the patch file. Versions close to the supported ones should be very easy to instrument.

  2. Apply the changes for the instrumentation.

git apply ../setup/kernel/v6-2-rc5.patch
cd ..
  1. Build the docker container that includes the static analysis pass:
cd semantic-inference
docker build -t sem-infer .
cd ..

Now we are ready to perform the static analysis!

  1. But first, you need a kernel config. We suggest to either use defconfig or syzbot's, but any config that works for you is fine. You can generate defconfig by make defconfig.

  2. Run the static analysis. To start the docker:

docker run -ti -v "/path/to/linux":/kernel --entrypoint /bin/bash sem-infer

Inside the docker, run:

cd /kernel
make olddefconfig CC=clang-ktypes
CC=clang-ktypes ./scripts/kconfig/merge_config.sh .config /plugin/actor_static.config
make -C /kernel/ -j `nproc` CC=clang-ktypes 2> /kernel/ptrs.txt

After the compilation finished, you can exit the docker container.

Kernel preparation

  1. Clean up the kernel repo. This will delete the kernel config, please save it beforehand if it is a custom config.
make clean
make mrproper
  1. Regenerate the config/restore the config. Apply changes required by ACTOR:
./scripts/kconfig/merge_config.sh .config ../setup/kernel/actor.config
  1. Build the kernel for fuzzing. If you don't want to use all cores, replace $(nproc) with the number of cores you want to use.
make -j$(nproc)
cd ..

Fuzzer setup

  1. Make sure go is in your PATH and GOPATH points to ., the root of this repo.

  2. Build ACTOR.

cd src/github.com/google/syzkaller/
export GO111MODULE=off
make -j$(nproc)
cd ../../../../

VM setup

  1. Build an image for the VM. Please follow syzkaller's instructions here. ACTOR expects the image and the corresponding key under ./image.

  2. Build IVSHMEM.

cd setup/ivshmem/kernel_module/uio
make
  1. ACTOR expects the kernel modules uio.ko and uio_ivshmem.ko in the directory /root in the VM. Start QEMU with the image, e.g.,
qemu-system-x86_64 -kernel linux/arch/x86/boot/bzImage -append "console=ttyS0 root=/dev/sda debug earlyprintk=serial slub_debug=QUZ nokaslr" -hda image/bullseye.img -net user,hostfwd=tcp::10021-:22 -net nic -enable-kvm -nographic -m 4G -smp 2
  1. In a separate terminal, transfer the two required files via scp. Once you are done, you can shutdown the VM.
scp -i image/bullseye.id_rsa -P10021 linux/drivers/uio/uio.ko root@localhost:
scp -i image/bullseye.id_rsa -P10021 setup/ivshmem/kernel_module/uio/uio_ivshmem.ko root@localhost:

Running ACTOR

  1. Create an work directory.
mkdir -p out/workdir
  1. Copy the ptrs.txt file into the work directory.
cp linux/ptrs.txt out/workdir/
  1. Start fuzzing.
cd setup/actor
../../src/github.com/google/syzkaller/bin/syz-manager -config actor.config

Porting ACTOR to a different kernel

Most of the changes are in a few standalone files that can be copied between versions. As long as the kernel API used in those files does not change, there should not be anything to be done in them. The main task is to adapt the changes in existing files. For this, you can take any of the two diffs provided as a guideline. In many cases, especially if the kernel version is close to the one of the diff, the changes are minimal.

Please note: the implemenation of the kernel module and the fuzzer refer to actions as events.

Bug reports

Citing ACTOR

If you find this work useful for your research, we would appreciate citations using this Bibtex entry.

@inproceedings{Fleischer23,
   author = {Marius Fleischer and Dipanjan Das and Priyanka Bose and Weiheng Bai and Kangjie Lu and Mathias Payer and Christopher Kruegel and Giovanni Vigna},
   title = {{ACTOR}: Action-Guided Kernel Fuzzing},
   booktitle = {32th {USENIX} Security Symposium ({USENIX} Security 23)},
   year = {2023},
   address = {Anaheim, CA},
   url = {https://www.usenix.org/conference/usenixsecurity23/presentation/fleischer},
   publisher = {{USENIX} Association},
}