├── .gitignore ├── .gitmodules ├── CMakeLists.txt ├── README.md ├── configs └── syzkaller │ ├── Makefile │ ├── agamotto-usb.ar5523.cfg │ ├── agamotto-usb.btusb.cfg │ ├── agamotto-usb.go7007.cfg │ ├── agamotto-usb.mwifiex.cfg │ ├── agamotto-usb.pn533.cfg │ ├── agamotto-usb.rsi.cfg │ ├── agamotto-usb.si470x.cfg │ ├── agamotto-usb.usx2y.cfg │ ├── baseline-usb.ar5523.cfg │ ├── baseline-usb.btusb.cfg │ ├── baseline-usb.go7007.cfg │ ├── baseline-usb.mwifiex.cfg │ ├── baseline-usb.pn533.cfg │ ├── baseline-usb.rsi.cfg │ ├── baseline-usb.si470x.cfg │ ├── baseline-usb.usx2y.cfg │ ├── snapshot-usb.ar5523.cfg │ ├── snapshot-usb.btusb.cfg │ ├── snapshot-usb.go7007.cfg │ ├── snapshot-usb.mwifiex.cfg │ ├── snapshot-usb.pn533.cfg │ ├── snapshot-usb.rsi.cfg │ ├── snapshot-usb.si470x.cfg │ └── snapshot-usb.usx2y.cfg ├── guest ├── CMakeLists.txt ├── agamotto.h └── linux │ ├── CMakeLists.txt │ ├── agents │ ├── CMakeLists.txt │ ├── agent-chkpt.c │ ├── agent-debug.sh │ ├── agent-dev-prog.sh │ ├── agent-exit.c │ ├── agent-get-prog.c │ ├── agent-next.c │ ├── agent.sh │ └── generated │ │ ├── agent-aqc100-debug.sh │ │ ├── agent-aqc100-prog01.sh │ │ ├── agent-aqc100-prog02.sh │ │ ├── agent-aqc100-prog03.sh │ │ ├── agent-aqc100-prog04.sh │ │ ├── agent-aqc100-prog05.sh │ │ ├── agent-aqc100-prog80.sh │ │ ├── agent-aqc100-prog81.sh │ │ ├── agent-aqc100-prog96.sh │ │ ├── agent-aqc100-prog97.sh │ │ ├── agent-aqc100-prog98.sh │ │ ├── agent-aqc100-prog99.sh │ │ ├── agent-quark-debug.sh │ │ ├── agent-quark-prog01.sh │ │ ├── agent-quark-prog02.sh │ │ ├── agent-quark-prog03.sh │ │ ├── agent-quark-prog04.sh │ │ ├── agent-quark-prog05.sh │ │ ├── agent-quark-prog80.sh │ │ ├── agent-quark-prog81.sh │ │ ├── agent-quark-prog96.sh │ │ ├── agent-quark-prog97.sh │ │ ├── agent-quark-prog98.sh │ │ ├── agent-quark-prog99.sh │ │ ├── agent-rtl8139-debug.sh │ │ ├── agent-rtl8139-prog01.sh │ │ ├── agent-rtl8139-prog02.sh │ │ ├── agent-rtl8139-prog03.sh │ │ ├── agent-rtl8139-prog04.sh │ │ ├── agent-rtl8139-prog05.sh │ │ ├── agent-rtl8139-prog80.sh │ │ ├── agent-rtl8139-prog81.sh │ │ ├── agent-rtl8139-prog96.sh │ │ ├── agent-rtl8139-prog97.sh │ │ ├── agent-rtl8139-prog98.sh │ │ ├── agent-rtl8139-prog99.sh │ │ ├── agent-snic-debug.sh │ │ ├── agent-snic-prog01.sh │ │ ├── agent-snic-prog02.sh │ │ ├── agent-snic-prog03.sh │ │ ├── agent-snic-prog04.sh │ │ ├── agent-snic-prog05.sh │ │ ├── agent-snic-prog80.sh │ │ ├── agent-snic-prog81.sh │ │ ├── agent-snic-prog96.sh │ │ ├── agent-snic-prog97.sh │ │ ├── agent-snic-prog98.sh │ │ ├── agent-snic-prog99.sh │ │ ├── agent-usb-debug.sh │ │ ├── agent-usb-prog01.sh │ │ ├── agent-usb-prog02.sh │ │ ├── agent-usb-prog03.sh │ │ ├── agent-usb-prog04.sh │ │ ├── agent-usb-prog05.sh │ │ ├── agent-usb-prog80.sh │ │ ├── agent-usb-prog81.sh │ │ ├── agent-usb-prog96.sh │ │ ├── agent-usb-prog97.sh │ │ ├── agent-usb-prog98.sh │ │ ├── agent-usb-prog99.sh │ │ └── agent.sh │ ├── kernel.patch │ ├── progs │ ├── CMakeLists.txt │ ├── prog01.c │ ├── prog02.c │ ├── prog03.sh │ ├── prog04.sh │ ├── prog05.sh │ ├── prog80.sh │ ├── prog81.sh │ ├── prog96.sh │ ├── prog97.c │ ├── prog98.sh │ └── prog99.sh │ └── syz │ ├── CMakeLists.txt │ └── executor.c ├── host └── linux │ └── kernel.patch ├── libafl ├── .gitignore ├── CMakeLists.txt ├── libafl.patch ├── setup.sh └── src │ ├── libafl.c │ └── libafl.h ├── libagamotto ├── CMakeLists.txt ├── include │ └── agamotto.h └── src │ ├── fuzzer.c │ ├── fuzzer.h │ ├── intercept.c │ ├── kvm.c │ ├── kvm.h │ ├── snapshot.c │ └── snapshot.h ├── qemu.patch ├── scripts ├── build-image.sh ├── build-linux-guest.sh ├── copy-modules.py ├── copy-modules.sh ├── create-debian-image.sh ├── create-overlay-image.py ├── create-overlay-image.sh ├── fixup.py ├── fuzz.py ├── reset-overlay+fuzz.sh ├── run-qemu.sh └── seed │ └── Agamotto ├── setup.sh └── syzkaller.patch /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.swp 3 | .DS_Store 4 | /.vscode/ 5 | /build/ 6 | /configs/syzkaller/generated/ 7 | /scripts/chroot/ 8 | /scripts/stretch.* 9 | __pycache__/ 10 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "qemu"] 2 | path = qemu 3 | url = https://github.com/qemu/qemu.git 4 | [submodule "guest/linux/kernel"] 5 | path = guest/linux/kernel 6 | url = https://github.com/google/kasan.git 7 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.7.2) 2 | 3 | if ("$ENV{GOPATH}" STREQUAL "") 4 | message(FATAL_ERROR "GOPATH env var is not set") 5 | endif() 6 | 7 | if (NOT EXISTS $ENV{GOPATH}/src/github.com/google/syzkaller) 8 | message(FATAL_ERROR "Syzkaller is not found under GOPATH") 9 | endif() 10 | 11 | project(agamotto) 12 | 13 | add_subdirectory(libagamotto) 14 | add_subdirectory(libafl) 15 | add_subdirectory(guest) 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Agamotto: Accelerating Kernel Driver Fuzzing with Lightweight Virtual Machine Checkpoints 2 | 3 | ## Prerequisite 4 | 5 | - CMake 3.7.2 or higher (`cmake -version`) 6 | - Go 1.12.3 or higher (`go version`) 7 | - Python 3 8 | 9 | 10 | ## Setup 11 | 12 | ### Download source code 13 | 14 | ```bash 15 | git clone --recursive https://github.com/securesystemslab/agamotto.git 16 | cd agamotto 17 | export AGPATH=$PWD # assumed by commands that follow 18 | ./setup.sh 19 | ``` 20 | 21 | 22 | ### Change the host Linux kernel for custom hypercall support 23 | 24 | Build the host Linux kernel with [our patch](host/linux/kernel.patch) applied, and with `CONFIG_KVM_AGAMOTTO=y`, and install & reboot it. 25 | 26 | #### Tested environment: 27 | - [Ubuntu-hwe-4.18.0-18.19_18.04.1](https://git.launchpad.net/~ubuntu-kernel/ubuntu/+source/linux/+git/bionic) on AMD EPYC 7601 28 | 29 | 30 | ### Download and build Syzkaller 31 | 32 | ```bash 33 | # Get Syzkaller source code 34 | go get -u -d github.com/google/syzkaller 35 | cd $GOPATH/src/github.com/google/syzkaller 36 | git checkout ddc3e85997efdad885e208db6a98bca86e5dd52f 37 | 38 | # Apply patch and build 39 | cd $GOPATH/src/github.com/google/syzkaller 40 | patch -p0 <$AGPATH/syzkaller.patch 41 | make 42 | ``` 43 | 44 | 45 | ### Build project and generate necessary files 46 | 47 | ```bash 48 | # Build project 49 | cd $AGPATH/build 50 | cmake .. 51 | make 52 | ``` 53 | 54 | 55 | ### Setup QEMU 56 | 57 | ```bash 58 | # Apply patch 59 | cd $AGPATH/qemu 60 | patch -p0 <$AGPATH/qemu.patch 61 | 62 | # Build 63 | mkdir $AGPATH/build/qemu 64 | cd $AGPATH/build/qemu 65 | $AGPATH/qemu/configure --prefix=$AGPATH/build/qemu/install --target-list=x86_64-softmmu --with-agamotto=$AGPATH/build/libagamotto --enable-debug 66 | make -j4 install 67 | ``` 68 | 69 | 70 | ### Setup VM 71 | 72 | - Patch and build Linux kernel 73 | ```bash 74 | cd $AGPATH/guest/linux/kernel 75 | patch -p0 <../kernel.patch 76 | ``` 77 | 78 | ```bash 79 | cd $AGPATH/scripts 80 | ./build-linux-guest.sh all ../guest/linux/kernel/ 81 | ``` 82 | 83 | - Create a Debian image 84 | ```bash 85 | cd $AGPATH/scripts 86 | ./create-debian-image.sh # Create an image 87 | ./copy-modules.py all -d stretch.img # Copy necessary files into the image 88 | ``` 89 | 90 | 91 | ### Start fuzzing 92 | 93 | ```bash 94 | # Generate Syzkaller config files 95 | cd $AGPATH 96 | make -C configs/syzkaller VMCNT= -B 97 | 98 | # Run Syzkaller USB fuzzing 99 | cd $GOPATH/src/github.com/google/syzkaller 100 | export PATH=$AGPATH/build/qemu/install/bin:$PATH 101 | export LD_LIBRARY_PATH=$AGPATH/build/libagamotto:$LD_LIBRARY_PATH 102 | ./bin/syz-manager -config $AGPATH/configs/syzkaller/generated/.cfg 103 | ``` 104 | 105 | ```bash 106 | # Run AFL PCI fuzzing 107 | cd $AGPATH/scripts 108 | ./create-overlay-image.py rtl8139 -d stretch.img 109 | export PATH=$AGPATH/build/qemu/install/bin:$PATH 110 | export LD_LIBRARY_PATH=$AGPATH/build/libagamotto:$LD_LIBRARY_PATH 111 | ./fuzz.py rtl8139 -g linux-prog05 -i seed/ -N 112 | ``` 113 | 114 | ## Citing our work 115 | 116 | ``` 117 | @inproceedings{song2020agamotto, 118 | title = {{Agamotto}: Accelerating Kernel Driver Fuzzing with 119 | Lightweight Virtual Machine Checkpoints}, 120 | author = {Song, Dokyung and Hetzelt, Felicitas and Kim, Jonghwan and 121 | Kang, Brent Byunghoon and Seifert, Jean-Pierre and Franz, 122 | Michael}, 123 | booktitle = {{USENIX} Security Symposium}, 124 | year = {2020} 125 | } 126 | ``` 127 | -------------------------------------------------------------------------------- /configs/syzkaller/Makefile: -------------------------------------------------------------------------------- 1 | FIXUP=../../scripts/fixup.py 2 | 3 | MODES=baseline agamotto snapshot 4 | 5 | HOST?=localhost 6 | PORT?=56841 7 | WORKDIR?=workdir 8 | VMCNT?=1 9 | 10 | CONFIGS=usb.rsi usb.mwifiex usb.ar5523 usb.btusb usb.usx2y usb.pn533 usb.go7007 usb.si470x 11 | 12 | files := $(foreach mode,$(MODES),$(foreach config,$(CONFIGS),generated/$(mode)-$(config).cfg)) 13 | files_1 := $(foreach mode,$(MODES),$(foreach config,$(CONFIGS),generated/$(mode)-$(config).cfg.1)) 14 | files_2 := $(foreach mode,$(MODES),$(foreach config,$(CONFIGS),generated/$(mode)-$(config).cfg.2)) 15 | files_3 := $(foreach mode,$(MODES),$(foreach config,$(CONFIGS),generated/$(mode)-$(config).cfg.3)) 16 | 17 | all: $(files) $(files_1) $(files_2) $(files_3) 18 | 19 | generated/%-2d.cfg: %-2d.cfg |generated 20 | $(FIXUP) -i $^ -o $@ -c $(VMCNT) -t $(HOST) -p $(PORT) -w $(WORKDIR) 21 | 22 | generated/%.cfg: %.cfg |generated 23 | $(FIXUP) -i $^ -o $@ -c $(VMCNT) -t $(HOST) -p $(PORT) -w $(WORKDIR) 24 | 25 | generated/%.cfg.1: %.cfg |generated 26 | $(FIXUP) -i $^ -o $@ -c $(VMCNT) -t $(HOST) -p $(PORT) -w $(WORKDIR) -r 1 27 | 28 | generated/%.cfg.2: %.cfg |generated 29 | $(FIXUP) -i $^ -o $@ -c $(VMCNT) -t $(HOST) -p $(PORT) -w $(WORKDIR) -r 2 30 | 31 | generated/%.cfg.3: %.cfg |generated 32 | $(FIXUP) -i $^ -o $@ -c $(VMCNT) -t $(HOST) -p $(PORT) -w $(WORKDIR) -r 3 33 | 34 | generated: 35 | mkdir -p generated 36 | 37 | clean: 38 | rm -rf generated 39 | -------------------------------------------------------------------------------- /configs/syzkaller/agamotto-usb.ar5523.cfg: -------------------------------------------------------------------------------- 1 | { 2 | "name": "agamotto-usb.ar5523", 3 | "target": "linux/amd64", 4 | "http": "$HOST:$PORT", 5 | "workdir": "$AGPATH/$WORKDIR/agamotto-usb.ar5523/$RUNID", 6 | "kernel_obj": "$AGPATH/build/guest/linux/image/usb/", 7 | "image": "$AGPATH/scripts/stretch.img", 8 | "sshkey": "$AGPATH/scripts/stretch.id_rsa", 9 | "syzkaller": "$GOPATH/src/github.com/google/syzkaller", 10 | "procs": 1, 11 | "sandbox": "none", 12 | "cover": true, 13 | "vcover": true, 14 | "reproduce": false, 15 | "seed": 1, 16 | "type": "qemu", 17 | "enable_syscalls": [ 18 | "syz_usb_connect$ar5523", 19 | "syz_usb_control_io$ar5523", 20 | "syz_usb_ep_read$ar5523", 21 | "syz_usb_ep_write$ar5523", 22 | "syz_usb_disconnect" 23 | ], 24 | "syz_fuzzer": "$GOPATH/src/github.com/google/syzkaller/bin/linux_amd64/syz-fuzzer", 25 | "vm": { 26 | "count": $VMCNT, 27 | "cpu": 1, 28 | "mem": 512, 29 | "agent": $AGENTID, 30 | "libagamotto": "$AGPATH/build/libagamotto/libagamotto.so", 31 | "kernel": "$AGPATH/build/guest/linux/image/usb/arch/x86/boot/bzImage", 32 | "chkpt_pool_size": 12288 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /configs/syzkaller/agamotto-usb.btusb.cfg: -------------------------------------------------------------------------------- 1 | { 2 | "name": "agamotto-usb.btusb", 3 | "target": "linux/amd64", 4 | "http": "$HOST:$PORT", 5 | "workdir": "$AGPATH/$WORKDIR/agamotto-usb.btusb/$RUNID", 6 | "kernel_obj": "$AGPATH/build/guest/linux/image/usb/", 7 | "image": "$AGPATH/scripts/stretch.img", 8 | "sshkey": "$AGPATH/scripts/stretch.id_rsa", 9 | "syzkaller": "$GOPATH/src/github.com/google/syzkaller", 10 | "procs": 1, 11 | "sandbox": "none", 12 | "cover": true, 13 | "vcover": true, 14 | "reproduce": false, 15 | "seed": 1, 16 | "type": "qemu", 17 | "enable_syscalls": [ 18 | "syz_usb_connect$btusb", 19 | "syz_usb_control_io$btusb", 20 | "syz_usb_ep_read$btusb", 21 | "syz_usb_ep_write$btusb", 22 | "syz_usb_disconnect" 23 | ], 24 | "syz_fuzzer": "$GOPATH/src/github.com/google/syzkaller/bin/linux_amd64/syz-fuzzer", 25 | "vm": { 26 | "count": $VMCNT, 27 | "cpu": 1, 28 | "mem": 512, 29 | "agent": $AGENTID, 30 | "libagamotto": "$AGPATH/build/libagamotto/libagamotto.so", 31 | "kernel": "$AGPATH/build/guest/linux/image/usb/arch/x86/boot/bzImage", 32 | "chkpt_pool_size": 12288 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /configs/syzkaller/agamotto-usb.go7007.cfg: -------------------------------------------------------------------------------- 1 | { 2 | "name": "agamotto-usb.go7007", 3 | "target": "linux/amd64", 4 | "http": "$HOST:$PORT", 5 | "workdir": "$AGPATH/$WORKDIR/agamotto-usb.go7007/$RUNID", 6 | "kernel_obj": "$AGPATH/build/guest/linux/image/usb/", 7 | "image": "$AGPATH/scripts/stretch.img", 8 | "sshkey": "$AGPATH/scripts/stretch.id_rsa", 9 | "syzkaller": "$GOPATH/src/github.com/google/syzkaller", 10 | "procs": 1, 11 | "sandbox": "none", 12 | "cover": true, 13 | "vcover": true, 14 | "reproduce": false, 15 | "seed": 1, 16 | "type": "qemu", 17 | "enable_syscalls": [ 18 | "syz_usb_connect$go7007", 19 | "syz_usb_control_io$go7007", 20 | "syz_usb_ep_read$go7007", 21 | "syz_usb_ep_write$go7007", 22 | "syz_usb_disconnect" 23 | ], 24 | "syz_fuzzer": "$GOPATH/src/github.com/google/syzkaller/bin/linux_amd64/syz-fuzzer", 25 | "vm": { 26 | "count": $VMCNT, 27 | "cpu": 1, 28 | "mem": 512, 29 | "agent": $AGENTID, 30 | "libagamotto": "$AGPATH/build/libagamotto/libagamotto.so", 31 | "kernel": "$AGPATH/build/guest/linux/image/usb/arch/x86/boot/bzImage", 32 | "chkpt_pool_size": 12288 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /configs/syzkaller/agamotto-usb.mwifiex.cfg: -------------------------------------------------------------------------------- 1 | { 2 | "name": "agamotto-usb.mwifiex", 3 | "target": "linux/amd64", 4 | "http": "$HOST:$PORT", 5 | "workdir": "$AGPATH/$WORKDIR/agamotto-usb.mwifiex/$RUNID", 6 | "kernel_obj": "$AGPATH/build/guest/linux/image/usb/", 7 | "image": "$AGPATH/scripts/stretch.img", 8 | "sshkey": "$AGPATH/scripts/stretch.id_rsa", 9 | "syzkaller": "$GOPATH/src/github.com/google/syzkaller", 10 | "procs": 1, 11 | "sandbox": "none", 12 | "cover": true, 13 | "vcover": true, 14 | "reproduce": false, 15 | "seed": 1, 16 | "type": "qemu", 17 | "enable_syscalls": [ 18 | "syz_usb_connect$mwifiex_8766", 19 | "syz_usb_control_io$mwifiex_8766", 20 | "syz_usb_ep_read$mwifiex_8766", 21 | "syz_usb_ep_write$mwifiex_8766", 22 | "syz_usb_disconnect" 23 | ], 24 | "syz_fuzzer": "$GOPATH/src/github.com/google/syzkaller/bin/linux_amd64/syz-fuzzer", 25 | "vm": { 26 | "count": $VMCNT, 27 | "cpu": 1, 28 | "mem": 512, 29 | "agent": $AGENTID, 30 | "libagamotto": "$AGPATH/build/libagamotto/libagamotto.so", 31 | "kernel": "$AGPATH/build/guest/linux/image/usb/arch/x86/boot/bzImage", 32 | "chkpt_pool_size": 12288 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /configs/syzkaller/agamotto-usb.pn533.cfg: -------------------------------------------------------------------------------- 1 | { 2 | "name": "agamotto-usb.pn533", 3 | "target": "linux/amd64", 4 | "http": "$HOST:$PORT", 5 | "workdir": "$AGPATH/$WORKDIR/agamotto-usb.pn533/$RUNID", 6 | "kernel_obj": "$AGPATH/build/guest/linux/image/usb/", 7 | "image": "$AGPATH/scripts/stretch.img", 8 | "sshkey": "$AGPATH/scripts/stretch.id_rsa", 9 | "syzkaller": "$GOPATH/src/github.com/google/syzkaller", 10 | "procs": 1, 11 | "sandbox": "none", 12 | "cover": true, 13 | "vcover": true, 14 | "reproduce": false, 15 | "seed": 1, 16 | "type": "qemu", 17 | "enable_syscalls": [ 18 | "syz_usb_connect$pn533", 19 | "syz_usb_control_io$pn533", 20 | "syz_usb_ep_read$pn533", 21 | "syz_usb_ep_write$pn533", 22 | "syz_usb_disconnect" 23 | ], 24 | "syz_fuzzer": "$GOPATH/src/github.com/google/syzkaller/bin/linux_amd64/syz-fuzzer", 25 | "vm": { 26 | "count": $VMCNT, 27 | "cpu": 1, 28 | "mem": 512, 29 | "agent": $AGENTID, 30 | "libagamotto": "$AGPATH/build/libagamotto/libagamotto.so", 31 | "kernel": "$AGPATH/build/guest/linux/image/usb/arch/x86/boot/bzImage", 32 | "chkpt_pool_size": 12288 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /configs/syzkaller/agamotto-usb.rsi.cfg: -------------------------------------------------------------------------------- 1 | { 2 | "name": "snapshot-usb.rsi", 3 | "target": "linux/amd64", 4 | "http": "$HOST:$PORT", 5 | "workdir": "$AGPATH/$WORKDIR/snapshot-usb.rsi/$RUNID", 6 | "kernel_obj": "$AGPATH/build/guest/linux/image/usb/", 7 | "image": "$AGPATH/scripts/stretch.img", 8 | "sshkey": "$AGPATH/scripts/stretch.id_rsa", 9 | "syzkaller": "$GOPATH/src/github.com/google/syzkaller", 10 | "procs": 1, 11 | "sandbox": "none", 12 | "cover": true, 13 | "vcover": true, 14 | "rootchkptonly": true, 15 | "reproduce": false, 16 | "seed": 1, 17 | "type": "qemu", 18 | "enable_syscalls": [ 19 | "syz_usb_connect$rsi_9113", 20 | "syz_usb_control_io$rsi_9113", 21 | "syz_usb_ep_read$rsi", 22 | "syz_usb_ep_write$rsi", 23 | "syz_usb_disconnect" 24 | ], 25 | "syz_fuzzer": "$GOPATH/src/github.com/google/syzkaller/bin/linux_amd64/syz-fuzzer", 26 | "vm": { 27 | "count": $VMCNT, 28 | "cpu": 1, 29 | "mem": 512, 30 | "agent": $AGENTID, 31 | "libagamotto": "$AGPATH/build/libagamotto/libagamotto.so", 32 | "kernel": "$AGPATH/build/guest/linux/image/usb/arch/x86/boot/bzImage", 33 | "chkpt_pool_size": 12288 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /configs/syzkaller/agamotto-usb.si470x.cfg: -------------------------------------------------------------------------------- 1 | { 2 | "name": "agamotto-usb.si470x", 3 | "target": "linux/amd64", 4 | "http": "$HOST:$PORT", 5 | "workdir": "$AGPATH/$WORKDIR/agamotto-usb.si470x/$RUNID", 6 | "kernel_obj": "$AGPATH/build/guest/linux/image/usb/", 7 | "image": "$AGPATH/scripts/stretch.img", 8 | "sshkey": "$AGPATH/scripts/stretch.id_rsa", 9 | "syzkaller": "$GOPATH/src/github.com/google/syzkaller", 10 | "procs": 1, 11 | "sandbox": "none", 12 | "cover": true, 13 | "vcover": true, 14 | "reproduce": false, 15 | "seed": 1, 16 | "type": "qemu", 17 | "enable_syscalls": [ 18 | "syz_usb_connect$si470x", 19 | "syz_usb_control_io$si470x", 20 | "syz_usb_ep_read$si470x", 21 | "syz_usb_ep_write$si470x", 22 | "syz_usb_disconnect" 23 | ], 24 | "syz_fuzzer": "$GOPATH/src/github.com/google/syzkaller/bin/linux_amd64/syz-fuzzer", 25 | "vm": { 26 | "count": $VMCNT, 27 | "cpu": 1, 28 | "mem": 512, 29 | "agent": $AGENTID, 30 | "libagamotto": "$AGPATH/build/libagamotto/libagamotto.so", 31 | "kernel": "$AGPATH/build/guest/linux/image/usb/arch/x86/boot/bzImage", 32 | "chkpt_pool_size": 12288 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /configs/syzkaller/agamotto-usb.usx2y.cfg: -------------------------------------------------------------------------------- 1 | { 2 | "name": "agamotto-usb.usx2y", 3 | "target": "linux/amd64", 4 | "http": "$HOST:$PORT", 5 | "workdir": "$AGPATH/$WORKDIR/agamotto-usb.usx2y/$RUNID", 6 | "kernel_obj": "$AGPATH/build/guest/linux/image/usb/", 7 | "image": "$AGPATH/scripts/stretch.img", 8 | "sshkey": "$AGPATH/scripts/stretch.id_rsa", 9 | "syzkaller": "$GOPATH/src/github.com/google/syzkaller", 10 | "procs": 1, 11 | "sandbox": "none", 12 | "cover": true, 13 | "vcover": true, 14 | "reproduce": false, 15 | "seed": 1, 16 | "type": "qemu", 17 | "enable_syscalls": [ 18 | "syz_usb_connect$usx2y", 19 | "syz_usb_control_io$usx2y", 20 | "syz_usb_ep_read$usx2y", 21 | "syz_usb_ep_write$usx2y", 22 | "syz_usb_disconnect" 23 | ], 24 | "syz_fuzzer": "$GOPATH/src/github.com/google/syzkaller/bin/linux_amd64/syz-fuzzer", 25 | "vm": { 26 | "count": $VMCNT, 27 | "cpu": 1, 28 | "mem": 512, 29 | "agent": $AGENTID, 30 | "libagamotto": "$AGPATH/build/libagamotto/libagamotto.so", 31 | "kernel": "$AGPATH/build/guest/linux/image/usb/arch/x86/boot/bzImage", 32 | "chkpt_pool_size": 12288 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /configs/syzkaller/baseline-usb.ar5523.cfg: -------------------------------------------------------------------------------- 1 | { 2 | "name": "baseline-usb.ar5523", 3 | "target": "linux/amd64", 4 | "http": "$HOST:$PORT", 5 | "workdir": "$AGPATH/$WORKDIR/baseline-usb.ar5523/$RUNID", 6 | "kernel_obj": "$AGPATH/build/guest/linux/image/usb/", 7 | "image": "$AGPATH/scripts/stretch.img", 8 | "sshkey": "$AGPATH/scripts/stretch.id_rsa", 9 | "syzkaller": "$GOPATH/src/github.com/google/syzkaller", 10 | "procs": 1, 11 | "sandbox": "none", 12 | "cover": true, 13 | "reproduce": false, 14 | "seed": 1, 15 | "type": "qemu", 16 | "enable_syscalls": [ 17 | "syz_usb_connect$ar5523", 18 | "syz_usb_control_io$ar5523", 19 | "syz_usb_ep_read$ar5523", 20 | "syz_usb_ep_write$ar5523", 21 | "syz_usb_disconnect" 22 | ], 23 | "vm": { 24 | "count": $VMCNT, 25 | "cpu": 1, 26 | "mem": 512, 27 | "kernel": "$AGPATH/build/guest/linux/image/usb/arch/x86/boot/bzImage" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /configs/syzkaller/baseline-usb.btusb.cfg: -------------------------------------------------------------------------------- 1 | { 2 | "name": "baseline-usb.btusb", 3 | "target": "linux/amd64", 4 | "http": "$HOST:$PORT", 5 | "workdir": "$AGPATH/$WORKDIR/baseline-usb.btusb/$RUNID", 6 | "kernel_obj": "$AGPATH/build/guest/linux/image/usb/", 7 | "image": "$AGPATH/scripts/stretch.img", 8 | "sshkey": "$AGPATH/scripts/stretch.id_rsa", 9 | "syzkaller": "$GOPATH/src/github.com/google/syzkaller", 10 | "procs": 1, 11 | "sandbox": "none", 12 | "cover": true, 13 | "reproduce": false, 14 | "seed": 1, 15 | "type": "qemu", 16 | "enable_syscalls": [ 17 | "syz_usb_connect$btusb", 18 | "syz_usb_control_io$btusb", 19 | "syz_usb_ep_read$btusb", 20 | "syz_usb_ep_write$btusb", 21 | "syz_usb_disconnect" 22 | ], 23 | "vm": { 24 | "count": $VMCNT, 25 | "cpu": 1, 26 | "mem": 512, 27 | "kernel": "$AGPATH/build/guest/linux/image/usb/arch/x86/boot/bzImage" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /configs/syzkaller/baseline-usb.go7007.cfg: -------------------------------------------------------------------------------- 1 | { 2 | "name": "baseline-usb.go7007", 3 | "target": "linux/amd64", 4 | "http": "$HOST:$PORT", 5 | "workdir": "$AGPATH/$WORKDIR/baseline-usb.go7007/$RUNID", 6 | "kernel_obj": "$AGPATH/build/guest/linux/image/usb/", 7 | "image": "$AGPATH/scripts/stretch.img", 8 | "sshkey": "$AGPATH/scripts/stretch.id_rsa", 9 | "syzkaller": "$GOPATH/src/github.com/google/syzkaller", 10 | "procs": 1, 11 | "sandbox": "none", 12 | "cover": true, 13 | "reproduce": false, 14 | "seed": 1, 15 | "type": "qemu", 16 | "enable_syscalls": [ 17 | "syz_usb_connect$go7007", 18 | "syz_usb_control_io$go7007", 19 | "syz_usb_ep_read$go7007", 20 | "syz_usb_ep_write$go7007", 21 | "syz_usb_disconnect" 22 | ], 23 | "vm": { 24 | "count": $VMCNT, 25 | "cpu": 1, 26 | "mem": 512, 27 | "kernel": "$AGPATH/build/guest/linux/image/usb/arch/x86/boot/bzImage" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /configs/syzkaller/baseline-usb.mwifiex.cfg: -------------------------------------------------------------------------------- 1 | { 2 | "name": "baseline-usb.mwifiex", 3 | "target": "linux/amd64", 4 | "http": "$HOST:$PORT", 5 | "workdir": "$AGPATH/$WORKDIR/baseline-usb.mwifiex/$RUNID", 6 | "kernel_obj": "$AGPATH/build/guest/linux/image/usb/", 7 | "image": "$AGPATH/scripts/stretch.img", 8 | "sshkey": "$AGPATH/scripts/stretch.id_rsa", 9 | "syzkaller": "$GOPATH/src/github.com/google/syzkaller", 10 | "procs": 1, 11 | "sandbox": "none", 12 | "cover": true, 13 | "reproduce": false, 14 | "seed": 1, 15 | "type": "qemu", 16 | "enable_syscalls": [ 17 | "syz_usb_connect$mwifiex_8766", 18 | "syz_usb_control_io$mwifiex_8766", 19 | "syz_usb_ep_read$mwifiex_8766", 20 | "syz_usb_ep_write$mwifiex_8766", 21 | "syz_usb_disconnect" 22 | ], 23 | "vm": { 24 | "count": $VMCNT, 25 | "cpu": 1, 26 | "mem": 512, 27 | "kernel": "$AGPATH/build/guest/linux/image/usb/arch/x86/boot/bzImage" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /configs/syzkaller/baseline-usb.pn533.cfg: -------------------------------------------------------------------------------- 1 | { 2 | "name": "baseline-usb.pn533", 3 | "target": "linux/amd64", 4 | "http": "$HOST:$PORT", 5 | "workdir": "$AGPATH/$WORKDIR/baseline-usb.pn533/$RUNID", 6 | "kernel_obj": "$AGPATH/build/guest/linux/image/usb/", 7 | "image": "$AGPATH/scripts/stretch.img", 8 | "sshkey": "$AGPATH/scripts/stretch.id_rsa", 9 | "syzkaller": "$GOPATH/src/github.com/google/syzkaller", 10 | "procs": 1, 11 | "sandbox": "none", 12 | "cover": true, 13 | "reproduce": false, 14 | "seed": 1, 15 | "type": "qemu", 16 | "enable_syscalls": [ 17 | "syz_usb_connect$pn533", 18 | "syz_usb_control_io$pn533", 19 | "syz_usb_ep_read$pn533", 20 | "syz_usb_ep_write$pn533", 21 | "syz_usb_disconnect" 22 | ], 23 | "vm": { 24 | "count": $VMCNT, 25 | "cpu": 1, 26 | "mem": 512, 27 | "kernel": "$AGPATH/build/guest/linux/image/usb/arch/x86/boot/bzImage" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /configs/syzkaller/baseline-usb.rsi.cfg: -------------------------------------------------------------------------------- 1 | { 2 | "name": "baseline-usb.rsi", 3 | "target": "linux/amd64", 4 | "http": "$HOST:$PORT", 5 | "workdir": "$AGPATH/$WORKDIR/baseline-usb.rsi/$RUNID", 6 | "kernel_obj": "$AGPATH/build/guest/linux/image/usb/", 7 | "image": "$AGPATH/scripts/stretch.img", 8 | "sshkey": "$AGPATH/scripts/stretch.id_rsa", 9 | "syzkaller": "$GOPATH/src/github.com/google/syzkaller", 10 | "procs": 1, 11 | "sandbox": "none", 12 | "cover": true, 13 | "reproduce": false, 14 | "seed": 1, 15 | "type": "qemu", 16 | "enable_syscalls": [ 17 | "syz_usb_connect$rsi_9113", 18 | "syz_usb_control_io$rsi_9113", 19 | "syz_usb_ep_read$rsi", 20 | "syz_usb_ep_write$rsi", 21 | "syz_usb_disconnect" 22 | ], 23 | "vm": { 24 | "count": $VMCNT, 25 | "cpu": 1, 26 | "mem": 512, 27 | "kernel": "$AGPATH/build/guest/linux/image/usb/arch/x86/boot/bzImage" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /configs/syzkaller/baseline-usb.si470x.cfg: -------------------------------------------------------------------------------- 1 | { 2 | "name": "baseline-usb.si470x", 3 | "target": "linux/amd64", 4 | "http": "$HOST:$PORT", 5 | "workdir": "$AGPATH/$WORKDIR/baseline-usb.si470x/$RUNID", 6 | "kernel_obj": "$AGPATH/build/guest/linux/image/usb/", 7 | "image": "$AGPATH/scripts/stretch.img", 8 | "sshkey": "$AGPATH/scripts/stretch.id_rsa", 9 | "syzkaller": "$GOPATH/src/github.com/google/syzkaller", 10 | "procs": 1, 11 | "sandbox": "none", 12 | "cover": true, 13 | "reproduce": false, 14 | "seed": 1, 15 | "type": "qemu", 16 | "enable_syscalls": [ 17 | "syz_usb_connect$si470x", 18 | "syz_usb_control_io$si470x", 19 | "syz_usb_ep_read$si470x", 20 | "syz_usb_ep_write$si470x", 21 | "syz_usb_disconnect" 22 | ], 23 | "vm": { 24 | "count": $VMCNT, 25 | "cpu": 1, 26 | "mem": 512, 27 | "kernel": "$AGPATH/build/guest/linux/image/usb/arch/x86/boot/bzImage" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /configs/syzkaller/baseline-usb.usx2y.cfg: -------------------------------------------------------------------------------- 1 | { 2 | "name": "baseline-usb.usx2y", 3 | "target": "linux/amd64", 4 | "http": "$HOST:$PORT", 5 | "workdir": "$AGPATH/$WORKDIR/baseline-usb.usx2y/$RUNID", 6 | "kernel_obj": "$AGPATH/build/guest/linux/image/usb/", 7 | "image": "$AGPATH/scripts/stretch.img", 8 | "sshkey": "$AGPATH/scripts/stretch.id_rsa", 9 | "syzkaller": "$GOPATH/src/github.com/google/syzkaller", 10 | "procs": 1, 11 | "sandbox": "none", 12 | "cover": true, 13 | "reproduce": false, 14 | "seed": 1, 15 | "type": "qemu", 16 | "enable_syscalls": [ 17 | "syz_usb_connect$usx2y", 18 | "syz_usb_control_io$usx2y", 19 | "syz_usb_ep_read$usx2y", 20 | "syz_usb_ep_write$usx2y", 21 | "syz_usb_disconnect" 22 | ], 23 | "vm": { 24 | "count": $VMCNT, 25 | "cpu": 1, 26 | "mem": 512, 27 | "kernel": "$AGPATH/build/guest/linux/image/usb/arch/x86/boot/bzImage" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /configs/syzkaller/snapshot-usb.ar5523.cfg: -------------------------------------------------------------------------------- 1 | { 2 | "name": "snapshot-usb.ar5523", 3 | "target": "linux/amd64", 4 | "http": "$HOST:$PORT", 5 | "workdir": "$AGPATH/$WORKDIR/snapshot-usb.ar5523/$RUNID", 6 | "kernel_obj": "$AGPATH/build/guest/linux/image/usb/", 7 | "image": "$AGPATH/scripts/stretch.img", 8 | "sshkey": "$AGPATH/scripts/stretch.id_rsa", 9 | "syzkaller": "$GOPATH/src/github.com/google/syzkaller", 10 | "procs": 1, 11 | "sandbox": "none", 12 | "cover": true, 13 | "vcover": true, 14 | "rootchkptonly": true, 15 | "reproduce": false, 16 | "seed": 1, 17 | "type": "qemu", 18 | "enable_syscalls": [ 19 | "syz_usb_connect$ar5523", 20 | "syz_usb_control_io$ar5523", 21 | "syz_usb_ep_read$ar5523", 22 | "syz_usb_ep_write$ar5523", 23 | "syz_usb_disconnect" 24 | ], 25 | "syz_fuzzer": "$GOPATH/src/github.com/google/syzkaller/bin/linux_amd64/syz-fuzzer", 26 | "vm": { 27 | "count": $VMCNT, 28 | "cpu": 1, 29 | "mem": 512, 30 | "agent": $AGENTID, 31 | "libagamotto": "$AGPATH/build/libagamotto/libagamotto.so", 32 | "kernel": "$AGPATH/build/guest/linux/image/usb/arch/x86/boot/bzImage", 33 | "chkpt_pool_size": 12288 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /configs/syzkaller/snapshot-usb.btusb.cfg: -------------------------------------------------------------------------------- 1 | { 2 | "name": "snapshot-usb.btusb", 3 | "target": "linux/amd64", 4 | "http": "$HOST:$PORT", 5 | "workdir": "$AGPATH/$WORKDIR/snapshot-usb.btusb/$RUNID", 6 | "kernel_obj": "$AGPATH/build/guest/linux/image/usb/", 7 | "image": "$AGPATH/scripts/stretch.img", 8 | "sshkey": "$AGPATH/scripts/stretch.id_rsa", 9 | "syzkaller": "$GOPATH/src/github.com/google/syzkaller", 10 | "procs": 1, 11 | "sandbox": "none", 12 | "cover": true, 13 | "vcover": true, 14 | "rootchkptonly": true, 15 | "reproduce": false, 16 | "seed": 1, 17 | "type": "qemu", 18 | "enable_syscalls": [ 19 | "syz_usb_connect$btusb", 20 | "syz_usb_control_io$btusb", 21 | "syz_usb_ep_read$btusb", 22 | "syz_usb_ep_write$btusb", 23 | "syz_usb_disconnect" 24 | ], 25 | "syz_fuzzer": "$GOPATH/src/github.com/google/syzkaller/bin/linux_amd64/syz-fuzzer", 26 | "vm": { 27 | "count": $VMCNT, 28 | "cpu": 1, 29 | "mem": 512, 30 | "agent": $AGENTID, 31 | "libagamotto": "$AGPATH/build/libagamotto/libagamotto.so", 32 | "kernel": "$AGPATH/build/guest/linux/image/usb/arch/x86/boot/bzImage", 33 | "chkpt_pool_size": 12288 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /configs/syzkaller/snapshot-usb.go7007.cfg: -------------------------------------------------------------------------------- 1 | { 2 | "name": "snapshot-usb.go7007", 3 | "target": "linux/amd64", 4 | "http": "$HOST:$PORT", 5 | "workdir": "$AGPATH/$WORKDIR/snapshot-usb.go7007/$RUNID", 6 | "kernel_obj": "$AGPATH/build/guest/linux/image/usb/", 7 | "image": "$AGPATH/scripts/stretch.img", 8 | "sshkey": "$AGPATH/scripts/stretch.id_rsa", 9 | "syzkaller": "$GOPATH/src/github.com/google/syzkaller", 10 | "procs": 1, 11 | "sandbox": "none", 12 | "cover": true, 13 | "vcover": true, 14 | "rootchkptonly": true, 15 | "reproduce": false, 16 | "seed": 1, 17 | "type": "qemu", 18 | "enable_syscalls": [ 19 | "syz_usb_connect$go7007", 20 | "syz_usb_control_io$go7007", 21 | "syz_usb_ep_read$go7007", 22 | "syz_usb_ep_write$go7007", 23 | "syz_usb_disconnect" 24 | ], 25 | "syz_fuzzer": "$GOPATH/src/github.com/google/syzkaller/bin/linux_amd64/syz-fuzzer", 26 | "vm": { 27 | "count": $VMCNT, 28 | "cpu": 1, 29 | "mem": 512, 30 | "agent": $AGENTID, 31 | "libagamotto": "$AGPATH/build/libagamotto/libagamotto.so", 32 | "kernel": "$AGPATH/build/guest/linux/image/usb/arch/x86/boot/bzImage", 33 | "chkpt_pool_size": 12288 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /configs/syzkaller/snapshot-usb.mwifiex.cfg: -------------------------------------------------------------------------------- 1 | { 2 | "name": "snapshot-usb.mwifiex", 3 | "target": "linux/amd64", 4 | "http": "$HOST:$PORT", 5 | "workdir": "$AGPATH/$WORKDIR/snapshot-usb.mwifiex/$RUNID", 6 | "kernel_obj": "$AGPATH/build/guest/linux/image/usb/", 7 | "image": "$AGPATH/scripts/stretch.img", 8 | "sshkey": "$AGPATH/scripts/stretch.id_rsa", 9 | "syzkaller": "$GOPATH/src/github.com/google/syzkaller", 10 | "procs": 1, 11 | "sandbox": "none", 12 | "cover": true, 13 | "vcover": true, 14 | "rootchkptonly": true, 15 | "reproduce": false, 16 | "seed": 1, 17 | "type": "qemu", 18 | "enable_syscalls": [ 19 | "syz_usb_connect$mwifiex_8766", 20 | "syz_usb_control_io$mwifiex_8766", 21 | "syz_usb_ep_read$mwifiex_8766", 22 | "syz_usb_ep_write$mwifiex_8766", 23 | "syz_usb_disconnect" 24 | ], 25 | "syz_fuzzer": "$GOPATH/src/github.com/google/syzkaller/bin/linux_amd64/syz-fuzzer", 26 | "vm": { 27 | "count": $VMCNT, 28 | "cpu": 1, 29 | "mem": 512, 30 | "agent": $AGENTID, 31 | "libagamotto": "$AGPATH/build/libagamotto/libagamotto.so", 32 | "kernel": "$AGPATH/build/guest/linux/image/usb/arch/x86/boot/bzImage", 33 | "chkpt_pool_size": 12288 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /configs/syzkaller/snapshot-usb.pn533.cfg: -------------------------------------------------------------------------------- 1 | { 2 | "name": "snapshot-usb.pn533", 3 | "target": "linux/amd64", 4 | "http": "$HOST:$PORT", 5 | "workdir": "$AGPATH/$WORKDIR/snapshot-usb.pn533/$RUNID", 6 | "kernel_obj": "$AGPATH/build/guest/linux/image/usb/", 7 | "image": "$AGPATH/scripts/stretch.img", 8 | "sshkey": "$AGPATH/scripts/stretch.id_rsa", 9 | "syzkaller": "$GOPATH/src/github.com/google/syzkaller", 10 | "procs": 1, 11 | "sandbox": "none", 12 | "cover": true, 13 | "vcover": true, 14 | "rootchkptonly": true, 15 | "reproduce": false, 16 | "seed": 1, 17 | "type": "qemu", 18 | "enable_syscalls": [ 19 | "syz_usb_connect$pn533", 20 | "syz_usb_control_io$pn533", 21 | "syz_usb_ep_read$pn533", 22 | "syz_usb_ep_write$pn533", 23 | "syz_usb_disconnect" 24 | ], 25 | "syz_fuzzer": "$GOPATH/src/github.com/google/syzkaller/bin/linux_amd64/syz-fuzzer", 26 | "vm": { 27 | "count": $VMCNT, 28 | "cpu": 1, 29 | "mem": 512, 30 | "agent": $AGENTID, 31 | "libagamotto": "$AGPATH/build/libagamotto/libagamotto.so", 32 | "kernel": "$AGPATH/build/guest/linux/image/usb/arch/x86/boot/bzImage", 33 | "chkpt_pool_size": 12288 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /configs/syzkaller/snapshot-usb.rsi.cfg: -------------------------------------------------------------------------------- 1 | { 2 | "name": "snapshot-usb.rsi", 3 | "target": "linux/amd64", 4 | "http": "$HOST:$PORT", 5 | "workdir": "$AGPATH/$WORKDIR/snapshot-usb.rsi/$RUNID", 6 | "kernel_obj": "$AGPATH/build/guest/linux/image/usb/", 7 | "image": "$AGPATH/scripts/stretch.img", 8 | "sshkey": "$AGPATH/scripts/stretch.id_rsa", 9 | "syzkaller": "$GOPATH/src/github.com/google/syzkaller", 10 | "procs": 1, 11 | "sandbox": "none", 12 | "cover": true, 13 | "vcover": true, 14 | "rootchkptonly": true, 15 | "reproduce": false, 16 | "seed": 1, 17 | "type": "qemu", 18 | "enable_syscalls": [ 19 | "syz_usb_connect$rsi_9113", 20 | "syz_usb_control_io$rsi_9113", 21 | "syz_usb_ep_read$rsi", 22 | "syz_usb_ep_write$rsi", 23 | "syz_usb_disconnect" 24 | ], 25 | "syz_fuzzer": "$GOPATH/src/github.com/google/syzkaller/bin/linux_amd64/syz-fuzzer", 26 | "vm": { 27 | "count": $VMCNT, 28 | "cpu": 1, 29 | "mem": 512, 30 | "agent": $AGENTID, 31 | "libagamotto": "$AGPATH/build/libagamotto/libagamotto.so", 32 | "kernel": "$AGPATH/build/guest/linux/image/usb/arch/x86/boot/bzImage", 33 | "chkpt_pool_size": 12288 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /configs/syzkaller/snapshot-usb.si470x.cfg: -------------------------------------------------------------------------------- 1 | { 2 | "name": "snapshot-usb.si470x", 3 | "target": "linux/amd64", 4 | "http": "$HOST:$PORT", 5 | "workdir": "$AGPATH/$WORKDIR/snapshot-usb.si470x/$RUNID", 6 | "kernel_obj": "$AGPATH/build/guest/linux/image/usb/", 7 | "image": "$AGPATH/scripts/stretch.img", 8 | "sshkey": "$AGPATH/scripts/stretch.id_rsa", 9 | "syzkaller": "$GOPATH/src/github.com/google/syzkaller", 10 | "procs": 1, 11 | "sandbox": "none", 12 | "cover": true, 13 | "vcover": true, 14 | "rootchkptonly": true, 15 | "reproduce": false, 16 | "seed": 1, 17 | "type": "qemu", 18 | "enable_syscalls": [ 19 | "syz_usb_connect$si470x", 20 | "syz_usb_control_io$si470x", 21 | "syz_usb_ep_read$si470x", 22 | "syz_usb_ep_write$si470x", 23 | "syz_usb_disconnect" 24 | ], 25 | "syz_fuzzer": "$GOPATH/src/github.com/google/syzkaller/bin/linux_amd64/syz-fuzzer", 26 | "vm": { 27 | "count": $VMCNT, 28 | "cpu": 1, 29 | "mem": 512, 30 | "agent": $AGENTID, 31 | "libagamotto": "$AGPATH/build/libagamotto/libagamotto.so", 32 | "kernel": "$AGPATH/build/guest/linux/image/usb/arch/x86/boot/bzImage", 33 | "chkpt_pool_size": 12288 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /configs/syzkaller/snapshot-usb.usx2y.cfg: -------------------------------------------------------------------------------- 1 | { 2 | "name": "snapshot-usb.usx2y", 3 | "target": "linux/amd64", 4 | "http": "$HOST:$PORT", 5 | "workdir": "$AGPATH/$WORKDIR/snapshot-usb.usx2y/$RUNID", 6 | "kernel_obj": "$AGPATH/build/guest/linux/image/usb/", 7 | "image": "$AGPATH/scripts/stretch.img", 8 | "sshkey": "$AGPATH/scripts/stretch.id_rsa", 9 | "syzkaller": "$GOPATH/src/github.com/google/syzkaller", 10 | "procs": 1, 11 | "sandbox": "none", 12 | "cover": true, 13 | "vcover": true, 14 | "rootchkptonly": true, 15 | "reproduce": false, 16 | "seed": 1, 17 | "type": "qemu", 18 | "enable_syscalls": [ 19 | "syz_usb_connect$usx2y", 20 | "syz_usb_control_io$usx2y", 21 | "syz_usb_ep_read$usx2y", 22 | "syz_usb_ep_write$usx2y", 23 | "syz_usb_disconnect" 24 | ], 25 | "syz_fuzzer": "$GOPATH/src/github.com/google/syzkaller/bin/linux_amd64/syz-fuzzer", 26 | "vm": { 27 | "count": $VMCNT, 28 | "cpu": 1, 29 | "mem": 512, 30 | "agent": $AGENTID, 31 | "libagamotto": "$AGPATH/build/libagamotto/libagamotto.so", 32 | "kernel": "$AGPATH/build/guest/linux/image/usb/arch/x86/boot/bzImage", 33 | "chkpt_pool_size": 12288 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /guest/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_host_system_information(RESULT PROCESSOR_NAME QUERY PROCESSOR_NAME) 2 | 3 | if (PROCESSOR_NAME MATCHES ".*AMD.*") 4 | add_definitions(-DX86_64_AMD_FAMILY) 5 | endif() 6 | 7 | add_subdirectory(linux) 8 | -------------------------------------------------------------------------------- /guest/agamotto.h: -------------------------------------------------------------------------------- 1 | #ifndef _GUEST_AGAMOTTO_H 2 | #define _GUEST_AGAMOTTO_H 3 | 4 | #ifdef __MINGW64__ 5 | #ifndef uint64_t 6 | #define uint64_t UINT64 7 | #endif 8 | #ifndef int32_t 9 | #define int32_t INT32 10 | #endif 11 | #ifndef uint8_t 12 | #define uint8_t UINT8 13 | #endif 14 | #else 15 | #include 16 | #endif 17 | 18 | #include 19 | 20 | #define KVM_HC_AGAMOTTO 20 21 | 22 | #define HC_AGAMOTTO_GET_PROG 0 23 | #define HC_AGAMOTTO_END 1 24 | #define HC_AGAMOTTO_DEBUG 10 25 | #define HC_AGAMOTTO_NEXT 20 26 | #define SYZKALLER_HC_ROOT_CHKPT 5 27 | #define HC_AGAMOTTO_DEBUG_NEXT 13 28 | 29 | static uint64_t agamotto_kvm_hypercall(uint64_t a0) 30 | { 31 | uint64_t ret; 32 | uint64_t nr = KVM_HC_AGAMOTTO; 33 | 34 | asm("movq %0, %%rbx;" 35 | : 36 | : "r"(a0)); 37 | asm("movq %0, %%rax;" 38 | : 39 | : "r"(nr)); 40 | #ifdef X86_64_AMD_FAMILY 41 | asm("vmmcall; movq %% rax,%0" 42 | : "=r"(ret) 43 | :); 44 | #else 45 | asm("vmcall; movq %% rax,%0" 46 | : "=r"(ret) 47 | :); 48 | #endif 49 | return ret; 50 | } 51 | 52 | static uint64_t agamotto_kvm_hypercall2(uint64_t a0, uint64_t a1) 53 | { 54 | uint64_t ret; 55 | uint64_t nr = KVM_HC_AGAMOTTO; 56 | 57 | asm("movq %0, %%rcx;" 58 | : 59 | : "r"(a1)); 60 | asm("movq %0, %%rbx;" 61 | : 62 | : "r"(a0)); 63 | asm("movq %0, %%rax;" 64 | : 65 | : "r"(nr)); 66 | #ifdef X86_64_AMD_FAMILY 67 | asm("vmmcall; movq %% rax,%0" 68 | : "=r"(ret) 69 | :); 70 | #else 71 | asm("vmcall; movq %% rax,%0" 72 | : "=r"(ret) 73 | :); 74 | #endif 75 | return ret; 76 | } 77 | 78 | static uint64_t agamotto_kvm_hypercall3(uint64_t a0, uint64_t a1, uint64_t a2) 79 | { 80 | uint64_t ret; 81 | uint64_t nr = KVM_HC_AGAMOTTO; 82 | 83 | asm("movq %0, %%rsi;" 84 | : 85 | : "r"(a2)); 86 | asm("movq %0, %%rcx;" 87 | : 88 | : "r"(a1)); 89 | asm("movq %0, %%rbx;" 90 | : 91 | : "r"(a0)); 92 | asm("movq %0, %%rax;" 93 | : 94 | : "r"(nr)); 95 | #ifdef X86_64_AMD_FAMILY 96 | asm("vmmcall; movq %% rax,%0" 97 | : "=r"(ret) 98 | :); 99 | #else 100 | asm("vmcall; movq %% rax,%0" 101 | : "=r"(ret) 102 | :); 103 | #endif 104 | return ret; 105 | } 106 | 107 | static void agamotto_agent_exit_cb() 108 | { 109 | // TODO 110 | } 111 | 112 | #endif // _GUEST_AGAMOTTO_H 113 | -------------------------------------------------------------------------------- /guest/linux/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(progs) 2 | add_subdirectory(syz) 3 | add_subdirectory(agents) 4 | -------------------------------------------------------------------------------- /guest/linux/agents/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(agent-exit agent-exit.c) 2 | 3 | target_include_directories( 4 | agent-exit 5 | PUBLIC 6 | ${CMAKE_CURRENT_SOURCE_DIR}/../../ 7 | ) 8 | 9 | add_executable(agent-get-prog agent-get-prog.c) 10 | 11 | target_include_directories( 12 | agent-get-prog 13 | PUBLIC 14 | ${CMAKE_CURRENT_SOURCE_DIR}/../../ 15 | ) 16 | 17 | add_executable(agent-chkpt agent-chkpt.c) 18 | 19 | target_include_directories( 20 | agent-chkpt 21 | PUBLIC 22 | ${CMAKE_CURRENT_SOURCE_DIR}/../../ 23 | ) 24 | 25 | add_executable(agent-next agent-next.c) 26 | 27 | target_include_directories( 28 | agent-next 29 | PUBLIC 30 | ${CMAKE_CURRENT_SOURCE_DIR}/../../ 31 | ) 32 | 33 | 34 | -------------------------------------------------------------------------------- /guest/linux/agents/agent-chkpt.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char** argv) 5 | { 6 | uint64_t ret = 0; 7 | 8 | if (argc > 1) { 9 | ret = strtoul(argv[1], NULL, 16); 10 | } 11 | 12 | agamotto_kvm_hypercall2(HC_AGAMOTTO_DEBUG, SYZKALLER_HC_ROOT_CHKPT); 13 | 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /guest/linux/agents/agent-debug.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo $1 4 | 5 | cat /proc/modules 6 | 7 | for mod in $(cat /proc/modules | awk '{print $1}') 8 | do 9 | for sect_file in /sys/module/$mod/sections/.* 10 | do 11 | addr=$(cat $sect_file) 12 | sect=$(basename $sect_file) 13 | (echo $mod $sect $addr) | xargs 14 | done 15 | done 16 | 17 | if [ ! -z $NO_SHUTDOWN ]; then # for debugging 18 | exit 0 19 | fi 20 | 21 | echo shutting down... 22 | 23 | # Signal VMM to exit 24 | /root/agent-exit 0xdead0000 25 | -------------------------------------------------------------------------------- /guest/linux/agents/agent-dev-prog.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! ${skip_root_chkpt} ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! ${skip_modprobe} ; then 8 | modprobe ${module} 9 | # insmod /lib/modules/4.19.0${image}+/kernel/${module_relpath} 10 | fi 11 | 12 | /root/${prog} ${module} 13 | -------------------------------------------------------------------------------- /guest/linux/agents/agent-exit.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char** argv) 5 | { 6 | uint64_t ret = 0; 7 | 8 | if (argc > 1) { 9 | ret = strtoul(argv[1], NULL, 16); 10 | } 11 | 12 | agamotto_kvm_hypercall2(HC_AGAMOTTO_END, ret); 13 | 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /guest/linux/agents/agent-get-prog.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char** argv) 4 | { 5 | uint64_t ret = agamotto_kvm_hypercall(HC_AGAMOTTO_GET_PROG); 6 | 7 | printf("%lu\n", ret); 8 | 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /guest/linux/agents/agent-next.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(int argc, char** argv) 6 | { 7 | agamotto_kvm_hypercall2(HC_AGAMOTTO_DEBUG, HC_AGAMOTTO_DEBUG_NEXT); 8 | 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /guest/linux/agents/agent.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | id=$$(/root/agent-get-prog) 4 | 5 | progs=( 6 | ${AGENTS} 7 | ) 8 | 9 | sleep 5 10 | 11 | if [ $$id -lt $${#progs[@]} ]; then 12 | /root/$${progs[$$id]} 13 | else 14 | echo "Failed to find guest agent $$id" 15 | /root/agent-exit AGENT_START_FAILURE 16 | exit 1 17 | fi 18 | 19 | /root/agent-exit 20 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-aqc100-debug.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! true ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! false ; then 8 | modprobe atlantic 9 | # insmod /lib/modules/4.19.0aqtion+/kernel/drivers/net/ethernet/aquantia/atlantic/atlantic.ko 10 | fi 11 | 12 | /root/debug atlantic 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-aqc100-prog01.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! false ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! false ; then 8 | modprobe atlantic 9 | # insmod /lib/modules/4.19.0aqtion+/kernel/drivers/net/ethernet/aquantia/atlantic/atlantic.ko 10 | fi 11 | 12 | /root/prog01 atlantic 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-aqc100-prog02.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! false ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! false ; then 8 | modprobe atlantic 9 | # insmod /lib/modules/4.19.0aqtion+/kernel/drivers/net/ethernet/aquantia/atlantic/atlantic.ko 10 | fi 11 | 12 | /root/prog02 atlantic 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-aqc100-prog03.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! false ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! false ; then 8 | modprobe atlantic 9 | # insmod /lib/modules/4.19.0aqtion+/kernel/drivers/net/ethernet/aquantia/atlantic/atlantic.ko 10 | fi 11 | 12 | /root/prog03 atlantic 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-aqc100-prog04.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! false ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! false ; then 8 | modprobe atlantic 9 | # insmod /lib/modules/4.19.0aqtion+/kernel/drivers/net/ethernet/aquantia/atlantic/atlantic.ko 10 | fi 11 | 12 | /root/prog04 atlantic 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-aqc100-prog05.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! false ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! false ; then 8 | modprobe atlantic 9 | # insmod /lib/modules/4.19.0aqtion+/kernel/drivers/net/ethernet/aquantia/atlantic/atlantic.ko 10 | fi 11 | 12 | /root/prog05 atlantic 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-aqc100-prog80.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! true ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! true ; then 8 | modprobe atlantic 9 | # insmod /lib/modules/4.19.0aqtion+/kernel/drivers/net/ethernet/aquantia/atlantic/atlantic.ko 10 | fi 11 | 12 | /root/prog80 atlantic 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-aqc100-prog81.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! true ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! true ; then 8 | modprobe atlantic 9 | # insmod /lib/modules/4.19.0aqtion+/kernel/drivers/net/ethernet/aquantia/atlantic/atlantic.ko 10 | fi 11 | 12 | /root/prog81 atlantic 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-aqc100-prog96.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! false ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! false ; then 8 | modprobe atlantic 9 | # insmod /lib/modules/4.19.0aqtion+/kernel/drivers/net/ethernet/aquantia/atlantic/atlantic.ko 10 | fi 11 | 12 | /root/prog96 atlantic 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-aqc100-prog97.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! false ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! false ; then 8 | modprobe atlantic 9 | # insmod /lib/modules/4.19.0aqtion+/kernel/drivers/net/ethernet/aquantia/atlantic/atlantic.ko 10 | fi 11 | 12 | /root/prog97 atlantic 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-aqc100-prog98.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! true ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! false ; then 8 | modprobe atlantic 9 | # insmod /lib/modules/4.19.0aqtion+/kernel/drivers/net/ethernet/aquantia/atlantic/atlantic.ko 10 | fi 11 | 12 | /root/prog98 atlantic 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-aqc100-prog99.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! true ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! false ; then 8 | modprobe atlantic 9 | # insmod /lib/modules/4.19.0aqtion+/kernel/drivers/net/ethernet/aquantia/atlantic/atlantic.ko 10 | fi 11 | 12 | /root/prog99 atlantic 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-quark-debug.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! true ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! false ; then 8 | modprobe stmmac-pci 9 | # insmod /lib/modules/4.19.0stmmac+/kernel/drivers/net/ethernet/stmicro/stmmac/stmmac-pci.ko 10 | fi 11 | 12 | /root/debug stmmac-pci 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-quark-prog01.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! false ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! false ; then 8 | modprobe stmmac-pci 9 | # insmod /lib/modules/4.19.0stmmac+/kernel/drivers/net/ethernet/stmicro/stmmac/stmmac-pci.ko 10 | fi 11 | 12 | /root/prog01 stmmac-pci 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-quark-prog02.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! false ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! false ; then 8 | modprobe stmmac-pci 9 | # insmod /lib/modules/4.19.0stmmac+/kernel/drivers/net/ethernet/stmicro/stmmac/stmmac-pci.ko 10 | fi 11 | 12 | /root/prog02 stmmac-pci 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-quark-prog03.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! false ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! false ; then 8 | modprobe stmmac-pci 9 | # insmod /lib/modules/4.19.0stmmac+/kernel/drivers/net/ethernet/stmicro/stmmac/stmmac-pci.ko 10 | fi 11 | 12 | /root/prog03 stmmac-pci 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-quark-prog04.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! false ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! false ; then 8 | modprobe stmmac-pci 9 | # insmod /lib/modules/4.19.0stmmac+/kernel/drivers/net/ethernet/stmicro/stmmac/stmmac-pci.ko 10 | fi 11 | 12 | /root/prog04 stmmac-pci 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-quark-prog05.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! false ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! false ; then 8 | modprobe stmmac-pci 9 | # insmod /lib/modules/4.19.0stmmac+/kernel/drivers/net/ethernet/stmicro/stmmac/stmmac-pci.ko 10 | fi 11 | 12 | /root/prog05 stmmac-pci 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-quark-prog80.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! true ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! true ; then 8 | modprobe stmmac-pci 9 | # insmod /lib/modules/4.19.0stmmac+/kernel/drivers/net/ethernet/stmicro/stmmac/stmmac-pci.ko 10 | fi 11 | 12 | /root/prog80 stmmac-pci 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-quark-prog81.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! true ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! true ; then 8 | modprobe stmmac-pci 9 | # insmod /lib/modules/4.19.0stmmac+/kernel/drivers/net/ethernet/stmicro/stmmac/stmmac-pci.ko 10 | fi 11 | 12 | /root/prog81 stmmac-pci 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-quark-prog96.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! false ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! false ; then 8 | modprobe stmmac-pci 9 | # insmod /lib/modules/4.19.0stmmac+/kernel/drivers/net/ethernet/stmicro/stmmac/stmmac-pci.ko 10 | fi 11 | 12 | /root/prog96 stmmac-pci 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-quark-prog97.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! false ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! false ; then 8 | modprobe stmmac-pci 9 | # insmod /lib/modules/4.19.0stmmac+/kernel/drivers/net/ethernet/stmicro/stmmac/stmmac-pci.ko 10 | fi 11 | 12 | /root/prog97 stmmac-pci 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-quark-prog98.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! true ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! false ; then 8 | modprobe stmmac-pci 9 | # insmod /lib/modules/4.19.0stmmac+/kernel/drivers/net/ethernet/stmicro/stmmac/stmmac-pci.ko 10 | fi 11 | 12 | /root/prog98 stmmac-pci 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-quark-prog99.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! true ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! false ; then 8 | modprobe stmmac-pci 9 | # insmod /lib/modules/4.19.0stmmac+/kernel/drivers/net/ethernet/stmicro/stmmac/stmmac-pci.ko 10 | fi 11 | 12 | /root/prog99 stmmac-pci 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-rtl8139-debug.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! true ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! false ; then 8 | modprobe 8139cp 9 | # insmod /lib/modules/4.19.0rtl8139+/kernel/drivers/net/ethernet/realtek/8139cp.ko 10 | fi 11 | 12 | /root/debug 8139cp 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-rtl8139-prog01.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! false ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! false ; then 8 | modprobe 8139cp 9 | # insmod /lib/modules/4.19.0rtl8139+/kernel/drivers/net/ethernet/realtek/8139cp.ko 10 | fi 11 | 12 | /root/prog01 8139cp 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-rtl8139-prog02.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! false ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! false ; then 8 | modprobe 8139cp 9 | # insmod /lib/modules/4.19.0rtl8139+/kernel/drivers/net/ethernet/realtek/8139cp.ko 10 | fi 11 | 12 | /root/prog02 8139cp 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-rtl8139-prog03.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! false ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! false ; then 8 | modprobe 8139cp 9 | # insmod /lib/modules/4.19.0rtl8139+/kernel/drivers/net/ethernet/realtek/8139cp.ko 10 | fi 11 | 12 | /root/prog03 8139cp 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-rtl8139-prog04.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! false ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! false ; then 8 | modprobe 8139cp 9 | # insmod /lib/modules/4.19.0rtl8139+/kernel/drivers/net/ethernet/realtek/8139cp.ko 10 | fi 11 | 12 | /root/prog04 8139cp 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-rtl8139-prog05.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! false ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! false ; then 8 | modprobe 8139cp 9 | # insmod /lib/modules/4.19.0rtl8139+/kernel/drivers/net/ethernet/realtek/8139cp.ko 10 | fi 11 | 12 | /root/prog05 8139cp 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-rtl8139-prog80.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! true ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! true ; then 8 | modprobe 8139cp 9 | # insmod /lib/modules/4.19.0rtl8139+/kernel/drivers/net/ethernet/realtek/8139cp.ko 10 | fi 11 | 12 | /root/prog80 8139cp 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-rtl8139-prog81.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! true ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! true ; then 8 | modprobe 8139cp 9 | # insmod /lib/modules/4.19.0rtl8139+/kernel/drivers/net/ethernet/realtek/8139cp.ko 10 | fi 11 | 12 | /root/prog81 8139cp 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-rtl8139-prog96.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! false ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! false ; then 8 | modprobe 8139cp 9 | # insmod /lib/modules/4.19.0rtl8139+/kernel/drivers/net/ethernet/realtek/8139cp.ko 10 | fi 11 | 12 | /root/prog96 8139cp 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-rtl8139-prog97.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! false ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! false ; then 8 | modprobe 8139cp 9 | # insmod /lib/modules/4.19.0rtl8139+/kernel/drivers/net/ethernet/realtek/8139cp.ko 10 | fi 11 | 12 | /root/prog97 8139cp 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-rtl8139-prog98.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! true ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! false ; then 8 | modprobe 8139cp 9 | # insmod /lib/modules/4.19.0rtl8139+/kernel/drivers/net/ethernet/realtek/8139cp.ko 10 | fi 11 | 12 | /root/prog98 8139cp 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-rtl8139-prog99.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! true ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! false ; then 8 | modprobe 8139cp 9 | # insmod /lib/modules/4.19.0rtl8139+/kernel/drivers/net/ethernet/realtek/8139cp.ko 10 | fi 11 | 12 | /root/prog99 8139cp 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-snic-debug.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! true ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! false ; then 8 | modprobe snic 9 | # insmod /lib/modules/4.19.0snic+/kernel/drivers/scsi/snic/snic.ko 10 | fi 11 | 12 | /root/debug snic 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-snic-prog01.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! false ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! false ; then 8 | modprobe snic 9 | # insmod /lib/modules/4.19.0snic+/kernel/drivers/scsi/snic/snic.ko 10 | fi 11 | 12 | /root/prog01 snic 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-snic-prog02.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! false ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! false ; then 8 | modprobe snic 9 | # insmod /lib/modules/4.19.0snic+/kernel/drivers/scsi/snic/snic.ko 10 | fi 11 | 12 | /root/prog02 snic 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-snic-prog03.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! false ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! false ; then 8 | modprobe snic 9 | # insmod /lib/modules/4.19.0snic+/kernel/drivers/scsi/snic/snic.ko 10 | fi 11 | 12 | /root/prog03 snic 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-snic-prog04.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! false ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! false ; then 8 | modprobe snic 9 | # insmod /lib/modules/4.19.0snic+/kernel/drivers/scsi/snic/snic.ko 10 | fi 11 | 12 | /root/prog04 snic 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-snic-prog05.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! false ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! false ; then 8 | modprobe snic 9 | # insmod /lib/modules/4.19.0snic+/kernel/drivers/scsi/snic/snic.ko 10 | fi 11 | 12 | /root/prog05 snic 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-snic-prog80.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! true ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! true ; then 8 | modprobe snic 9 | # insmod /lib/modules/4.19.0snic+/kernel/drivers/scsi/snic/snic.ko 10 | fi 11 | 12 | /root/prog80 snic 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-snic-prog81.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! true ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! true ; then 8 | modprobe snic 9 | # insmod /lib/modules/4.19.0snic+/kernel/drivers/scsi/snic/snic.ko 10 | fi 11 | 12 | /root/prog81 snic 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-snic-prog96.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! false ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! false ; then 8 | modprobe snic 9 | # insmod /lib/modules/4.19.0snic+/kernel/drivers/scsi/snic/snic.ko 10 | fi 11 | 12 | /root/prog96 snic 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-snic-prog97.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! false ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! false ; then 8 | modprobe snic 9 | # insmod /lib/modules/4.19.0snic+/kernel/drivers/scsi/snic/snic.ko 10 | fi 11 | 12 | /root/prog97 snic 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-snic-prog98.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! true ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! false ; then 8 | modprobe snic 9 | # insmod /lib/modules/4.19.0snic+/kernel/drivers/scsi/snic/snic.ko 10 | fi 11 | 12 | /root/prog98 snic 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-snic-prog99.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! true ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! false ; then 8 | modprobe snic 9 | # insmod /lib/modules/4.19.0snic+/kernel/drivers/scsi/snic/snic.ko 10 | fi 11 | 12 | /root/prog99 snic 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-usb-debug.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! true ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! true ; then 8 | modprobe 9 | # insmod /lib/modules/4.19.0usb+/kernel/ 10 | fi 11 | 12 | /root/debug 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-usb-prog01.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! false ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! true ; then 8 | modprobe 9 | # insmod /lib/modules/4.19.0usb+/kernel/ 10 | fi 11 | 12 | /root/prog01 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-usb-prog02.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! false ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! true ; then 8 | modprobe 9 | # insmod /lib/modules/4.19.0usb+/kernel/ 10 | fi 11 | 12 | /root/prog02 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-usb-prog03.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! false ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! true ; then 8 | modprobe 9 | # insmod /lib/modules/4.19.0usb+/kernel/ 10 | fi 11 | 12 | /root/prog03 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-usb-prog04.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! false ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! true ; then 8 | modprobe 9 | # insmod /lib/modules/4.19.0usb+/kernel/ 10 | fi 11 | 12 | /root/prog04 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-usb-prog05.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! false ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! true ; then 8 | modprobe 9 | # insmod /lib/modules/4.19.0usb+/kernel/ 10 | fi 11 | 12 | /root/prog05 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-usb-prog80.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! true ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! true ; then 8 | modprobe 9 | # insmod /lib/modules/4.19.0usb+/kernel/ 10 | fi 11 | 12 | /root/prog80 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-usb-prog81.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! true ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! true ; then 8 | modprobe 9 | # insmod /lib/modules/4.19.0usb+/kernel/ 10 | fi 11 | 12 | /root/prog81 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-usb-prog96.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! false ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! true ; then 8 | modprobe 9 | # insmod /lib/modules/4.19.0usb+/kernel/ 10 | fi 11 | 12 | /root/prog96 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-usb-prog97.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! false ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! true ; then 8 | modprobe 9 | # insmod /lib/modules/4.19.0usb+/kernel/ 10 | fi 11 | 12 | /root/prog97 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-usb-prog98.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! true ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! true ; then 8 | modprobe 9 | # insmod /lib/modules/4.19.0usb+/kernel/ 10 | fi 11 | 12 | /root/prog98 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent-usb-prog99.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! true ; then 4 | /root/agent-chkpt 5 | fi 6 | 7 | if ! true ; then 8 | modprobe 9 | # insmod /lib/modules/4.19.0usb+/kernel/ 10 | fi 11 | 12 | /root/prog99 13 | -------------------------------------------------------------------------------- /guest/linux/agents/generated/agent.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | id=$(/root/agent-get-prog) 4 | 5 | progs=( 6 | "agent-aqc100-debug.sh" # 0 7 | "agent-aqc100-prog01.sh" # 1 8 | "agent-aqc100-prog02.sh" # 2 9 | "agent-aqc100-prog03.sh" # 3 10 | "agent-aqc100-prog04.sh" # 4 11 | "agent-aqc100-prog05.sh" # 5 12 | "agent-aqc100-prog80.sh" # 6 13 | "agent-aqc100-prog81.sh" # 7 14 | "agent-aqc100-prog96.sh" # 8 15 | "agent-aqc100-prog97.sh" # 9 16 | "agent-aqc100-prog98.sh" # 10 17 | "agent-aqc100-prog99.sh" # 11 18 | "agent-quark-debug.sh" # 12 19 | "agent-quark-prog01.sh" # 13 20 | "agent-quark-prog02.sh" # 14 21 | "agent-quark-prog03.sh" # 15 22 | "agent-quark-prog04.sh" # 16 23 | "agent-quark-prog05.sh" # 17 24 | "agent-quark-prog80.sh" # 18 25 | "agent-quark-prog81.sh" # 19 26 | "agent-quark-prog96.sh" # 20 27 | "agent-quark-prog97.sh" # 21 28 | "agent-quark-prog98.sh" # 22 29 | "agent-quark-prog99.sh" # 23 30 | "agent-rtl8139-debug.sh" # 24 31 | "agent-rtl8139-prog01.sh" # 25 32 | "agent-rtl8139-prog02.sh" # 26 33 | "agent-rtl8139-prog03.sh" # 27 34 | "agent-rtl8139-prog04.sh" # 28 35 | "agent-rtl8139-prog05.sh" # 29 36 | "agent-rtl8139-prog80.sh" # 30 37 | "agent-rtl8139-prog81.sh" # 31 38 | "agent-rtl8139-prog96.sh" # 32 39 | "agent-rtl8139-prog97.sh" # 33 40 | "agent-rtl8139-prog98.sh" # 34 41 | "agent-rtl8139-prog99.sh" # 35 42 | "agent-snic-debug.sh" # 36 43 | "agent-snic-prog01.sh" # 37 44 | "agent-snic-prog02.sh" # 38 45 | "agent-snic-prog03.sh" # 39 46 | "agent-snic-prog04.sh" # 40 47 | "agent-snic-prog05.sh" # 41 48 | "agent-snic-prog80.sh" # 42 49 | "agent-snic-prog81.sh" # 43 50 | "agent-snic-prog96.sh" # 44 51 | "agent-snic-prog97.sh" # 45 52 | "agent-snic-prog98.sh" # 46 53 | "agent-snic-prog99.sh" # 47 54 | "agent-usb-debug.sh" # 48 55 | "agent-usb-prog01.sh" # 49 56 | "agent-usb-prog02.sh" # 50 57 | "agent-usb-prog03.sh" # 51 58 | "agent-usb-prog04.sh" # 52 59 | "agent-usb-prog05.sh" # 53 60 | "agent-usb-prog80.sh" # 54 61 | "agent-usb-prog81.sh" # 55 62 | "agent-usb-prog96.sh" # 56 63 | "agent-usb-prog97.sh" # 57 64 | "agent-usb-prog98.sh" # 58 65 | "agent-usb-prog99.sh" # 59 66 | ) 67 | 68 | sleep 5 69 | 70 | if [ $id -lt ${#progs[@]} ]; then 71 | /root/${progs[$id]} 72 | else 73 | echo "Failed to find guest agent $id" 74 | /root/agent-exit AGENT_START_FAILURE 75 | exit 1 76 | fi 77 | 78 | /root/agent-exit 79 | -------------------------------------------------------------------------------- /guest/linux/progs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file(GLOB prog_C_SRC 2 | "*.c" 3 | ) 4 | 5 | foreach(prog_C ${prog_C_SRC}) 6 | get_filename_component(prog_C ${prog_C} NAME) 7 | string(REPLACE ".c" "" prog_NOEXT ${prog_C}) 8 | add_executable(${prog_NOEXT} ${prog_C}) 9 | target_include_directories( 10 | ${prog_NOEXT} 11 | PUBLIC 12 | ${CMAKE_CURRENT_SOURCE_DIR}/../../ 13 | ) 14 | endforeach() 15 | 16 | file(GLOB prog_SH_SRC 17 | "*.sh" 18 | ) 19 | 20 | foreach(prog_SH ${prog_SH_SRC}) 21 | get_filename_component(prog_SH ${prog_SH} NAME) 22 | string(REPLACE ".sh" "" prog_NOEXT ${prog_SH}) 23 | add_custom_target(${prog_NOEXT} ALL) 24 | add_custom_command( 25 | TARGET ${prog_NOEXT} 26 | COMMAND ${CMAKE_COMMAND} -E copy 27 | ${CMAKE_CURRENT_SOURCE_DIR}/${prog_SH} 28 | ${CMAKE_CURRENT_BINARY_DIR}/${prog_NOEXT} 29 | ) 30 | endforeach() 31 | -------------------------------------------------------------------------------- /guest/linux/progs/prog01.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include // strcpy, memset(), and memcpy() 4 | #include // close() 5 | 6 | #include // inet_pton() and inet_ntop() 7 | //#include // defines values for argument "request" of ioctl. 8 | #include // ETH_P_ARP = 0x0806 9 | #include // struct sockaddr_ll (see man 7 packet) 10 | #include 11 | #include // struct ifreq 12 | #include // struct addrinfo 13 | #include // IPPROTO_RAW, INET_ADDRSTRLEN 14 | #include // IP_MAXPACKET (which is 65535) 15 | #include // macro ioctl is defined 16 | #include // needed for socket() 17 | #include // needed for socket(), uint8_t, uint16_t 18 | 19 | #include // errno, perror() 20 | 21 | #include 22 | #include 23 | 24 | #include 25 | 26 | int ifup(int sockfd, char* iface_name); 27 | 28 | /** 29 | * Create socket function 30 | */ 31 | int create_socket() 32 | { 33 | 34 | int sockfd = 0; 35 | 36 | sockfd = socket(AF_INET, SOCK_DGRAM, 0); 37 | if (sockfd == -1) { 38 | fprintf(stderr, "Could not get socket.\n"); 39 | return -1; 40 | } 41 | 42 | return sockfd; 43 | } 44 | 45 | /** 46 | * Generic ioctrlcall to reduce code size 47 | */ 48 | int generic_ioctrlcall(int sockfd, u_long* flags, struct ifreq* ifr) 49 | { 50 | 51 | if (ioctl(sockfd, (long unsigned int)flags, &ifr) < 0) { 52 | fprintf(stderr, "ioctl: %s\n", (char*)flags); 53 | return -1; 54 | } 55 | return 1; 56 | } 57 | 58 | /** 59 | * Set route with metric 100 60 | */ 61 | int set_route(int sockfd, char* gateway_addr, struct sockaddr_in* addr) 62 | { 63 | struct rtentry route; 64 | int err = 0; 65 | memset(&route, 0, sizeof(route)); 66 | addr = (struct sockaddr_in*)&route.rt_gateway; 67 | addr->sin_family = AF_INET; 68 | addr->sin_addr.s_addr = inet_addr(gateway_addr); 69 | addr = (struct sockaddr_in*)&route.rt_dst; 70 | addr->sin_family = AF_INET; 71 | addr->sin_addr.s_addr = inet_addr("0.0.0.0"); 72 | addr = (struct sockaddr_in*)&route.rt_genmask; 73 | addr->sin_family = AF_INET; 74 | addr->sin_addr.s_addr = inet_addr("0.0.0.0"); 75 | route.rt_flags = RTF_UP | RTF_GATEWAY; 76 | route.rt_metric = 100; 77 | err = ioctl(sockfd, SIOCADDRT, &route); 78 | if ((err) < 0) { 79 | fprintf(stderr, "ioctl: %d\n", err); 80 | return -1; 81 | } 82 | return 1; 83 | } 84 | 85 | /** 86 | * Set ip function 87 | */ 88 | int set_ip(char* iface_name, char* ip_addr, char* gateway_addr) 89 | { 90 | if (!iface_name) 91 | return -1; 92 | struct ifreq ifr; 93 | struct sockaddr_in sin; 94 | int sockfd = create_socket(); 95 | 96 | ifup(sockfd, iface_name); 97 | sin.sin_family = AF_INET; 98 | 99 | // Convert IP from numbers and dots to binary notation 100 | inet_aton(ip_addr, &sin.sin_addr.s_addr); 101 | 102 | /* get interface name */ 103 | strncpy(ifr.ifr_name, iface_name, IFNAMSIZ); 104 | 105 | /* Read interface flags */ 106 | generic_ioctrlcall(sockfd, (u_long*)"SIOCGIFFLAGS", &ifr); 107 | /* 108 | * Expected in according to 109 | * "UNIX Network Programming". 110 | */ 111 | #ifdef ifr_flags 112 | #define IRFFLAGS ifr_flags 113 | #else /* Present on kFreeBSD */ 114 | #define IRFFLAGS ifr_flagshigh 115 | #endif 116 | // If interface is down, bring it up 117 | if (ifr.IRFFLAGS | ~(IFF_UP)) { 118 | ifr.IRFFLAGS |= IFF_UP; 119 | generic_ioctrlcall(sockfd, (u_long*)"SIOCSIFFLAGS", &ifr); 120 | } 121 | // Set route 122 | //set_route(sockfd, gateway_addr , &sin); 123 | memcpy(&ifr.ifr_addr, &sin, sizeof(struct sockaddr)); 124 | // Set interface address 125 | if (ioctl(sockfd, SIOCSIFADDR, &ifr) < 0) { 126 | fprintf(stderr, "Cannot set IP address. "); 127 | perror(ifr.ifr_name); 128 | return -1; 129 | } 130 | #undef IRFFLAGS 131 | 132 | return 0; 133 | } 134 | 135 | int ifup(int sockfd, char* iface_name) 136 | { 137 | struct ifreq ifr; 138 | memset(&ifr, 0, sizeof(ifr)); 139 | 140 | strncpy(ifr.ifr_name, iface_name, IFNAMSIZ); 141 | 142 | ifr.ifr_flags |= IFF_UP; 143 | if (ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0) { 144 | fprintf(stderr, "ifup: "); 145 | perror("SIOCGIFCONF"); 146 | close(sockfd); 147 | return -1; 148 | } 149 | } 150 | 151 | int main(int argc, char** argv) 152 | { 153 | //while(1) 154 | int ret = set_ip("eth0", "192.168.181.128", "192.168.181.1"); 155 | } 156 | -------------------------------------------------------------------------------- /guest/linux/progs/prog02.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include // strcpy, memset(), and memcpy() 4 | #include // close() 5 | 6 | #include // inet_pton() and inet_ntop() 7 | //#include // defines values for argument "request" of ioctl. 8 | #include // ETH_P_ARP = 0x0806 9 | #include // struct sockaddr_ll (see man 7 packet) 10 | #include 11 | #include // struct ifreq 12 | #include // struct addrinfo 13 | #include // IPPROTO_RAW, INET_ADDRSTRLEN 14 | #include // IP_MAXPACKET (which is 65535) 15 | #include // macro ioctl is defined 16 | #include // needed for socket() 17 | #include // needed for socket(), uint8_t, uint16_t 18 | 19 | #include // errno, perror() 20 | 21 | #include 22 | #include 23 | 24 | #include 25 | 26 | int ifup(int sockfd, char* iface_name); 27 | 28 | /** 29 | * Create socket function 30 | */ 31 | int create_socket() 32 | { 33 | 34 | int sockfd = 0; 35 | 36 | sockfd = socket(AF_INET, SOCK_DGRAM, 0); 37 | if (sockfd == -1) { 38 | fprintf(stderr, "Could not get socket.\n"); 39 | return -1; 40 | } 41 | 42 | return sockfd; 43 | } 44 | 45 | /** 46 | * Generic ioctrlcall to reduce code size 47 | */ 48 | int generic_ioctrlcall(int sockfd, u_long* flags, struct ifreq* ifr) 49 | { 50 | 51 | if (ioctl(sockfd, (long unsigned int)flags, &ifr) < 0) { 52 | fprintf(stderr, "ioctl: %s\n", (char*)flags); 53 | return -1; 54 | } 55 | return 1; 56 | } 57 | 58 | /** 59 | * Set route with metric 100 60 | */ 61 | int set_route(int sockfd, char* gateway_addr, struct sockaddr_in* addr) 62 | { 63 | struct rtentry route; 64 | int err = 0; 65 | memset(&route, 0, sizeof(route)); 66 | addr = (struct sockaddr_in*)&route.rt_gateway; 67 | addr->sin_family = AF_INET; 68 | addr->sin_addr.s_addr = inet_addr(gateway_addr); 69 | addr = (struct sockaddr_in*)&route.rt_dst; 70 | addr->sin_family = AF_INET; 71 | addr->sin_addr.s_addr = inet_addr("0.0.0.0"); 72 | addr = (struct sockaddr_in*)&route.rt_genmask; 73 | addr->sin_family = AF_INET; 74 | addr->sin_addr.s_addr = inet_addr("0.0.0.0"); 75 | route.rt_flags = RTF_UP | RTF_GATEWAY; 76 | route.rt_metric = 100; 77 | err = ioctl(sockfd, SIOCADDRT, &route); 78 | if ((err) < 0) { 79 | fprintf(stderr, "ioctl: %d\n", err); 80 | return -1; 81 | } 82 | return 1; 83 | } 84 | 85 | /** 86 | * Set ip function 87 | */ 88 | int set_ip(char* iface_name, char* ip_addr, char* gateway_addr) 89 | { 90 | if (!iface_name) 91 | return -1; 92 | struct ifreq ifr; 93 | struct sockaddr_in sin; 94 | int sockfd = create_socket(); 95 | 96 | ifup(sockfd, iface_name); 97 | sin.sin_family = AF_INET; 98 | 99 | // Convert IP from numbers and dots to binary notation 100 | inet_aton(ip_addr, &sin.sin_addr.s_addr); 101 | 102 | /* get interface name */ 103 | strncpy(ifr.ifr_name, iface_name, IFNAMSIZ); 104 | 105 | /* Read interface flags */ 106 | generic_ioctrlcall(sockfd, (u_long*)"SIOCGIFFLAGS", &ifr); 107 | /* 108 | * Expected in according to 109 | * "UNIX Network Programming". 110 | */ 111 | #ifdef ifr_flags 112 | #define IRFFLAGS ifr_flags 113 | #else /* Present on kFreeBSD */ 114 | #define IRFFLAGS ifr_flagshigh 115 | #endif 116 | // If interface is down, bring it up 117 | if (ifr.IRFFLAGS | ~(IFF_UP)) { 118 | ifr.IRFFLAGS |= IFF_UP; 119 | generic_ioctrlcall(sockfd, (u_long*)"SIOCSIFFLAGS", &ifr); 120 | } 121 | // Set route 122 | //set_route(sockfd, gateway_addr , &sin); 123 | memcpy(&ifr.ifr_addr, &sin, sizeof(struct sockaddr)); 124 | // Set interface address 125 | if (ioctl(sockfd, SIOCSIFADDR, &ifr) < 0) { 126 | fprintf(stderr, "Cannot set IP address. "); 127 | perror(ifr.ifr_name); 128 | return -1; 129 | } 130 | #undef IRFFLAGS 131 | 132 | return 0; 133 | } 134 | 135 | int ifup(int sockfd, char* iface_name) 136 | { 137 | struct ifreq ifr; 138 | memset(&ifr, 0, sizeof(ifr)); 139 | 140 | strncpy(ifr.ifr_name, iface_name, IFNAMSIZ); 141 | 142 | ifr.ifr_flags |= IFF_UP; 143 | if (ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0) { 144 | fprintf(stderr, "ifup: "); 145 | perror("SIOCGIFCONF"); 146 | close(sockfd); 147 | return -1; 148 | } 149 | } 150 | 151 | int main(int argc, char** argv) 152 | { 153 | //while(1) 154 | int ret = set_ip("wlp2s0", "192.168.181.128", "192.168.181.1"); 155 | } 156 | -------------------------------------------------------------------------------- /guest/linux/progs/prog03.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # note that modprobe has been executed by top-level agent script (i.e., agent-dev-prog.sh) 4 | 5 | echo $1 6 | 7 | ifconfig eth0 8 | 9 | exit_code=$? 10 | if [ $exit_code -ne 0 ]; then 11 | /root/agent-exit 12 | fi 13 | 14 | ethtool eth0 15 | 16 | exit_code=$? 17 | if [ $exit_code -ne 0 ]; then 18 | /root/agent-exit 19 | fi 20 | 21 | ethtool -t eth0 22 | 23 | exit_code=$? 24 | if [ $exit_code -ne 0 ]; then 25 | /root/agent-exit 26 | fi 27 | -------------------------------------------------------------------------------- /guest/linux/progs/prog04.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo $1 4 | 5 | cat /proc/net/wireless 6 | 7 | ifconfig 8 | 9 | exit_code=$? 10 | if [ $exit_code -ne 0 ]; then 11 | /root/agent-exit 12 | fi 13 | 14 | iwlist scan 15 | 16 | exit_code=$? 17 | if [ $exit_code -ne 0 ]; then 18 | /root/agent-exit 19 | fi 20 | 21 | iw dev 22 | 23 | exit_code=$? 24 | if [ $exit_code -ne 0 ]; then 25 | /root/agent-exit 26 | fi 27 | -------------------------------------------------------------------------------- /guest/linux/progs/prog05.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ## This file is used as the guest agent for reported PCI experiments 4 | 5 | echo $1 6 | 7 | #ifconfig 8 | -------------------------------------------------------------------------------- /guest/linux/progs/prog80.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # note that modprobe has been executed by top-level agent script (i.e., agent-dev-prog.sh) 4 | 5 | echo "$1" 6 | 7 | /root/agent-next 8 | 9 | while : 10 | do 11 | echo "modprobe $1" 12 | timeout 5 modprobe -v $1 13 | #echo "ifconfig" 14 | #timeout 5 ifconfig 15 | echo "modprobe -r -f $1" 16 | timeout 5 modprobe -r -v -f $1 17 | echo "next input" 18 | /root/agent-next 19 | done 20 | -------------------------------------------------------------------------------- /guest/linux/progs/prog81.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # note that modprobe has been executed by top-level agent script (i.e., agent-dev-prog.sh) 4 | 5 | echo "$1" 6 | 7 | while : 8 | do 9 | modprobe $1 10 | ifconfig eth0 11 | rmmod -f $1 12 | /root/agent-next 13 | done 14 | -------------------------------------------------------------------------------- /guest/linux/progs/prog96.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | /syz-usbgen-keyboard 4 | 5 | /root/agent-exit 0xdead0000 6 | -------------------------------------------------------------------------------- /guest/linux/progs/prog97.c: -------------------------------------------------------------------------------- 1 | // benchmark driver 2 | 3 | #include 4 | #include 5 | 6 | enum { 7 | DEBUG_HC_BENCHMARK = 12, 8 | }; 9 | 10 | static bool should_exit(void) 11 | { 12 | return false; 13 | } 14 | 15 | int main() 16 | { 17 | while (!should_exit()) { 18 | agamotto_kvm_hypercall3(HC_AGAMOTTO_DEBUG, DEBUG_HC_BENCHMARK, 0); 19 | } 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /guest/linux/progs/prog98.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo $1 4 | 5 | /syz-executor.debug 6 | -------------------------------------------------------------------------------- /guest/linux/progs/prog99.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo $1 4 | 5 | /syz-executor.debug 6 | -------------------------------------------------------------------------------- /guest/linux/syz/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file(GLOB executor_C_SRC 2 | "*.c" 3 | ) 4 | 5 | foreach(executor_C ${executor_C_SRC}) 6 | get_filename_component(executor_C ${executor_C} NAME) 7 | string(REPLACE "executor" "syz-executor" syz_executor_C ${executor_C}) 8 | string(REPLACE ".c" "" syz_executor_NOEXT ${syz_executor_C}) 9 | add_executable(${syz_executor_NOEXT} ${executor_C}) 10 | message(${CMAKE_CURRENT_SOURCE_DIR}) 11 | target_include_directories( 12 | ${syz_executor_NOEXT} 13 | PUBLIC 14 | ${CMAKE_CURRENT_SOURCE_DIR}/../../ 15 | ) 16 | target_link_libraries(${syz_executor_NOEXT} rt) 17 | endforeach() 18 | 19 | 20 | file(GLOB executor_SH_SRC 21 | "*.sh" 22 | ) 23 | 24 | foreach(executor_SH ${executor_SH_SRC}) 25 | get_filename_component(executor_SH ${executor_SH} NAME) 26 | string(REPLACE "executor" "syz-executor" syz_executor_SH ${executor_SH}) 27 | string(REPLACE ".sh" "" syz_executor_NOEXT ${syz_executor_SH}) 28 | add_custom_target(${syz_executor_NOEXT} ALL) 29 | add_custom_command( 30 | TARGET ${syz_executor_NOEXT} 31 | COMMAND ${CMAKE_COMMAND} -E copy 32 | ${CMAKE_CURRENT_SOURCE_DIR}/${executor_SH} 33 | ${CMAKE_CURRENT_BINARY_DIR}/${syz_executor_NOEXT} 34 | ) 35 | endforeach() 36 | -------------------------------------------------------------------------------- /guest/linux/syz/executor.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | #define EXEC_BUFFER_SIZE (2 << 20) 14 | #define OUTPUT_SIZE (16 << 20) 15 | 16 | const int kInFd = 3; 17 | const int kOutFd = 4; 18 | 19 | static int file_idx = 0; 20 | 21 | typedef struct { 22 | uint64_t pfn : 54; 23 | unsigned int soft_dirty : 1; 24 | unsigned int file_page : 1; 25 | unsigned int swapped : 1; 26 | unsigned int present : 1; 27 | } PagemapEntry; 28 | 29 | static int pagemap_get_entry(PagemapEntry* entry, int pagemap_fd, uintptr_t vaddr) 30 | { 31 | size_t nread; 32 | ssize_t ret; 33 | uint64_t data; 34 | uintptr_t vpn; 35 | 36 | vpn = vaddr / sysconf(_SC_PAGE_SIZE); 37 | nread = 0; 38 | while (nread < sizeof(data)) { 39 | ret = pread(pagemap_fd, &data, sizeof(data) - nread, 40 | vpn * sizeof(data) + nread); 41 | nread += ret; 42 | if (ret <= 0) { 43 | printf("failed to pread\n"); 44 | return -1; 45 | } 46 | } 47 | 48 | entry->pfn = data & (((uint64_t)1 << 54) - 1); 49 | entry->soft_dirty = (data >> 54) & 1; 50 | entry->file_page = (data >> 61) & 1; 51 | entry->swapped = (data >> 62) & 1; 52 | entry->present = (data >> 63) & 1; 53 | return 0; 54 | } 55 | 56 | static uint64_t get_phys_addr(pid_t pid, void* vaddr) 57 | { 58 | char pagemap_file[BUFSIZ]; 59 | int pagemap_fd; 60 | 61 | snprintf(pagemap_file, sizeof(pagemap_file), "/proc/%ju/pagemap", (uintmax_t)pid); 62 | pagemap_fd = open(pagemap_file, O_RDONLY); 63 | if (pagemap_fd < 0) { 64 | printf("failed to open %s\n", pagemap_file); 65 | return 0; 66 | } 67 | 68 | PagemapEntry entry; 69 | if (pagemap_get_entry(&entry, pagemap_fd, (uintptr_t)vaddr)) { 70 | return 0; 71 | } 72 | 73 | close(pagemap_fd); 74 | 75 | return (entry.pfn * sysconf(_SC_PAGE_SIZE)) + ((uintptr_t)vaddr % sysconf(_SC_PAGE_SIZE)); 76 | } 77 | 78 | static void printk(const char* fmt, ...) 79 | { 80 | va_list args; 81 | 82 | va_start(args, fmt); 83 | //char msg[1024]; 84 | //snprintf(msg, sizeof(msg), fmt, args); 85 | 86 | int kmsg_fd = open("/dev/kmsg", O_WRONLY); 87 | if (kmsg_fd > 0) { 88 | //printf("printk fd=%d msg=%s", kmsg_fd, msg); 89 | //write(kmsg_fd, msg, strlen(msg) + 1); 90 | dprintf(kmsg_fd, fmt, args); 91 | close(kmsg_fd); 92 | } else { 93 | printf("open /dev/kmsg failed with errno=%d\n", errno); 94 | } 95 | 96 | va_end(args); 97 | } 98 | 99 | static char* create_mem_mapped_file(size_t sz, int* out_fd) 100 | { 101 | int fd; 102 | char* ptr; 103 | 104 | char file_name[80]; 105 | sprintf(file_name, "/shm-syzkaller-%d", file_idx++); 106 | 107 | fd = shm_open(file_name, O_RDWR | O_CREAT | O_TRUNC, 0644); 108 | 109 | if (fd <= 0) { 110 | printf("open failed\n"); 111 | return NULL; 112 | } 113 | 114 | printf("new_fd=%d\n", fd); 115 | 116 | if (out_fd) { 117 | *out_fd = fd; 118 | } 119 | 120 | if (lseek(fd, sz - 1, SEEK_SET) == -1) { 121 | printf("lseek failed\n"); 122 | return NULL; 123 | } 124 | 125 | if (write(fd, "", 1) != 1) { 126 | printf("write failed\n"); 127 | return NULL; 128 | } 129 | 130 | ptr = mmap(0, sz, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 131 | 132 | memset(ptr, 0xab, sz); 133 | 134 | return ptr; 135 | } 136 | 137 | #define OPEN_IN_PIPE 138 | #undef OPEN_IN_PIPE 139 | #define OPEN_OUT_PIPE 140 | #undef OPEN_OUT_PIPE 141 | 142 | static int create_virtio_pipes(int* in_fd, int* out_fd, int* err_fd) 143 | { 144 | #ifdef OPEN_IN_PIPE 145 | char* in_file = "/dev/virtio-ports/serial0"; 146 | #endif 147 | #ifdef OPEN_OUT_PIPE 148 | char* out_file = "/dev/virtio-ports/serial1"; 149 | #endif 150 | char* err_file = "/dev/virtio-ports/serial2"; 151 | int fd; 152 | 153 | #ifdef OPEN_IN_PIPE 154 | fd = open(in_file, O_RDONLY); 155 | if (fd <= 0) { 156 | printf("opening stdout failed\n"); 157 | return -1; 158 | } 159 | 160 | if (dup2(fd, 0) < 0) { 161 | printf("dup to stdin failed\n"); 162 | return -1; 163 | } 164 | 165 | close(fd); 166 | #endif 167 | 168 | *in_fd = 0; 169 | 170 | #ifdef OPEN_OUT_PIPE 171 | fd = open(out_file, O_WRONLY | O_SYNC); 172 | if (fd <= 0) { 173 | printf("opening stdout failed\n"); 174 | return -1; 175 | } 176 | 177 | if (dup2(fd, 1) < 0) { 178 | printf("dup to stdout failed\n"); 179 | return -1; 180 | } 181 | 182 | close(fd); 183 | #endif 184 | 185 | *out_fd = 1; 186 | 187 | fd = open(err_file, O_WRONLY | O_SYNC); 188 | if (fd <= 0) { 189 | printf("opening stderr failed\n"); 190 | return -1; 191 | } 192 | 193 | // make stderr go to err_file 194 | if (dup2(fd, 2) < 0) { 195 | printf("dup to stderr failed\n"); 196 | return -1; 197 | } 198 | 199 | close(fd); 200 | 201 | *err_fd = 2; 202 | 203 | return 0; 204 | } 205 | 206 | #define NOSHMEM 0 207 | 208 | static int make_env() 209 | { 210 | int in_fd, out_fd, err_fd; 211 | 212 | #if 1 // pipes 213 | 214 | #if !NOSHMEM 215 | char* host_test = getenv("HOST_TEST"); 216 | 217 | int in_shm_fd = open("/dev/uio0", O_RDWR | O_SYNC); // in 218 | int out_shm_fd = open("/dev/uio1", O_RDWR | O_SYNC); // out 219 | 220 | if (in_shm_fd != kInFd || out_shm_fd != kOutFd) { 221 | perror("unexpected file descriptors\n"); 222 | return -1; 223 | } 224 | 225 | if (host_test) { 226 | printf("in_shm_fd=%d out_shm_id=%d", in_shm_fd, out_shm_fd); 227 | 228 | char* map = (char*)mmap(0, 2 << 20, PROT_READ | PROT_WRITE, MAP_SHARED, in_shm_fd, 1 * getpagesize()); 229 | if (map == MAP_FAILED) { 230 | perror("map of kInFd: failed\n"); 231 | return -1; 232 | } 233 | printf("map of kInFd: success\n"); 234 | munmap(map, 2 << 20); 235 | } 236 | 237 | #endif 238 | 239 | if (create_virtio_pipes(&in_fd, &out_fd, &err_fd) != 0) { 240 | return -1; 241 | } 242 | 243 | #if 1 244 | // TODO: hypercall 245 | #else 246 | // handshake with fuzzer running in host 247 | uint32_t val = 0x0; 248 | int res; 249 | if ((res = read(in_fd, &val, 4)) != 4) { 250 | printf("read from in_fd failed\n"); 251 | printk("### read from in_fd failed\n"); 252 | } 253 | printf("read 0x%x\n", val); 254 | printk("### read 0x%x\n", val); 255 | 256 | if (val != 0xdeaddead) { 257 | return -1; 258 | } 259 | 260 | val = 0xbeefbeef; 261 | if ((res = write(out_fd, &val, 4)) != 4) { 262 | printf("write to out_fd failed\n"); 263 | printk("### write to out_fd failed\n"); 264 | return -1; 265 | } 266 | printf("written 0x%x\n", val); 267 | printk("### written 0x%x\n", val); 268 | #endif 269 | 270 | if (in_fd != 0 || out_fd != 1 || err_fd != 2) { 271 | printf("unexpected file descriptors\n"); 272 | return -1; 273 | } 274 | 275 | #else 276 | char* in_ptr; 277 | char* out_ptr; 278 | 279 | in_ptr = create_mem_mapped_file(EXEC_BUFFER_SIZE, &in_fd); 280 | out_ptr = create_mem_mapped_file(OUTPUT_SIZE, &out_fd); 281 | 282 | if (!in_ptr || !out_ptr) { 283 | printf("failed to mmap file descriptors\n"); 284 | return -1; 285 | } 286 | 287 | int pid = getpid(); 288 | uint64_t in_phys_ptr = get_phys_addr(pid, in_ptr); 289 | uint64_t out_phys_ptr = get_phys_addr(pid, out_ptr); 290 | 291 | char* host_test = getenv("HOST_TEST"); 292 | if (!host_test) { 293 | agamotto_kvm_hypercall3(HC_AGAMOTTO_DEBUG, 3, in_phys_ptr); 294 | agamotto_kvm_hypercall3(HC_AGAMOTTO_DEBUG, 4, out_phys_ptr); 295 | } 296 | 297 | printf("in=0x%lx out=0x%lx\n", in_phys_ptr, out_phys_ptr); 298 | 299 | if (in_fd != kInFd || out_fd != kOutFd || err_fd != 2) { 300 | printf("unexpected file descriptors\n"); 301 | return -1; 302 | } 303 | #endif 304 | 305 | return 0; 306 | } 307 | 308 | int main(int argc, char** argv) 309 | { 310 | // TODO: support simple executor command, e.g., revision 311 | 312 | if (make_env() == 0) { 313 | printf("executing syz-executor...\n"); 314 | printk("### executing syz-executor...\n"); 315 | 316 | argv[0] = "syz-executor"; 317 | execv("/syz-executor", argv); 318 | 319 | printf("execv exited with error %d\n", errno); 320 | } else { 321 | printf("syz-executor env setup failed.\n"); 322 | printk("### syz-executor env setup failed.\n"); 323 | } 324 | 325 | return 0; 326 | } 327 | -------------------------------------------------------------------------------- /libafl/.gitignore: -------------------------------------------------------------------------------- 1 | /afl-2.52b/ 2 | /afl-2.52b.tgz 3 | -------------------------------------------------------------------------------- /libafl/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(libafl) 2 | 3 | add_library(afl 4 | STATIC 5 | $ 6 | ) 7 | 8 | add_library(libafl 9 | OBJECT 10 | "src/libafl.c" 11 | "afl-2.52b/afl-fuzz.c" 12 | ) 13 | 14 | set(BIN_PATH ${CMAKE_CURRENT_BINARY_DIR}) 15 | set(AFL_PATH ${CMAKE_CURRENT_SOURCE_DIR}/afl-2.52b) 16 | 17 | message(STATUS ${AFL_PATH}) 18 | 19 | set(CMAKE_C_FLAGS "-fPIC -DAFL_LIB -DBIN_PATH='\"${BIN_PATH}\"'") 20 | 21 | target_include_directories(libafl PUBLIC ${AFL_PATH}/..) 22 | 23 | target_link_libraries(afl PUBLIC dl) 24 | -------------------------------------------------------------------------------- /libafl/libafl.patch: -------------------------------------------------------------------------------- 1 | From 5e330dc7cf5b4bbea025619cc1203d77f65591cf Mon Sep 17 00:00:00 2001 2 | From: Dokyung Song 3 | Date: Thu, 25 Apr 2019 08:43:33 -0700 4 | Subject: [PATCH] LIBAFL patch 5 | 6 | --- 7 | afl-fuzz.c | 138 +++++++++++++++++++++++++++++++++++------------------ 8 | config.h | 2 +- 9 | 2 files changed, 93 insertions(+), 47 deletions(-) 10 | 11 | diff --git a/afl-fuzz.c b/afl-fuzz.c 12 | index 01b4afe..4e58c18 100644 13 | --- a/afl-fuzz.c 14 | +++ b/afl-fuzz.c 15 | @@ -80,6 +80,8 @@ 16 | really makes no sense to haul them around as function parameters. */ 17 | 18 | 19 | +EXP_ST s32 in_seed = -1; 20 | + 21 | EXP_ST u8 *in_dir, /* Input directory with test cases */ 22 | *out_file, /* File to fuzz, if any */ 23 | *out_dir, /* Working & output directory */ 24 | @@ -124,13 +126,13 @@ EXP_ST u8 skip_deterministic, /* Skip deterministic stages? */ 25 | deferred_mode, /* Deferred forkserver mode? */ 26 | fast_cal; /* Try to calibrate faster? */ 27 | 28 | -static s32 out_fd, /* Persistent fd for out_file */ 29 | +EXP_ST s32 out_fd, /* Persistent fd for out_file */ 30 | dev_urandom_fd = -1, /* Persistent fd for /dev/urandom */ 31 | dev_null_fd = -1, /* Persistent fd for /dev/null */ 32 | fsrv_ctl_fd, /* Fork server control pipe (write) */ 33 | fsrv_st_fd; /* Fork server status pipe (read) */ 34 | 35 | -static s32 forksrv_pid, /* PID of the fork server */ 36 | +EXP_ST s32 forksrv_pid, /* PID of the fork server */ 37 | child_pid = -1, /* PID of the fuzzed program */ 38 | out_dir_fd = -1; /* FD of the lock file */ 39 | 40 | @@ -144,7 +146,7 @@ static u8 var_bytes[MAP_SIZE]; /* Bytes that appear to be variable */ 41 | 42 | static s32 shm_id; /* ID of the SHM region */ 43 | 44 | -static volatile u8 stop_soon, /* Ctrl-C pressed? */ 45 | +EXP_ST volatile u8 stop_soon, /* Ctrl-C pressed? */ 46 | clear_screen = 1, /* Window resized? */ 47 | child_timed_out; /* Traced process timed out? */ 48 | 49 | @@ -184,25 +186,25 @@ EXP_ST u64 total_crashes, /* Total number of crashes */ 50 | blocks_eff_total, /* Blocks subject to effector maps */ 51 | blocks_eff_select; /* Blocks selected as fuzzable */ 52 | 53 | -static u32 subseq_tmouts; /* Number of timeouts in a row */ 54 | +EXP_ST u32 subseq_tmouts; /* Number of timeouts in a row */ 55 | 56 | -static u8 *stage_name = "init", /* Name of the current fuzz stage */ 57 | +EXP_ST u8 *stage_name = "init", /* Name of the current fuzz stage */ 58 | *stage_short, /* Short stage name */ 59 | *syncing_party; /* Currently syncing with... */ 60 | 61 | -static s32 stage_cur, stage_max; /* Stage progression */ 62 | -static s32 splicing_with = -1; /* Splicing with which test case? */ 63 | +EXP_ST s32 stage_cur, stage_max; /* Stage progression */ 64 | +EXP_ST s32 splicing_with = -1; /* Splicing with which test case? */ 65 | 66 | -static u32 master_id, master_max; /* Master instance job splitting */ 67 | +EXP_ST u32 master_id, master_max; /* Master instance job splitting */ 68 | 69 | static u32 syncing_case; /* Syncing with case #... */ 70 | 71 | -static s32 stage_cur_byte, /* Byte offset of current stage op */ 72 | +EXP_ST s32 stage_cur_byte, /* Byte offset of current stage op */ 73 | stage_cur_val; /* Value used for stage op */ 74 | 75 | -static u8 stage_val_type; /* Value type (STAGE_VAL_*) */ 76 | +EXP_ST u8 stage_val_type; /* Value type (STAGE_VAL_*) */ 77 | 78 | -static u64 stage_finds[32], /* Patterns found per fuzz stage */ 79 | +EXP_ST u64 stage_finds[32], /* Patterns found per fuzz stage */ 80 | stage_cycles[32]; /* Execs per fuzz stage */ 81 | 82 | static u32 rand_cnt; /* Random number counter */ 83 | @@ -221,13 +223,15 @@ static s32 cpu_aff = -1; /* Selected CPU core */ 84 | 85 | #endif /* HAVE_AFFINITY */ 86 | 87 | -static FILE* plot_file; /* Gnuplot output file */ 88 | +EXP_ST FILE* plot_file; /* Gnuplot output file */ 89 | 90 | struct queue_entry { 91 | 92 | u8* fname; /* File name for the test case */ 93 | u32 len; /* Input length */ 94 | 95 | + u32 used_len; /* Used input length */ 96 | + 97 | u8 cal_failed, /* Calibration failed? */ 98 | trim_done, /* Trimmed? */ 99 | was_fuzzed, /* Had any fuzzing done yet? */ 100 | @@ -252,7 +256,7 @@ struct queue_entry { 101 | 102 | }; 103 | 104 | -static struct queue_entry *queue, /* Fuzzing queue (linked list) */ 105 | +EXP_ST struct queue_entry *queue, /* Fuzzing queue (linked list) */ 106 | *queue_cur, /* Current offset within the queue */ 107 | *queue_top, /* Top of the list */ 108 | *q_prev100; /* Previous 100 marker */ 109 | @@ -266,11 +270,11 @@ struct extra_data { 110 | u32 hit_cnt; /* Use count in the corpus */ 111 | }; 112 | 113 | -static struct extra_data* extras; /* Extra tokens to fuzz with */ 114 | -static u32 extras_cnt; /* Total number of tokens read */ 115 | +EXP_ST struct extra_data* extras; /* Extra tokens to fuzz with */ 116 | +EXP_ST u32 extras_cnt; /* Total number of tokens read */ 117 | 118 | -static struct extra_data* a_extras; /* Automatically selected extras */ 119 | -static u32 a_extras_cnt; /* Total number of tokens available */ 120 | +EXP_ST struct extra_data* a_extras; /* Automatically selected extras */ 121 | +EXP_ST u32 a_extras_cnt; /* Total number of tokens available */ 122 | 123 | static u8* (*post_handler)(u8* buf, u32* len); 124 | 125 | @@ -324,7 +328,7 @@ enum { 126 | 127 | /* Get unix time in milliseconds */ 128 | 129 | -static u64 get_cur_time(void) { 130 | +EXP_ST u64 get_cur_time(void) { 131 | 132 | struct timeval tv; 133 | struct timezone tz; 134 | @@ -361,6 +365,15 @@ static inline u32 UR(u32 limit) { 135 | 136 | ck_read(dev_urandom_fd, &seed, sizeof(seed), "/dev/urandom"); 137 | 138 | + if (in_seed > -1) { 139 | + 140 | + seed[0] = in_seed; 141 | + in_seed += 128; 142 | + seed[1] = in_seed; 143 | + in_seed += 128; 144 | + 145 | + } 146 | + 147 | srandom(seed[0]); 148 | rand_cnt = (RESEED_RNG / 2) + (seed[1] % RESEED_RNG); 149 | 150 | @@ -510,7 +523,7 @@ static void bind_to_free_cpu(void) { 151 | /* Helper function to compare buffers; returns first and last differing offset. We 152 | use this to find reasonable locations for splicing two files. */ 153 | 154 | -static void locate_diffs(u8* ptr1, u8* ptr2, u32 len, s32* first, s32* last) { 155 | +EXP_ST void locate_diffs(u8* ptr1, u8* ptr2, u32 len, s32* first, s32* last) { 156 | 157 | s32 f_loc = -1; 158 | s32 l_loc = -1; 159 | @@ -695,7 +708,7 @@ static u8* DTD(u64 cur_ms, u64 event_ms) { 160 | .state file to avoid repeating deterministic fuzzing when resuming aborted 161 | scans. */ 162 | 163 | -static void mark_as_det_done(struct queue_entry* q) { 164 | +EXP_ST void mark_as_det_done(struct queue_entry* q) { 165 | 166 | u8* fn = strrchr(q->fname, '/'); 167 | s32 fd; 168 | @@ -1284,7 +1297,7 @@ static void update_bitmap_score(struct queue_entry* q) { 169 | until the next run. The favored entries are given more air time during 170 | all fuzzing steps. */ 171 | 172 | -static void cull_queue(void) { 173 | +EXP_ST void cull_queue(void) { 174 | 175 | struct queue_entry* q; 176 | static u8 temp_v[MAP_SIZE >> 3]; 177 | @@ -1402,7 +1415,7 @@ static void setup_post(void) { 178 | /* Read all testcases from the input directory, then queue them for testing. 179 | Called at startup. */ 180 | 181 | -static void read_testcases(void) { 182 | +EXP_ST void read_testcases(void) { 183 | 184 | struct dirent **nl; 185 | s32 nl_cnt; 186 | @@ -1659,7 +1672,7 @@ static void load_extras_file(u8* fname, u32* min_len, u32* max_len, 187 | 188 | /* Read extras from the extras directory and sort them by size. */ 189 | 190 | -static void load_extras(u8* dir) { 191 | +EXP_ST void load_extras(u8* dir) { 192 | 193 | DIR* d; 194 | struct dirent* de; 195 | @@ -1771,7 +1784,7 @@ static inline u8 memcmp_nocase(u8* m1, u8* m2, u32 len) { 196 | 197 | /* Maybe add automatic extra. */ 198 | 199 | -static void maybe_add_auto(u8* mem, u32 len) { 200 | +EXP_ST void maybe_add_auto(u8* mem, u32 len) { 201 | 202 | u32 i; 203 | 204 | @@ -1877,7 +1890,7 @@ sort_a_extras: 205 | 206 | /* Save automatically generated extras. */ 207 | 208 | -static void save_auto(void) { 209 | +EXP_ST void save_auto(void) { 210 | 211 | u32 i; 212 | 213 | @@ -1905,7 +1918,7 @@ static void save_auto(void) { 214 | 215 | /* Load automatically generated extras. */ 216 | 217 | -static void load_auto(void) { 218 | +EXP_ST void load_auto(void) { 219 | 220 | u32 i; 221 | 222 | @@ -1948,7 +1961,7 @@ static void load_auto(void) { 223 | 224 | /* Destroy extras. */ 225 | 226 | -static void destroy_extras(void) { 227 | +EXP_ST void destroy_extras(void) { 228 | 229 | u32 i; 230 | 231 | @@ -2262,6 +2275,7 @@ static u8 run_target(char** argv, u32 timeout) { 232 | 233 | static struct itimerval it; 234 | static u32 prev_timed_out = 0; 235 | + static u32 used_len = 0; 236 | 237 | int status = 0; 238 | u32 tb4; 239 | @@ -2378,7 +2392,7 @@ static u8 run_target(char** argv, u32 timeout) { 240 | 241 | } 242 | 243 | - if (child_pid <= 0) FATAL("Fork server is misbehaving (OOM?)"); 244 | + if (child_pid <= 0) FATAL("Fork server is misbehaving (OOM?) %d", child_pid); 245 | 246 | } 247 | 248 | @@ -2406,6 +2420,13 @@ static u8 run_target(char** argv, u32 timeout) { 249 | 250 | } 251 | 252 | + if ((res = read(fsrv_st_fd, &used_len, 4)) != 4) { 253 | + 254 | + if (stop_soon) return 0; 255 | + RPFATAL(res, "Unable to communicate with fork server (OOM?)"); 256 | + 257 | + } 258 | + 259 | } 260 | 261 | if (!WIFSTOPPED(status)) child_pid = 0; 262 | @@ -2439,7 +2460,7 @@ static u8 run_target(char** argv, u32 timeout) { 263 | 264 | kill_signal = WTERMSIG(status); 265 | 266 | - if (child_timed_out && kill_signal == SIGKILL) return FAULT_TMOUT; 267 | + if (kill_signal == SIGKILL) return FAULT_TMOUT; 268 | 269 | return FAULT_CRASH; 270 | 271 | @@ -2461,6 +2482,27 @@ static u8 run_target(char** argv, u32 timeout) { 272 | } 273 | 274 | 275 | +static void write_queue_cur() { 276 | + 277 | + u8 *fn = alloc_printf("%s/queue_cur", out_dir); 278 | + 279 | + unlink(fn); 280 | + 281 | + if (queue_cur) { 282 | + 283 | + if (symlink(queue_cur->fname, fn) != 0) { 284 | + 285 | + PFATAL("Unable to create '%s'", fn); 286 | + 287 | + } 288 | + 289 | + } 290 | + 291 | + ck_free(fn); 292 | + 293 | +} 294 | + 295 | + 296 | /* Write modified data to file for testing. If out_file is set, the old file 297 | is unlinked and a new one is created. Otherwise, out_fd is rewound and 298 | truncated. */ 299 | @@ -2469,6 +2511,8 @@ static void write_to_testcase(void* mem, u32 len) { 300 | 301 | s32 fd = out_fd; 302 | 303 | + write_queue_cur(); 304 | + 305 | if (out_file) { 306 | 307 | unlink(out_file); /* Ignore errors. */ 308 | @@ -2522,13 +2566,13 @@ static void write_with_gap(void* mem, u32 len, u32 skip_at, u32 skip_len) { 309 | } 310 | 311 | 312 | -static void show_stats(void); 313 | +EXP_ST void show_stats(void); 314 | 315 | /* Calibrate a new test case. This is done when processing the input directory 316 | to warn about flaky or otherwise problematic test cases early on; and when 317 | new paths are discovered to detect variable behavior and so on. */ 318 | 319 | -static u8 calibrate_case(char** argv, struct queue_entry* q, u8* use_mem, 320 | +EXP_ST u8 calibrate_case(char** argv, struct queue_entry* q, u8* use_mem, 321 | u32 handicap, u8 from_queue) { 322 | 323 | static u8 first_trace[MAP_SIZE]; 324 | @@ -2694,7 +2738,7 @@ static void check_map_coverage(void) { 325 | /* Perform dry run of all test cases to confirm that the app is working as 326 | expected. This is done only for the initial inputs, and only once. */ 327 | 328 | -static void perform_dry_run(char** argv) { 329 | +EXP_ST void perform_dry_run(char** argv) { 330 | 331 | struct queue_entry* q = queue; 332 | u32 cal_failures = 0; 333 | @@ -2931,7 +2975,7 @@ static void nuke_resume_dir(void); 334 | /* Create hard links for input test cases in the output directory, choosing 335 | good names and pivoting accordingly. */ 336 | 337 | -static void pivot_inputs(void) { 338 | +EXP_ST void pivot_inputs(void) { 339 | 340 | struct queue_entry* q = queue; 341 | u32 id = 0; 342 | @@ -3302,7 +3346,7 @@ keep_as_crash: 343 | /* When resuming, try to find the queue position to start from. This makes sense 344 | only when resuming, and when we can find the original fuzzer_stats. */ 345 | 346 | -static u32 find_start_position(void) { 347 | +EXP_ST u32 find_start_position(void) { 348 | 349 | static u8 tmp[4096]; /* Ought to be enough for anybody. */ 350 | 351 | @@ -3372,7 +3416,7 @@ static void find_timeout(void) { 352 | 353 | /* Update stats file for unattended monitoring. */ 354 | 355 | -static void write_stats_file(double bitmap_cvg, double stability, double eps) { 356 | +EXP_ST void write_stats_file(double bitmap_cvg, double stability, double eps) { 357 | 358 | static double last_bcvg, last_stab, last_eps; 359 | 360 | @@ -3459,10 +3503,12 @@ static void maybe_update_plot_file(double bitmap_cvg, double eps) { 361 | static u32 prev_qp, prev_pf, prev_pnf, prev_ce, prev_md; 362 | static u64 prev_qc, prev_uc, prev_uh; 363 | 364 | +#if 0 365 | if (prev_qp == queued_paths && prev_pf == pending_favored && 366 | prev_pnf == pending_not_fuzzed && prev_ce == current_entry && 367 | prev_qc == queue_cycle && prev_uc == unique_crashes && 368 | prev_uh == unique_hangs && prev_md == max_depth) return; 369 | +#endif 370 | 371 | prev_qp = queued_paths; 372 | prev_pf = pending_favored; 373 | @@ -3867,7 +3913,7 @@ static void check_term_size(void); 374 | /* A spiffy retro stats screen! This is called every stats_update_freq 375 | execve() calls, plus in several other circumstances. */ 376 | 377 | -static void show_stats(void) { 378 | +EXP_ST void show_stats(void) { 379 | 380 | static u64 last_stats_ms, last_plot_ms, last_ms, last_execs; 381 | static double avg_exec; 382 | @@ -4340,7 +4386,7 @@ static void show_stats(void) { 383 | plus a bunch of warnings. Some calibration stuff also ended up here, 384 | along with several hardcoded constants. Maybe clean up eventually. */ 385 | 386 | -static void show_init_stats(void) { 387 | +EXP_ST void show_init_stats(void) { 388 | 389 | struct queue_entry* q = queue; 390 | u32 min_bits = 0, max_bits = 0; 391 | @@ -4460,7 +4506,7 @@ static u32 next_p2(u32 val) { 392 | trimmer uses power-of-two increments somewhere between 1/16 and 1/1024 of 393 | file size, to keep the stage short and sweet. */ 394 | 395 | -static u8 trim_case(char** argv, struct queue_entry* q, u8* in_buf) { 396 | +EXP_ST u8 trim_case(char** argv, struct queue_entry* q, u8* in_buf) { 397 | 398 | static u8 tmp[64]; 399 | static u8 clean_trace[MAP_SIZE]; 400 | @@ -4636,7 +4682,7 @@ EXP_ST u8 common_fuzz_stuff(char** argv, u8* out_buf, u32 len) { 401 | /* Helper to choose random block len for block operations in fuzz_one(). 402 | Doesn't return zero, provided that max_len is > 0. */ 403 | 404 | -static u32 choose_block_len(u32 limit) { 405 | +EXP_ST u32 choose_block_len(u32 limit) { 406 | 407 | u32 min_value, max_value; 408 | u32 rlim = MIN(queue_cycle, 3); 409 | @@ -4680,7 +4726,7 @@ static u32 choose_block_len(u32 limit) { 410 | A helper function for fuzz_one(). Maybe some of these constants should 411 | go into config.h. */ 412 | 413 | -static u32 calculate_score(struct queue_entry* q) { 414 | +EXP_ST u32 calculate_score(struct queue_entry* q) { 415 | 416 | u32 avg_exec_us = total_cal_us / total_cal_cycles; 417 | u32 avg_bitmap_size = total_bitmap_size / total_bitmap_entries; 418 | @@ -4754,7 +4800,7 @@ static u32 calculate_score(struct queue_entry* q) { 419 | return 1 if xor_val is zero, which implies that the old and attempted new 420 | values are identical and the exec would be a waste of time. */ 421 | 422 | -static u8 could_be_bitflip(u32 xor_val) { 423 | +EXP_ST u8 could_be_bitflip(u32 xor_val) { 424 | 425 | u32 sh = 0; 426 | 427 | @@ -4784,7 +4830,7 @@ static u8 could_be_bitflip(u32 xor_val) { 428 | /* Helper function to see if a particular value is reachable through 429 | arithmetic operations. Used for similar purposes. */ 430 | 431 | -static u8 could_be_arith(u32 old_val, u32 new_val, u8 blen) { 432 | +EXP_ST u8 could_be_arith(u32 old_val, u32 new_val, u8 blen) { 433 | 434 | u32 i, ov = 0, nv = 0, diffs = 0; 435 | 436 | @@ -4865,7 +4911,7 @@ static u8 could_be_arith(u32 old_val, u32 new_val, u8 blen) { 437 | already executed LE insertion for current blen and wants to see 438 | if BE variant passed in new_val is unique. */ 439 | 440 | -static u8 could_be_interest(u32 old_val, u32 new_val, u8 blen, u8 check_le) { 441 | +EXP_ST u8 could_be_interest(u32 old_val, u32 new_val, u8 blen, u8 check_le) { 442 | 443 | u32 i, j; 444 | 445 | @@ -4937,7 +4983,7 @@ static u8 could_be_interest(u32 old_val, u32 new_val, u8 blen, u8 check_le) { 446 | function is a tad too long... returns 0 if fuzzed successfully, 1 if 447 | skipped or bailed out. */ 448 | 449 | -static u8 fuzz_one(char** argv) { 450 | +EXP_ST u8 fuzz_one(char** argv) { 451 | 452 | s32 len, fd, temp_len, i, j; 453 | u8 *in_buf, *out_buf, *orig_in, *ex_tmp, *eff_map = 0; 454 | @@ -6623,7 +6669,7 @@ abandon_entry: 455 | 456 | /* Grab interesting test cases from other fuzzers. */ 457 | 458 | -static void sync_fuzzers(char** argv) { 459 | +EXP_ST void sync_fuzzers(char** argv) { 460 | 461 | DIR* sd; 462 | struct dirent* sd_ent; 463 | @@ -7428,7 +7474,7 @@ static void get_core_count(void) { 464 | 465 | /* Validate and fix up out_dir and sync_dir when using -S. */ 466 | 467 | -static void fix_up_sync(void) { 468 | +EXP_ST void fix_up_sync(void) { 469 | 470 | u8* x = sync_id; 471 | 472 | diff --git a/config.h b/config.h 473 | index e74b3b3..c407b8d 100644 474 | --- a/config.h 475 | +++ b/config.h 476 | @@ -194,7 +194,7 @@ 477 | /* Fuzzer stats file and plot update intervals (sec): */ 478 | 479 | #define STATS_UPDATE_SEC 60 480 | -#define PLOT_UPDATE_SEC 5 481 | +#define PLOT_UPDATE_SEC 60 482 | 483 | /* Smoothing divisor for CPU load and exec speed stats (1 - no smoothing). */ 484 | 485 | -- 486 | 2.17.1 487 | 488 | -------------------------------------------------------------------------------- /libafl/setup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | AFLVER="${AFLVER:-2.52b}" 4 | 5 | wget lcamtuf.coredump.cx/afl/releases/afl-$AFLVER.tgz; 6 | tar -xf afl-$AFLVER.tgz; 7 | 8 | pushd afl-$AFLVER 9 | # TODO replace it with patch 10 | git init 11 | git add . 12 | git apply ../libafl.patch 13 | popd 14 | -------------------------------------------------------------------------------- /libafl/src/libafl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libafl.h 3 | */ 4 | 5 | #ifndef _LIBAFL_H_ 6 | #define _LIBAFL_H_ 7 | 8 | #include 9 | #include 10 | 11 | #define USE_AFL_FUZZ_ONE 12 | #define SKIP_PERISCOPE_MUTATORS 13 | //#define SKIP_BITFLIP 14 | //#define SKIP_ARITH 15 | 16 | typedef uint8_t u8; 17 | typedef uint16_t u16; 18 | typedef uint32_t u32; 19 | // typedef uint64_t u64; 20 | 21 | typedef int8_t s8; 22 | typedef int16_t s16; 23 | typedef int32_t s32; 24 | typedef int64_t s64; 25 | 26 | u8 libafl_setup(u8 *opt_i, u8 *opt_o, u8 *opt_dict, u8 *opt_f, s32 ctrl_fd, 27 | s32 status_fd, u8 opt_n, u8 opt_d, u8 *opt_M, u8 *opt_S, u32 seed); 28 | void libafl_perform_dry_run(void); 29 | u8 libafl_fuzz_one(void); 30 | void libafl_destroy(void); 31 | 32 | u8 libafl_get_queue_cur_info(void); 33 | 34 | #endif // _LIBAFL_H_ 35 | -------------------------------------------------------------------------------- /libagamotto/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(libagamotto) 2 | 3 | file(GLOB agamotto_SRC 4 | "src/*.c" 5 | ) 6 | 7 | add_library(agamotto 8 | SHARED 9 | ${agamotto_SRC} 10 | ) 11 | 12 | add_library(agamotto_nomain 13 | SHARED 14 | $ 15 | ) 16 | 17 | target_link_libraries(agamotto_nomain PUBLIC dl) 18 | 19 | set(COMMON_FLAGS "-D_GNU_SOURCE") 20 | set(COMMON_FLAGS "${COMMON_FLAGS} -Wall -fPIC -fno-strict-aliasing") 21 | 22 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COMMON_FLAGS}") 23 | 24 | target_link_libraries(agamotto PUBLIC ${CMAKE_DL_LIBS} pthread) 25 | 26 | message(STATUS ${CMAKE_CURRENT_SOURCE_DIR}) 27 | 28 | set(LIBAFL_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../libafl) 29 | 30 | target_include_directories(agamotto PUBLIC ${LIBAFL_PATH}/src) 31 | target_include_directories(agamotto PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) 32 | 33 | target_link_libraries(agamotto PUBLIC afl) 34 | 35 | add_custom_command( 36 | TARGET agamotto_nomain POST_BUILD 37 | COMMAND cp ${LIBAFL_PATH}/src/libafl.h libafl.h 38 | ) 39 | -------------------------------------------------------------------------------- /libagamotto/include/agamotto.h: -------------------------------------------------------------------------------- 1 | /* 2 | * agamotto.h 3 | * 4 | * Authors: 5 | * dokyungs@uci.edu 6 | */ 7 | 8 | #ifndef AGAMOTTO_H 9 | #define AGAMOTTO_H 10 | 11 | #include 12 | 13 | typedef int (*mmio_read_t)(unsigned, uint64_t *); 14 | 15 | #endif -------------------------------------------------------------------------------- /libagamotto/src/fuzzer.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | 18 | #include "fuzzer.h" 19 | 20 | // can it be fork-and-exec? would it be better or not? 21 | static pthread_t s_fuzzer_thread; 22 | static pthread_t s_vmfuzzer_io_thread; 23 | 24 | static volatile bool s_fuzzer_exiting = false; 25 | static pthread_cond_t fuzzer_init_cond = PTHREAD_COND_INITIALIZER; 26 | static pthread_mutex_t fuzzer_init_cond_mutex = PTHREAD_MUTEX_INITIALIZER; 27 | 28 | #define QEMU_MONITOR_UNIX_SOCKET 0 29 | 30 | #if QEMU_MONITOR_UNIX_SOCKET 31 | static int mon_fd = -1; 32 | #endif 33 | 34 | static int st_pipe[2], ctl_pipe[2]; 35 | 36 | #if 0 37 | static void *periscope_forksrv_thread_fn(void *arg) { 38 | s32 res; 39 | int prev_timed_out; 40 | int child_pid = 1; // fake child_pid 41 | int status = 0; 42 | 43 | printf("periscope: fork server thread up and running\n"); 44 | 45 | while (1) { 46 | if ((res = read(ctl_pipe[0], &prev_timed_out, 4)) != 4) { 47 | printf("read from control pipe failed\n"); 48 | } 49 | 50 | #ifdef DEBUG 51 | printf("returning a fake child...\n"); 52 | #endif 53 | 54 | if ((res = write(st_pipe[1], &child_pid, 4)) != 4) { 55 | printf("write to status pipe failed\n"); 56 | } 57 | 58 | // printf("periscope: new input (%s) generated\n", out_file); 59 | 60 | // usleep(100 * 1000); 61 | 62 | if ((res = write(st_pipe[1], &status, 4)) != 4) { 63 | printf("write to status pipe failed\n"); 64 | } 65 | } 66 | 67 | return NULL; 68 | } 69 | #endif 70 | 71 | static void *periscope_fuzzer_thread_fn(void *param) { 72 | pthread_mutex_lock(&fuzzer_init_cond_mutex); 73 | pthread_cond_signal(&fuzzer_init_cond); 74 | pthread_mutex_unlock(&fuzzer_init_cond_mutex); 75 | 76 | #if 0 77 | pthread_t forksrv; 78 | ret = pthread_create(&forksrv, NULL, periscope_forksrv_thread_fn, NULL); 79 | if (ret < 0) { 80 | return NULL; 81 | } 82 | #endif 83 | 84 | libafl_perform_dry_run(); 85 | 86 | while (!s_fuzzer_exiting) { 87 | u8 stop_soon; 88 | stop_soon = libafl_fuzz_one(); 89 | if (stop_soon) { 90 | printf("periscope: stop soon flag set\n"); 91 | break; 92 | } 93 | } 94 | 95 | libafl_destroy(); 96 | 97 | #if 0 98 | pthread_join(forksrv, NULL); 99 | #endif 100 | 101 | #if QEMU_MONITOR_UNIX_SOCKET 102 | int rc; 103 | 104 | const char *cmd = "list snapshots"; // list the VM snapshots 105 | 106 | printf("Cmd: %s\n", cmd); 107 | rc = write(mon_fd, cmd, sizeof(cmd)); 108 | if (rc != sizeof(cmd)) { 109 | printf("cmd partially written\n"); 110 | } 111 | rc = 0; 112 | 113 | while (!s_fuzzer_exiting) { 114 | int wr_bytes = write(mon_fd, cmd, sizeof(cmd)); 115 | if (wr_bytes != sizeof(cmd)) { 116 | printf("wr error\n"); 117 | break; 118 | } 119 | 120 | // printf("vmfuzzer heartbeat\n"); 121 | 122 | usleep(100 * 10000); 123 | } 124 | #endif 125 | 126 | return NULL; 127 | } 128 | 129 | static void *periscope_io_thread_fn(void *arg) { 130 | #if QEMU_MONITOR_UNIX_SOCKET 131 | char buf[1024] = {0}; 132 | 133 | int rc; 134 | int rd_bytes = 0; 135 | 136 | rc = read(mon_fd, buf, 1024); 137 | 138 | while (rc > 0 && !s_fuzzer_exiting) { 139 | rd_bytes += rc; 140 | 141 | for (unsigned i = 0; i < rc; i++) { 142 | printf("%c", buf[i]); 143 | } 144 | memset(buf, 0, sizeof(buf)); 145 | rc = read(mon_fd, buf, 1024); 146 | // printf("rc = %d\n", rc); 147 | } 148 | #endif 149 | 150 | return NULL; 151 | } 152 | 153 | int periscope_init_syz_fuzzer(char **qemu_argv, char *syz_fuzzer_path, 154 | char *syz_fuzzer_argv, char *syz_fuzzer_executor, 155 | char *syz_fuzzer_index, int *out_st_pipe, 156 | int *out_ctl_pipe, int *out_shm_id, 157 | char *fifo_out) { 158 | if (pipe(st_pipe) || pipe(ctl_pipe)) { 159 | return -1; 160 | } 161 | 162 | *out_st_pipe = st_pipe[1]; 163 | *out_ctl_pipe = ctl_pipe[0]; 164 | 165 | int kCoverSize = 256 << 10; 166 | 167 | #ifdef OPEN_SHM 168 | #if 0 169 | *out_shm_id = open("/dev/shm/syzkaller", O_CREAT | O_RDWR | O_TRUNC, 0600); 170 | #else 171 | char *shm_id_str = "/syzkaller"; 172 | *out_shm_id = shm_open(shm_id_str, O_CREAT | O_RDWR | O_TRUNC, 0600); 173 | #endif 174 | ftruncate(*out_shm_id, (kCoverSize * sizeof(uintptr_t)) * 2); 175 | #endif 176 | 177 | if (fork() == 0) { 178 | int pid = getpid(); 179 | printf("periscope: child pid=%d syz-fuzzer=%s %s syz-executor=%s...\n", 180 | pid, syz_fuzzer_path, syz_fuzzer_argv, syz_fuzzer_executor); 181 | 182 | prctl(PR_SET_PDEATHSIG, SIGHUP); 183 | 184 | #ifdef OPEN_IN_PIPE 185 | int in_pipe = open("/tmp/serial0.in", O_WRONLY | O_SYNC); 186 | #endif 187 | #ifdef OPEN_OUT_PIPE 188 | int out_pipe = open("/tmp/serial1.out", O_RDONLY); 189 | #endif 190 | int err_pipe = 0; 191 | if (fifo_out) { 192 | err_pipe = open(fifo_out, O_RDONLY); 193 | } 194 | #ifdef OPEN_IN_PIPE 195 | char in_pipe_str[10 + 1]; 196 | sprintf(in_pipe_str, "%d", in_pipe); 197 | #endif 198 | #ifdef OPEN_OUT_PIPE 199 | char out_pipe_str[10 + 1]; 200 | sprintf(out_pipe_str, "%d", out_pipe); 201 | #endif 202 | char err_pipe_str[10 + 1]; 203 | sprintf(err_pipe_str, "%d", err_pipe); 204 | 205 | char st_pipe_str[10 + 1]; 206 | char ctl_pipe_str[10 + 1]; 207 | sprintf(st_pipe_str, "%d", st_pipe[0]); 208 | sprintf(ctl_pipe_str, "%d", ctl_pipe[1]); 209 | 210 | if (execl(syz_fuzzer_path, "syz-fuzzer", "-executor", 211 | syz_fuzzer_executor, "-args", syz_fuzzer_argv, "-st_pipe", 212 | st_pipe_str, "-ctl_pipe", ctl_pipe_str, 213 | #ifdef OPEN_IN_PIPE 214 | "-in_pipe", in_pipe_str, 215 | #endif 216 | #ifdef OPEN_OUT_PIPE 217 | "-out_pipe", out_pipe_str, 218 | #endif 219 | "-err_pipe", err_pipe_str, 220 | #ifdef OPEN_SHM 221 | "-shm_id", shm_id_str, 222 | #endif 223 | "-index", syz_fuzzer_index, NULL) == -1) { 224 | printf("periscope-child: execv errno=%d\n", errno); 225 | exit(1); 226 | } 227 | } else { 228 | // parent 229 | } 230 | 231 | return 0; 232 | } 233 | 234 | static int periscope_init_fuzzer(int *out_st_pipe, int *out_ctl_pipe) { 235 | int ret; 236 | pthread_attr_t attr; 237 | 238 | if (pipe(st_pipe) || pipe(ctl_pipe)) { 239 | return -1; 240 | } 241 | 242 | char *out_file = getenv("__PERISCOPE_OUT_FILE"); 243 | if (!out_file || strlen(out_file) == 0) { 244 | out_file = "cur"; 245 | } 246 | 247 | char *master_id = getenv("__PERISCOPE_MASTER_ID"); 248 | char *secondary_id = getenv("__PERISCOPE_SECONDARY_ID"); 249 | if (master_id && strlen(master_id)) { 250 | secondary_id = NULL; 251 | } else if (secondary_id && strlen(secondary_id)) { 252 | master_id = NULL; 253 | } else { 254 | master_id = NULL; 255 | secondary_id = NULL; 256 | } 257 | 258 | *out_st_pipe = st_pipe[1]; 259 | *out_ctl_pipe = ctl_pipe[0]; 260 | 261 | char *in_dir = getenv("__PERISCOPE_IN_DIR"); 262 | if (!in_dir || strlen(in_dir) == 0) { 263 | in_dir = "-"; 264 | } 265 | char *out_dir = getenv("__PERISCOPE_OUT_DIR"); 266 | if (!out_dir || strlen(out_dir) == 0) { 267 | out_dir = "out"; 268 | } 269 | char *dict_dir = getenv("__PERISCOPE_DICT_DIR"); 270 | if (!dict_dir || strlen(dict_dir) == 0) { 271 | dict_dir = ""; 272 | } 273 | 274 | unsigned int seed = -1; 275 | char *seed_str = getenv("__PERISCOPE_AFL_SEED"); 276 | if (seed_str) { 277 | sscanf(seed_str, "%d", &seed); 278 | } else { 279 | printf("periscope: seed id not given\n"); 280 | } 281 | 282 | u8 opt_n = false; 283 | u8 opt_d = false; 284 | u8 ok = 285 | libafl_setup(in_dir, out_dir, dict_dir, out_file, ctl_pipe[1], 286 | st_pipe[0], opt_n, opt_d, master_id, secondary_id, seed); 287 | if (!ok) { 288 | ret = -1; 289 | goto err; 290 | } 291 | 292 | ret = pthread_attr_init(&attr); 293 | if (ret < 0) { 294 | goto err; 295 | } 296 | 297 | ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 298 | if (ret < 0) { 299 | goto err; 300 | } 301 | 302 | ret = pthread_create(&s_fuzzer_thread, &attr, periscope_fuzzer_thread_fn, 303 | NULL); 304 | 305 | pthread_attr_destroy(&attr); 306 | 307 | pthread_mutex_lock(&fuzzer_init_cond_mutex); 308 | pthread_cond_wait(&fuzzer_init_cond, &fuzzer_init_cond_mutex); 309 | pthread_mutex_unlock(&fuzzer_init_cond_mutex); 310 | 311 | printf("periscope: fuzzer initialized.\n"); 312 | 313 | err: 314 | return ret; 315 | } 316 | 317 | static int initialize_vmfuzzer_io_thread(void) { 318 | int ret; 319 | pthread_attr_t attr; 320 | 321 | ret = pthread_attr_init(&attr); 322 | if (ret < 0) { 323 | goto err; 324 | } 325 | 326 | ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 327 | if (ret < 0) { 328 | goto err; 329 | } 330 | 331 | ret = pthread_create(&s_vmfuzzer_io_thread, &attr, periscope_io_thread_fn, 332 | NULL); 333 | 334 | pthread_attr_destroy(&attr); 335 | 336 | err: 337 | return ret; 338 | } 339 | 340 | static void (*qemu_sigint_handler)(int); 341 | 342 | static void vmfuzzer_sigint_handler(int signo) { 343 | printf("received SIGINT\n"); 344 | qemu_sigint_handler(signo); 345 | } 346 | 347 | static void initialize_signal_handler(void) { 348 | struct sigaction sa; 349 | struct sigaction old; 350 | 351 | printf("periscope: initializing signal handler\n"); 352 | 353 | sigaction(SIGINT, NULL, &old); 354 | if (old.sa_handler) { 355 | printf("No existing signal handler\n"); 356 | } 357 | qemu_sigint_handler = old.sa_handler; 358 | 359 | memset(&sa, 0, sizeof(sa)); 360 | sa.sa_handler = vmfuzzer_sigint_handler; 361 | sigemptyset(&sa.sa_mask); 362 | sigaction(SIGINT, &sa, NULL); 363 | } 364 | 365 | void periscope_post_qemu_init(void) { 366 | printf("periscope: post init...\n"); 367 | 368 | initialize_signal_handler(); 369 | 370 | #if QEMU_MONITOR_UNIX_SOCKET 371 | struct sockaddr_un addr; 372 | mon_fd = socket(AF_UNIX, SOCK_STREAM, 0); 373 | if (mon_fd == -1) { 374 | printf("socket creation failed\n"); 375 | } 376 | 377 | memset(&addr, 0, sizeof(addr)); 378 | addr.sun_family = AF_UNIX; 379 | strncpy(addr.sun_path, monitor_socket_file, sizeof(addr.sun_path) - 1); 380 | 381 | printf("Connecting to socket: %s\n", monitor_socket_file); 382 | if (connect(mon_fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) { 383 | printf("socket connection failed\n"); 384 | } 385 | #endif 386 | 387 | int ret = initialize_vmfuzzer_io_thread(); 388 | 389 | if (ret < 0) { 390 | printf("initialize vmfuzzer io thread failed.\n"); 391 | } 392 | } 393 | 394 | void periscope_pre_qemu_init(int *out_st_pipe, int *out_ctl_pipe) { 395 | printf("periscope: initializing...\n"); 396 | 397 | int ret = periscope_init_fuzzer(out_st_pipe, out_ctl_pipe); 398 | 399 | if (ret < 0) { 400 | printf("initialie vmfuzzer thread failed.\n"); 401 | } 402 | } 403 | 404 | int periscope_mmio_read(unsigned size, uint64_t *out) { 405 | // 406 | return 0; 407 | } -------------------------------------------------------------------------------- /libagamotto/src/fuzzer.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBAGAMOTTO_FUZZER_H 2 | #define LIBAGAMOTTO_FUZZER_H 3 | 4 | extern char monitor_socket_file[]; 5 | 6 | int periscope_init_syz_fuzzer(char **, char *, char *, char *, char *, int *, 7 | int *, int *, char *); 8 | 9 | void periscope_pre_qemu_init(int *, int *); 10 | void periscope_post_qemu_init(void); 11 | 12 | #endif -------------------------------------------------------------------------------- /libagamotto/src/intercept.c: -------------------------------------------------------------------------------- 1 | // This file contains code derived from libs2e code 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #undef __REDIRECT_NTH 18 | #include 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | #include "fuzzer.h" 25 | #include "kvm.h" 26 | 27 | static open_t s_original_open; 28 | 29 | int g_trace = 0; 30 | int g_kvm_fd = -1; 31 | int g_kvm_vm_fd = -1; 32 | int g_kvm_vcpu_fd = -1; 33 | 34 | int open64(const char *pathname, int flags, ...) { 35 | va_list list; 36 | va_start(list, flags); 37 | mode_t mode = va_arg(list, mode_t); 38 | va_end(list); 39 | 40 | if (strcmp(pathname, "/dev/kvm") == 0) { 41 | printf("periscope: Opening %s\n", pathname); 42 | int fd = s_original_open("/dev/kvm", flags, mode); 43 | if (fd < 0) { 44 | printf("Could not open /dev/kvm\n"); 45 | exit(-1); 46 | } 47 | 48 | g_kvm_fd = fd; 49 | return fd; 50 | } else { 51 | return s_original_open(pathname, flags, mode); 52 | } 53 | } 54 | 55 | static close_t s_original_close; 56 | int close64(int fd) { 57 | if (fd == g_kvm_fd) { 58 | printf("close %d\n", fd); 59 | close(fd); 60 | g_kvm_fd = -1; 61 | return 0; 62 | } else { 63 | return s_original_close(fd); 64 | } 65 | } 66 | 67 | static write_t s_original_write; 68 | ssize_t write(int fd, const void *buf, size_t count) { 69 | #if 0 70 | if (fd == g_kvm_fd || fd == g_kvm_vm_fd) { 71 | printf("write %d count=%ld\n", fd, count); 72 | exit(-1); 73 | } 74 | #endif 75 | return s_original_write(fd, buf, count); 76 | } 77 | 78 | static int handle_kvm_ioctl(int fd, int request, uint64_t arg1) { 79 | int ret = -1; 80 | 81 | switch ((uint32_t)request) { 82 | #if 1 83 | case KVM_GET_API_VERSION: 84 | return kvm_get_api_version(); 85 | case KVM_CHECK_EXTENSION: 86 | ret = kvm_check_extension(fd, arg1); 87 | break; 88 | case KVM_CREATE_VM: 89 | ret = g_original_ioctl(fd, request, arg1); 90 | g_kvm_vm_fd = ret; 91 | periscope_post_qemu_init(); 92 | break; 93 | case KVM_GET_VCPU_MMAP_SIZE: 94 | case KVM_GET_MSR_INDEX_LIST: 95 | case KVM_GET_SUPPORTED_CPUID: 96 | #else 97 | case KVM_CREATE_VM: { 98 | int tmpfd = s2e_kvm_create_vm(fd); 99 | if (tmpfd < 0) { 100 | printf("Could not create vm fd (errno=%d %s)\n", errno, 101 | strerror(errno)); 102 | exit(-1); 103 | } 104 | g_kvm_vm_fd = tmpfd; 105 | ret = tmpfd; 106 | } break; 107 | 108 | case KVM_GET_VCPU_MMAP_SIZE: { 109 | ret = s2e_kvm_get_vcpu_mmap_size(); 110 | } break; 111 | 112 | case KVM_GET_MSR_INDEX_LIST: { 113 | ret = s2e_kvm_get_msr_index_list(fd, (struct kvm_msr_list *)arg1); 114 | } break; 115 | 116 | case KVM_GET_SUPPORTED_CPUID: { 117 | ret = s2e_kvm_get_supported_cpuid(fd, (struct kvm_cpuid2 *)arg1); 118 | } break; 119 | #endif 120 | 121 | default: { 122 | #ifdef PERISCOPE_TRACE_KVM_IOCTL 123 | fprintf(stderr, "periscope: unknown KVM IOCTL %x\n", request); 124 | #endif 125 | ret = g_original_ioctl(fd, request, arg1); 126 | break; 127 | // exit(-1); 128 | } 129 | } 130 | 131 | return ret; 132 | } 133 | 134 | static int handle_kvm_vm_ioctl(int fd, int request, uint64_t arg1) { 135 | int ret = -1; 136 | 137 | switch ((uint32_t)request) { 138 | #if 1 139 | case KVM_CHECK_EXTENSION: 140 | ret = kvm_check_extension(fd, arg1); 141 | if (ret < 0) { 142 | errno = 1; 143 | } 144 | break; 145 | case KVM_SET_TSS_ADDR: 146 | case KVM_CREATE_VCPU: 147 | case KVM_SET_USER_MEMORY_REGION: 148 | case KVM_SET_CLOCK: 149 | case KVM_GET_CLOCK: 150 | case KVM_ENABLE_CAP: 151 | case KVM_IRQ_LINE_STATUS: 152 | ret = g_original_ioctl(fd, request, arg1); 153 | break; 154 | case KVM_GET_DIRTY_LOG: 155 | // printf("KVM_GET_DIRTY_LOG\n"); 156 | ret = g_original_ioctl(fd, request, arg1); 157 | break; 158 | case KVM_IOEVENTFD: 159 | // ret = kvm_vm_ioctl_ioeventfd(fd, (struct kvm_ioeventfd *) arg1); 160 | // break; 161 | case KVM_SET_IDENTITY_MAP_ADDR: 162 | case KVM_REGISTER_COALESCED_MMIO: 163 | // ret = kvm_vm_ioctl_register_coalesced_mmio(fd, (struct 164 | // kvm_coalesced_mmio_zone *) arg1); break; 165 | case KVM_UNREGISTER_COALESCED_MMIO: 166 | // ret = kvm_vm_ioctl_unregister_coalesced_mmio(fd, (struct 167 | // kvm_coalesced_mmio_zone *) arg1); break; 168 | case KVM_ASSIGN_PCI_DEVICE: 169 | // ret = kvm_vm_ioctl_assign_pci_device(fd, (struct kvm_assigned_pci_dev 170 | // *) arg1); 171 | ret = g_original_ioctl(fd, request, arg1); 172 | break; 173 | #if 0 174 | case KVM_MEM_RW: 175 | case KVM_FORCE_EXIT: 176 | case KVM_MEM_REGISTER_FIXED_REGION: 177 | case KVM_DISK_RW: 178 | case KVM_DEV_SNAPSHOT: 179 | case KVM_SET_CLOCK_SCALE: 180 | #endif 181 | break; 182 | #else 183 | case KVM_SET_TSS_ADDR: { 184 | ret = s2e_kvm_vm_set_tss_addr(fd, arg1); 185 | } break; 186 | 187 | case KVM_CREATE_VCPU: { 188 | ret = s2e_kvm_vm_create_vcpu(fd); 189 | } break; 190 | 191 | case KVM_SET_USER_MEMORY_REGION: { 192 | ret = s2e_kvm_vm_set_user_memory_region( 193 | fd, (struct kvm_userspace_memory_region *)arg1); 194 | } break; 195 | 196 | case KVM_SET_CLOCK: { 197 | ret = s2e_kvm_vm_set_clock(fd, (struct kvm_clock_data *)arg1); 198 | } break; 199 | 200 | case KVM_GET_CLOCK: { 201 | ret = s2e_kvm_vm_get_clock(fd, (struct kvm_clock_data *)arg1); 202 | } break; 203 | 204 | case KVM_ENABLE_CAP: { 205 | ret = s2e_kvm_vm_enable_cap(fd, (struct kvm_enable_cap *)arg1); 206 | } break; 207 | 208 | case KVM_IOEVENTFD: { 209 | ret = s2e_kvm_vm_ioeventfd(fd, (struct kvm_ioeventfd *)arg1); 210 | } break; 211 | 212 | case KVM_SET_IDENTITY_MAP_ADDR: { 213 | ret = s2e_kvm_vm_set_identity_map_addr(fd, arg1); 214 | } break; 215 | 216 | case KVM_GET_DIRTY_LOG: { 217 | ret = s2e_kvm_vm_get_dirty_log(fd, (struct kvm_dirty_log *)arg1); 218 | } break; 219 | 220 | case KVM_MEM_RW: { 221 | ret = s2e_kvm_vm_mem_rw(fd, (struct kvm_mem_rw *)arg1); 222 | } break; 223 | 224 | case KVM_FORCE_EXIT: { 225 | s2e_kvm_request_exit(); 226 | ret = 0; 227 | } break; 228 | 229 | case KVM_MEM_REGISTER_FIXED_REGION: { 230 | ret = s2e_kvm_vm_register_fixed_region(fd, 231 | (struct kvm_fixed_region *)arg1); 232 | } break; 233 | 234 | case KVM_DISK_RW: { 235 | ret = s2e_kvm_vm_disk_rw(fd, (struct kvm_disk_rw *)arg1); 236 | } break; 237 | 238 | case KVM_DEV_SNAPSHOT: { 239 | ret = s2e_kvm_vm_dev_snapshot(fd, (struct kvm_dev_snapshot *)arg1); 240 | } break; 241 | 242 | case KVM_SET_CLOCK_SCALE: { 243 | ret = s2e_kvm_set_clock_scale_ptr(fd, (unsigned *)arg1); 244 | } break; 245 | #endif 246 | 247 | default: { 248 | #ifdef PERISCOPE_TRACE_KVM_IOCTL 249 | fprintf(stderr, "periscope: unknown KVM VM IOCTL %x\n", request); 250 | #endif 251 | ret = g_original_ioctl(fd, request, arg1); 252 | break; 253 | // exit(-1); 254 | } 255 | } 256 | 257 | return ret; 258 | } 259 | 260 | static int handle_kvm_vcpu_ioctl(int fd, int request, uint64_t arg1) { 261 | int ret = -1; 262 | switch ((uint32_t)request) { 263 | #if 1 264 | case KVM_GET_CLOCK: 265 | case KVM_SET_CPUID2: 266 | case KVM_SET_SIGNAL_MASK: 267 | /***********************************************/ 268 | // When the symbolic execution engine needs to take a system snapshot, 269 | // it must rely on the KVM client to save the device state. That client 270 | // will typically also save/restore the CPU state. We don't want the 271 | // client to do that, so in order to not modify the client too much, we 272 | // ignore the calls to register setters when they are done in the 273 | // context of device state snapshotting. 274 | case KVM_SET_REGS: 275 | case KVM_SET_FPU: 276 | case KVM_SET_SREGS: 277 | case KVM_SET_MSRS: 278 | case KVM_SET_MP_STATE: 279 | case KVM_GET_REGS: 280 | case KVM_GET_FPU: 281 | case KVM_GET_SREGS: 282 | case KVM_GET_MSRS: 283 | case KVM_GET_MP_STATE: 284 | case KVM_RUN: 285 | case KVM_INTERRUPT: 286 | case KVM_NMI: 287 | break; 288 | #else 289 | case KVM_GET_CLOCK: { 290 | ret = s2e_kvm_vcpu_get_clock(fd, (struct kvm_clock_data *)arg1); 291 | } break; 292 | 293 | case KVM_SET_CPUID2: { 294 | ret = s2e_kvm_vcpu_set_cpuid2(fd, (struct kvm_cpuid2 *)arg1); 295 | } break; 296 | 297 | case KVM_SET_SIGNAL_MASK: { 298 | ret = s2e_kvm_vcpu_set_signal_mask(fd, (struct kvm_signal_mask *)arg1); 299 | } break; 300 | 301 | /***********************************************/ 302 | // When the symbolic execution engine needs to take a system snapshot, 303 | // it must rely on the KVM client to save the device state. That client 304 | // will typically also save/restore the CPU state. We don't want the 305 | // client to do that, so in order to not modify the client too much, we 306 | // ignore the calls to register setters when they are done in the 307 | // context of device state snapshotting. 308 | case KVM_SET_REGS: { 309 | if (g_handling_dev_state) { 310 | ret = 0; 311 | } else { 312 | ret = s2e_kvm_vcpu_set_regs(fd, (struct kvm_regs *)arg1); 313 | } 314 | } break; 315 | 316 | case KVM_SET_FPU: { 317 | if (g_handling_dev_state) { 318 | ret = 0; 319 | } else { 320 | ret = s2e_kvm_vcpu_set_fpu(fd, (struct kvm_fpu *)arg1); 321 | } 322 | } break; 323 | 324 | case KVM_SET_SREGS: { 325 | if (g_handling_dev_state) { 326 | ret = 0; 327 | } else { 328 | ret = s2e_kvm_vcpu_set_sregs(fd, (struct kvm_sregs *)arg1); 329 | } 330 | } break; 331 | 332 | case KVM_SET_MSRS: { 333 | if (g_handling_dev_state) { 334 | ret = ((struct kvm_msrs *)arg1)->nmsrs; 335 | } else { 336 | ret = s2e_kvm_vcpu_set_msrs(fd, (struct kvm_msrs *)arg1); 337 | } 338 | } break; 339 | 340 | case KVM_SET_MP_STATE: { 341 | if (g_handling_dev_state) { 342 | ret = 0; 343 | } else { 344 | ret = s2e_kvm_vcpu_set_mp_state(fd, (struct kvm_mp_state *)arg1); 345 | } 346 | } break; 347 | /***********************************************/ 348 | case KVM_GET_REGS: { 349 | if (g_handling_dev_state) { 350 | // Poison the returned registers to make sure we don't use 351 | // it again by accident. We can't just fail the call because 352 | // the client needs it to save the cpu state (that we ignore). 353 | memset((void *)arg1, 0xff, sizeof(struct kvm_regs)); 354 | ret = 0; 355 | } else { 356 | ret = s2e_kvm_vcpu_get_regs(fd, (struct kvm_regs *)arg1); 357 | } 358 | } break; 359 | 360 | case KVM_GET_FPU: { 361 | ret = s2e_kvm_vcpu_get_fpu(fd, (struct kvm_fpu *)arg1); 362 | } break; 363 | 364 | case KVM_GET_SREGS: { 365 | ret = s2e_kvm_vcpu_get_sregs(fd, (struct kvm_sregs *)arg1); 366 | } break; 367 | 368 | case KVM_GET_MSRS: { 369 | ret = s2e_kvm_vcpu_get_msrs(fd, (struct kvm_msrs *)arg1); 370 | } break; 371 | 372 | case KVM_GET_MP_STATE: { 373 | ret = s2e_kvm_vcpu_get_mp_state(fd, (struct kvm_mp_state *)arg1); 374 | } break; 375 | 376 | /***********************************************/ 377 | case KVM_RUN: { 378 | return s2e_kvm_vcpu_run(fd); 379 | } break; 380 | 381 | case KVM_INTERRUPT: { 382 | ret = s2e_kvm_vcpu_interrupt(fd, (struct kvm_interrupt *)arg1); 383 | } break; 384 | 385 | case KVM_NMI: { 386 | ret = s2e_kvm_vcpu_nmi(fd); 387 | } break; 388 | #endif 389 | default: { 390 | #ifdef PERISCOPE_TRACE_KVM_IOCTL 391 | fprintf(stderr, 392 | "periscope: unknown KVM VCPU IOCTL vcpu %d request=%#x " 393 | "arg=%#" PRIx64 " ret=%#x\n", 394 | fd, request, arg1, ret); 395 | #endif 396 | ret = g_original_ioctl(fd, request, arg1); 397 | break; 398 | // exit(-1); 399 | } 400 | } 401 | 402 | return ret; 403 | } 404 | 405 | ioctl_t g_original_ioctl; 406 | int ioctl(int fd, int request, uint64_t arg1) { 407 | int ret = -1; 408 | 409 | if (g_trace) { 410 | if (fd == g_kvm_fd) { 411 | // printf("ioctl %d request=%#x arg=%#"PRIx64" ret=%#x\n", fd, 412 | // request, arg1, ret); 413 | ret = handle_kvm_ioctl_trace(fd, request, arg1); 414 | } else if (fd == g_kvm_vm_fd) { 415 | // printf("ioctl vm %d request=%#x arg=%#"PRIx64" ret=%#x\n", fd, 416 | // request, arg1, ret); 417 | ret = handle_kvm_vm_ioctl_trace(fd, request, arg1); 418 | } else if (fd == g_kvm_vcpu_fd) { 419 | ret = handle_kvm_vcpu_ioctl_trace(fd, request, arg1); 420 | } else { 421 | // printf("ioctl on %d\n", fd); 422 | ret = g_original_ioctl(fd, request, arg1); 423 | } 424 | } else { 425 | if (fd == g_kvm_fd) { 426 | // printf("ioctl %d request=%#x arg=%#"PRIx64" ret=%#x\n", fd, 427 | // request, arg1, ret); 428 | ret = handle_kvm_ioctl(fd, request, arg1); 429 | } else if (fd == g_kvm_vm_fd) { 430 | // printf("ioctl vm %d request=%#x arg=%#"PRIx64" ret=%#x\n", fd, 431 | // request, arg1, ret); 432 | ret = handle_kvm_vm_ioctl(fd, request, arg1); 433 | } else if (fd == g_kvm_vcpu_fd) { 434 | ret = handle_kvm_vcpu_ioctl(fd, request, arg1); 435 | } else { 436 | // printf("ioctl on %d\n", fd); 437 | ret = g_original_ioctl(fd, request, arg1); 438 | } 439 | } 440 | 441 | return ret; 442 | } 443 | 444 | static poll_t s_original_poll; 445 | int poll(struct pollfd *fds, nfds_t nfds, int timeout) { 446 | // TODO: do we actually have to request exit from here? 447 | return s_original_poll(fds, nfds, timeout); 448 | } 449 | 450 | static select_t s_original_select; 451 | int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, 452 | struct timeval *timeout) { 453 | int ret = s_original_select(nfds, readfds, writefds, exceptfds, timeout); 454 | #if 0 455 | s2e_kvm_request_exit(); 456 | #endif 457 | return ret; 458 | } 459 | 460 | static exit_t s_original_exit; 461 | void exit(int code) { 462 | printf("Exiting with code=%d...\n", code); 463 | s_original_exit(code); 464 | #if 0 465 | s2e_kvm_request_process_exit(s_original_exit, code); 466 | #endif 467 | } 468 | 469 | #undef mmap 470 | 471 | static mmap_t s_original_mmap; 472 | void *mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset) { 473 | if (fd < 0 || (fd != g_kvm_vcpu_fd)) { 474 | return s_original_mmap(addr, len, prot, flags, fd, offset); 475 | } 476 | 477 | #if 0 478 | int real_size = s2e_kvm_get_vcpu_mmap_size(); 479 | assert(real_size == len); 480 | #endif 481 | assert(g_kvm_vcpu_buffer); 482 | 483 | return g_kvm_vcpu_buffer; 484 | } 485 | 486 | static mmap_t s_original_mmap64; 487 | void *mmap64(void *addr, size_t len, int prot, int flags, int fd, 488 | off_t offset) { 489 | if (fd < 0 || (fd != g_kvm_vcpu_fd)) { 490 | return s_original_mmap64(addr, len, prot, flags, fd, offset); 491 | } 492 | 493 | #if 0 494 | int real_size = s2e_kvm_get_vcpu_mmap_size(); 495 | assert(real_size == len); 496 | #endif 497 | assert(g_kvm_vcpu_buffer); 498 | 499 | return g_kvm_vcpu_buffer; 500 | } 501 | 502 | static dup_t s_original_dup; 503 | int dup(int fd) { 504 | if (fd == g_kvm_vcpu_fd) { 505 | // This should work most of the time, but may break if the client 506 | // assumes that the returned fd must be different. 507 | return g_kvm_vcpu_fd; 508 | } 509 | 510 | return s_original_dup(fd); 511 | } 512 | 513 | static madvise_t s_original_madvise; 514 | int madvise(void *addr, size_t len, int advice) { 515 | if (advice & MADV_DONTFORK) { 516 | // We must fork all memory for multi-core more 517 | advice &= ~MADV_DONTFORK; 518 | } 519 | 520 | if (!advice) { 521 | return 0; 522 | } 523 | 524 | return s_original_madvise(addr, len, advice); 525 | } 526 | 527 | /// 528 | /// \brief check_kvm_switch verifies that KVM mode is enabled. 529 | /// 530 | /// It's a common mistake to preload this library but forget the --enable-kvm 531 | /// switch 532 | /// 533 | /// \param argc command line arg count 534 | /// \param argv command line arguments 535 | /// \return true if kvm switch is found 536 | /// 537 | static bool check_kvm_switch(int argc, char **argv) { 538 | for (int i = 0; i < argc; ++i) { 539 | if (strstr(argv[i], "-enable-kvm")) { 540 | return true; 541 | } 542 | } 543 | 544 | return false; 545 | } 546 | 547 | #define MAX_SOCKET_PATH_STRING_SIZE 256 548 | 549 | char monitor_socket_file[MAX_SOCKET_PATH_STRING_SIZE] = {0}; 550 | 551 | #if 0 552 | static void check_monitor_socket(int argc, char **argv) { 553 | for (int i = 0; i < argc; ++i) { 554 | if (strstr(argv[i], "-monitor") && (i + 1 < argc)) { 555 | char buf[MAX_SOCKET_PATH_STRING_SIZE]; 556 | 557 | // TODO: more thorough length check 558 | strncpy(buf, argv[i + 1], sizeof(buf)); 559 | 560 | char *tok = strtok(buf, ","); 561 | if (tok) { 562 | tok = strtok(buf, ":"); 563 | if (tok) { 564 | strncpy(monitor_socket_file, strtok(NULL, ""), 565 | sizeof(monitor_socket_file)); 566 | break; 567 | } 568 | } 569 | } 570 | } 571 | } 572 | #endif 573 | 574 | // **************************** 575 | // Overriding __llibc_start_main 576 | // **************************** 577 | 578 | // The type of __libc_start_main 579 | typedef int (*T_libc_start_main)(int *(main)(int, char **, char **), int argc, 580 | char **ubp_av, void (*init)(void), 581 | void (*fini)(void), void (*rtld_fini)(void), 582 | void(*stack_end)); 583 | 584 | int __libc_start_main(int *(main)(int, char **, char **), int argc, 585 | char **ubp_av, void (*init)(void), void (*fini)(void), 586 | void (*rtld_fini)(void), void *stack_end) 587 | __attribute__((noreturn)); 588 | 589 | int __libc_start_main(int *(main)(int, char **, char **), int argc, 590 | char **ubp_av, void (*init)(void), void (*fini)(void), 591 | void (*rtld_fini)(void), void *stack_end) { 592 | 593 | T_libc_start_main orig_libc_start_main = 594 | (T_libc_start_main)dlsym(RTLD_NEXT, "__libc_start_main"); 595 | s_original_open = (open_t)dlsym(RTLD_NEXT, "open64"); 596 | s_original_close = (close_t)dlsym(RTLD_NEXT, "close64"); 597 | g_original_ioctl = (ioctl_t)dlsym(RTLD_NEXT, "ioctl"); 598 | s_original_write = (write_t)dlsym(RTLD_NEXT, "write"); 599 | s_original_select = (select_t)dlsym(RTLD_NEXT, "select"); 600 | s_original_poll = (poll_t)dlsym(RTLD_NEXT, "poll"); 601 | s_original_exit = (exit_t)dlsym(RTLD_NEXT, "exit"); 602 | s_original_mmap = (mmap_t)dlsym(RTLD_NEXT, "mmap"); 603 | s_original_mmap64 = (mmap_t)dlsym(RTLD_NEXT, "mmap64"); 604 | s_original_madvise = (madvise_t)dlsym(RTLD_NEXT, "madvise"); 605 | s_original_dup = (dup_t)dlsym(RTLD_NEXT, "dup"); 606 | 607 | // Hack when we are called from gdb or through a shell command 608 | if (strstr(ubp_av[0], "bash")) { 609 | (*orig_libc_start_main)(main, argc, ubp_av, init, fini, rtld_fini, 610 | stack_end); 611 | exit(-1); 612 | } 613 | 614 | // This library might spawn other processes. This will fail if we preload 615 | // this library for these processes, so we must remove this environment 616 | // variable. 617 | unsetenv("LD_PRELOAD"); 618 | 619 | // When libperiscope is used with qemu, verify that enable-kvm switch has 620 | // been specified. 621 | if (strstr(ubp_av[0], "qemu") && !check_kvm_switch(argc, ubp_av)) { 622 | printf("Please use -enable-kvm switch before starting QEMU\n"); 623 | exit(-1); 624 | } 625 | 626 | char **new_argv = ubp_av; 627 | 628 | int agent_id = -1; 629 | char *agent_str = getenv("__PERISCOPE_GUEST_AGENT_ID"); 630 | if (agent_str) { 631 | sscanf(agent_str, "%d", &agent_id); 632 | } else { 633 | printf("periscope: agent id not given\n"); 634 | } 635 | 636 | int fuzzer_id = -1; 637 | char *fuzzer_str = getenv("SYZ_FUZZER_INDEX"); 638 | if (fuzzer_str) { 639 | sscanf(fuzzer_str, "%d", &fuzzer_id); 640 | } else { 641 | printf("periscope: fuzzer id not given\n"); 642 | } 643 | 644 | /* 645 | * Syzkaller 646 | */ 647 | char *syz_fuzzer_path = getenv("SYZ_FUZZER_PATH"); 648 | char *syz_fuzzer_argv = getenv("SYZ_FUZZER_ARGV"); 649 | char *syz_fuzzer_executor = getenv("SYZ_FUZZER_EXECUTOR"); 650 | char *syz_fuzzer_index = getenv("SYZ_FUZZER_INDEX"); 651 | if (syz_fuzzer_path && syz_fuzzer_argv && syz_fuzzer_executor && 652 | syz_fuzzer_index) { 653 | int out_st_pipe, out_ctl_pipe, shm_id = -1; 654 | 655 | // TODO(dokyungs): check if 656 | // char *syz_fuzzer_debug = getenv("SYZ_FUZZER_DEBUG"); 657 | char fifo_base[50], fifo_out[50]; 658 | char fifo_in[50]; 659 | sprintf(fifo_base, "/tmp/serial-err-vm%s", syz_fuzzer_index); 660 | sprintf(fifo_in, "%s.in", fifo_base); 661 | remove(fifo_in); 662 | mkfifo(fifo_in, 0666); 663 | sprintf(fifo_out, "%s.out", fifo_base); 664 | remove(fifo_out); 665 | mkfifo(fifo_out, 0666); 666 | 667 | periscope_init_syz_fuzzer( 668 | ubp_av, syz_fuzzer_path, syz_fuzzer_argv, syz_fuzzer_executor, 669 | syz_fuzzer_index, &out_st_pipe, &out_ctl_pipe, &shm_id, fifo_out); 670 | int old_argc = argc; 671 | int new_argc = argc; 672 | new_argc += 2; // fuzzer 673 | 674 | // stderr pipe 675 | new_argc += 6; 676 | 677 | new_argv = (char **)malloc(sizeof(char *) * new_argc); 678 | memcpy(new_argv, ubp_av, sizeof(char *) * old_argc); 679 | 680 | char *mgr_pipe = getenv("SYZ_MANAGER_PIPE"); 681 | 682 | char *chkpt_pool_size = getenv("__PERISCOPE_CHKPT_POOL_SIZE"); 683 | 684 | new_argv[argc++] = "-device"; 685 | char fuzzer[200]; 686 | sprintf(fuzzer, 687 | "fuzzer,uri=%s:%d,st_pipe=%d,ctl_pipe=%d,mgr_pipe=%s,shm_id=%d," 688 | "chkpt_pool_size=%s,%s,fuzzer_id=%d", 689 | "syzkaller", agent_id, out_st_pipe, out_ctl_pipe, mgr_pipe, 690 | shm_id, chkpt_pool_size, "hostmem1=mb1", fuzzer_id); 691 | new_argv[argc++] = fuzzer; 692 | 693 | // TODO(dokyungs) 694 | new_argv[argc++] = "-device"; 695 | new_argv[argc++] = "virtio-serial-pci,id=virtio-serial2,ioeventfd=off"; 696 | new_argv[argc++] = "-chardev"; 697 | char err_pipe[100]; 698 | sprintf(err_pipe, "pipe,id=ch2,path=%s", fifo_base); 699 | new_argv[argc++] = err_pipe; 700 | new_argv[argc++] = "-device"; 701 | new_argv[argc++] = 702 | "virtserialport,bus=virtio-serial2.0,chardev=ch2,name=serial2"; 703 | 704 | for (int i = 0; i < new_argc; i++) { 705 | printf("%s ", new_argv[i]); 706 | } 707 | printf("\n"); 708 | 709 | if (argc != new_argc) { 710 | printf("periscope: arg handling error\n"); 711 | exit(1); 712 | } 713 | 714 | argc = new_argc; 715 | 716 | goto start_main; 717 | } else { 718 | // error: invalid arg 719 | } 720 | 721 | int out_st_pipe, out_ctl_pipe = -1; 722 | periscope_pre_qemu_init(&out_st_pipe, &out_ctl_pipe); 723 | 724 | #if 0 725 | check_monitor_socket(argc, ubp_av); 726 | #endif 727 | 728 | #define QEMU_FUZZER_IO_CHANNEL 729 | //#undef QEMU_FUZZER_IO_CHANNEL 730 | #ifdef QEMU_FUZZER_IO_CHANNEL 731 | /* 732 | * AFL 733 | */ 734 | int shm_id = -1; 735 | char *shm_str = getenv("__AFL_SHM_ID"); 736 | if (shm_str) { 737 | sscanf(shm_str, "%d", &shm_id); 738 | } 739 | 740 | if (out_st_pipe > -1 && out_ctl_pipe > -1) { 741 | char *chkpt_pool_size = getenv("__PERISCOPE_CHKPT_POOL_SIZE"); 742 | 743 | argc += 2; 744 | 745 | new_argv = (char **)malloc(sizeof(char *) * argc); 746 | memcpy(new_argv, ubp_av, sizeof(char *) * argc - 2); 747 | new_argv[argc - 2] = "-device"; 748 | char fuzzer[200]; 749 | sprintf(fuzzer, 750 | "fuzzer,uri=%s:%d,st_pipe=%d,ctl_pipe=%d,shm_id=%d," 751 | "chkpt_pool_size=%s,fuzzer_id=%d", 752 | "afl", agent_id, out_st_pipe, out_ctl_pipe, shm_id, 753 | chkpt_pool_size, fuzzer_id); 754 | new_argv[argc - 1] = fuzzer; 755 | } 756 | #endif 757 | 758 | #if 0 759 | if (!init_ram_size(argc, ubp_av)) { 760 | exit(-1); 761 | } 762 | #endif 763 | start_main: 764 | 765 | (*orig_libc_start_main)(main, argc, new_argv, init, fini, rtld_fini, 766 | stack_end); 767 | 768 | exit(1); // This is never reached 769 | } 770 | -------------------------------------------------------------------------------- /libagamotto/src/kvm.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "kvm.h" 5 | 6 | static const int MAX_MEMORY_SLOTS = 32; 7 | 8 | struct kvm_run *g_kvm_vcpu_buffer; 9 | 10 | int kvm_get_api_version(void) { 11 | return KVM_API_VERSION; // 12 on Ubuntu 18.04 12 | } 13 | 14 | int kvm_check_extension(int kvm_fd, int capability) { 15 | return g_original_ioctl(kvm_fd, KVM_CHECK_EXTENSION, capability); 16 | 17 | switch (capability) { 18 | case KVM_CAP_NR_MEMSLOTS: { 19 | return MAX_MEMORY_SLOTS; 20 | } break; 21 | 22 | case KVM_CAP_JOIN_MEMORY_REGIONS_WORKS: 23 | case KVM_CAP_MP_STATE: 24 | case KVM_CAP_EXT_CPUID: 25 | case KVM_CAP_SET_TSS_ADDR: 26 | case KVM_CAP_DESTROY_MEMORY_REGION_WORKS: 27 | case KVM_CAP_USER_MEMORY: 28 | case KVM_CAP_NR_VCPUS: 29 | case KVM_CAP_MAX_VCPUS: 30 | return 1; 31 | 32 | default: 33 | #ifdef KVM_DEBUG_INTERFACE 34 | printf("Unsupported cap %x\n", capability); 35 | #endif 36 | return -1; 37 | } 38 | } 39 | 40 | int kvm_vm_ioctl_ioeventfd(int vm_fd, struct kvm_ioeventfd *event) { 41 | int ret = -1; 42 | return ret; 43 | } 44 | 45 | int kvm_vm_ioctl_register_coalesced_mmio(int vm_fd, 46 | struct kvm_coalesced_mmio_zone *zone) { 47 | int ret = -1; 48 | return ret; 49 | } 50 | 51 | int kvm_vm_ioctl_unregister_coalesced_mmio( 52 | int vm_fd, struct kvm_coalesced_mmio_zone *zone) { 53 | int ret = -1; 54 | return ret; 55 | } 56 | 57 | int kvm_vm_ioctl_assign_pci_device(int vm_fd, 58 | struct kvm_assigned_pci_dev *dev) { 59 | int ret = -1; 60 | return ret; 61 | } 62 | 63 | int handle_kvm_ioctl_trace(int fd, int request, uint64_t arg) { 64 | int ret = -1; 65 | return ret; 66 | } 67 | 68 | int handle_kvm_vm_ioctl_trace(int fd, int request, uint64_t arg) { 69 | int ret = -1; 70 | return ret; 71 | } 72 | 73 | int handle_kvm_vcpu_ioctl_trace(int fd, int request, uint64_t arg) { 74 | int ret = -1; 75 | return ret; 76 | } 77 | -------------------------------------------------------------------------------- /libagamotto/src/kvm.h: -------------------------------------------------------------------------------- 1 | // This file contains code derived from libs2e code 2 | 3 | #ifndef LIBAGAMOTTO_KVM_H 4 | #define LIBAGAMOTTO_KVM_H 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | #define KVM_DEBUG_INTERFACE 1 18 | 19 | extern struct kvm_run *g_kvm_vcpu_buffer; 20 | 21 | typedef int (*open_t)(const char *pathname, int flags, mode_t mode); 22 | typedef int (*close_t)(int fd); 23 | typedef int (*ioctl_t)(int d, int request, ...); 24 | typedef ssize_t (*write_t)(int fd, const void *buf, size_t count); 25 | typedef int (*dup_t)(int fd); 26 | typedef int (*poll_t)(struct pollfd *fds, nfds_t nfds, int timeout); 27 | typedef int (*select_t)(int nfds, fd_set *readfds, fd_set *writefds, 28 | fd_set *exceptfds, struct timeval *timeout); 29 | 30 | typedef void (*exit_t)(int ret) __attribute__((__noreturn__)); 31 | 32 | typedef void *(*mmap_t)(void *addr, size_t len, int prot, int flags, int fd, 33 | off_t offset); 34 | typedef int (*madvise_t)(void *addr, size_t len, int advice); 35 | 36 | extern ioctl_t g_original_ioctl; 37 | 38 | int kvm_get_api_version(void); 39 | int kvm_check_extension(int kvm_fd, int capability); 40 | int kvm_create_vm(int kvm_fd); 41 | 42 | int kvm_vm_ioctl_ioeventfd(int vm_fd, struct kvm_ioeventfd *event); 43 | int kvm_vm_ioctl_register_coalesced_mmio(int vm_fd, 44 | struct kvm_coalesced_mmio_zone *zone); 45 | int kvm_vm_ioctl_unregister_coalesced_mmio( 46 | int vm_fd, struct kvm_coalesced_mmio_zone *zone); 47 | int kvm_vm_ioctl_assign_pci_device(int vm_fd, struct kvm_assigned_pci_dev *dev); 48 | 49 | int handle_kvm_ioctl_trace(int fd, int request, uint64_t arg); 50 | int handle_kvm_vm_ioctl_trace(int fd, int request, uint64_t arg); 51 | int handle_kvm_vcpu_ioctl_trace(int fd, int request, uint64_t arg); 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /libagamotto/src/snapshot.c: -------------------------------------------------------------------------------- 1 | #include "snapshot.h" 2 | 3 | int vmfuzzer_savevm(int parent, const uint8_t *bytes) { 4 | int ret = -1; 5 | 6 | return ret; 7 | } 8 | 9 | int vmfuzzer_loadvm(const uint8_t *bytes) { 10 | int ret = -1; 11 | 12 | return ret; 13 | } 14 | 15 | int vmfuzzer_purge_unused_snapshots() { 16 | int ret = -1; 17 | 18 | return ret; 19 | } 20 | -------------------------------------------------------------------------------- /libagamotto/src/snapshot.h: -------------------------------------------------------------------------------- 1 | // TODO: obsolete 2 | 3 | #ifndef LIBAGAMOTTO_SNAPSHOT_H 4 | #define LIBAGAMOTTO_SNAPSHOT_H 5 | 6 | #include 7 | 8 | #define MAX_SNAPSHOTS 1024 9 | #define MAX_SNAPSHOT_SIZE_TOTAL 512 // MiB 10 | #define MAX_SNAPSHOT_SIZE_EACH 1 // MiB 11 | 12 | // Probably maintain correspondence between input and snapshot. 13 | // Multiple inputs can point to a single snapshot. 14 | 15 | int vmfuzzer_savevm(int, const uint8_t *); 16 | 17 | int vmfuzzer_loadvm(const uint8_t *); 18 | 19 | int vmfuzzer_purge_unused_snapshots(); 20 | 21 | #endif -------------------------------------------------------------------------------- /scripts/build-image.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [ $# -ne 2 ]; then 4 | echo "Usage: $0 " >&2 5 | exit 1 6 | fi 7 | 8 | OUT_IMG=$2 9 | DIR=$1 10 | 11 | if [ -f $OUT_IMG ]; then 12 | echo "$OUT_IMG already exists." >&2 13 | exit 1 14 | fi 15 | 16 | if [ ! -d $DIR ]; then 17 | echo "$DIR does not exist." >&2 18 | exit 1 19 | fi 20 | 21 | set -eux 22 | 23 | dd if=/dev/zero of=$OUT_IMG bs=1M seek=2047 count=1 24 | sudo mkfs.ext4 -F $OUT_IMG 25 | sudo mkdir -p /mnt/$DIR 26 | sudo mount -o loop $OUT_IMG /mnt/$DIR 27 | sudo cp -a $DIR/. /mnt/$DIR/. 28 | sudo umount /mnt/$DIR 29 | -------------------------------------------------------------------------------- /scripts/build-linux-guest.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | GUEST_CONFIGS=( 4 | "aqtion" 5 | "rtl8139" 6 | "stmmac" 7 | "snic" 8 | "usb" 9 | ) 10 | 11 | if [ $# -lt 2 ] || [ $# -gt 3 ]; then 12 | echo "Usage: $0 []" >&2 13 | echo " CONFIG: all ${GUEST_CONFIGS[*]}" >&2 14 | exit 1 15 | fi 16 | 17 | if [ $1 != "all" ]; then 18 | GUEST_CONFIGS=($1) 19 | fi 20 | 21 | KERNEL_SRC_DIR=$2 22 | 23 | if [ ! -d $KERNEL_SRC_DIR ]; then 24 | echo $KERNEL_SRC_DIR does not exist. 25 | exit 1 26 | fi 27 | 28 | if [ $# -eq 3 ]; then 29 | IMAGE_OUT_DIR=$3 30 | else 31 | BUILD_DIR=$(dirname $0)/../build 32 | if [ ! -d $BUILD_DIR ]; then 33 | echo $BUILD_DIR does not exist. 34 | exit 1 35 | fi 36 | 37 | IMAGE_OUT_DIR=$BUILD_DIR/guest/linux/image 38 | 39 | IMAGE_OUT_DIR=$PWD/$IMAGE_OUT_DIR 40 | 41 | if [ ! -d $IMAGE_OUT_DIR ]; then 42 | echo Creating $IMAGE_OUT_DIR 43 | mkdir -p $IMAGE_OUT_DIR 44 | fi 45 | fi 46 | 47 | INSTALL_MOD_PATH=$IMAGE_OUT_DIR/modules 48 | 49 | pushd $KERNEL_SRC_DIR 50 | 51 | set -eux 52 | 53 | for config in ${GUEST_CONFIGS[*]}; do 54 | defconfig=agamotto_${config}_defconfig 55 | 56 | if [ -f arch/x86/configs/$defconfig ]; then 57 | echo Compiling $defconfig... 58 | make $defconfig O=$IMAGE_OUT_DIR/$config 59 | make -j40 O=$IMAGE_OUT_DIR/$config 60 | 61 | if [ $INSTALL_MOD_PATH != "" ]; then 62 | pushd $IMAGE_OUT_DIR/$config 63 | make modules_install INSTALL_MOD_PATH=$INSTALL_MOD_PATH 64 | popd 65 | fi 66 | else 67 | echo $defconfig does not exist. Skipping... 68 | fi 69 | done 70 | 71 | popd 72 | -------------------------------------------------------------------------------- /scripts/copy-modules.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import argparse 4 | from string import Template 5 | import os 6 | import fuzz 7 | import subprocess 8 | 9 | 10 | devices = fuzz.devices 11 | 12 | 13 | LINUX_AGENT_TMPL_SH = "../guest/linux/agents/agent.sh" 14 | LINUX_AGENT_SH = "../guest/linux/agents/generated/agent.sh" 15 | LINUX_AGENT_DEV_TMPL_SH = "../guest/linux/agents/agent-dev-prog.sh" 16 | LINUX_AGENT_DEV_DEBUG_TMPL_SH = "../guest/linux/agents/agent-dev-debug.sh" 17 | LINUX_AGENT_DEV_SH = "../guest/linux/agents/generated/agent-${dev}-${prog}.sh" 18 | 19 | 20 | def get_executable_path(os_, prog): 21 | prog_dir = "" 22 | if os_ == "linux": 23 | prog_dir = fuzz.LINUX_BUILD_DIR 24 | elif os_ == "windows": 25 | prog_dir = fuzz.WINDOWS_BUILD_DIR 26 | else: 27 | raise Exception("unknown OS %s" % (os_)) 28 | 29 | if prog.startswith("prog"): 30 | prog_dir = os.path.join(prog_dir, "progs") 31 | elif prog.startswith("trace"): 32 | prog_dir = os.path.join(prog_dir, "traces") 33 | else: 34 | raise Exception("unknown type %s" % (prog)) 35 | 36 | return os.path.join(prog_dir, prog) 37 | 38 | 39 | def setup_blacklist(os_): 40 | if os_ != "linux": 41 | return 42 | blacklist = "%s/blacklist.conf" % fuzz.LINUX_BUILD_DIR 43 | with open(blacklist, "w") as fd: 44 | for dev in devices: 45 | if "module" not in devices[dev] or not devices[dev]["module"]: 46 | continue 47 | module_ko = os.path.basename(devices[dev]["module"]) 48 | module_noext = os.path.splitext(module_ko)[0] 49 | fd.write("blacklist %s\n" % module_noext) 50 | 51 | 52 | def setup_guest_agent(os_): 53 | generated_dir = "../guest/linux/agents/generated" 54 | 55 | if not os.path.exists(generated_dir): 56 | os.mkdir(generated_dir) 57 | 58 | all_agents = fuzz.enumerate_guest_agents(os_) 59 | 60 | with open(LINUX_AGENT_TMPL_SH, "r") as f_in: 61 | with open(LINUX_AGENT_SH, "w") as f_out: 62 | sh = Template(f_in.read()).substitute( 63 | AGENTS="\n ".join( 64 | ["\"%s.sh\" # %d" % (a, all_agents.index(a)) for a in all_agents]), 65 | ) 66 | f_out.write(sh) 67 | 68 | for agent in all_agents: 69 | (_, dev, prog) = agent.split("-") 70 | 71 | if "image" not in devices[dev]: 72 | continue 73 | 74 | if "module" not in devices[dev]: 75 | continue 76 | 77 | agent = Template(LINUX_AGENT_DEV_SH).substitute( 78 | dev=dev, 79 | prog=prog, 80 | ) 81 | 82 | with open(LINUX_AGENT_DEV_TMPL_SH, "r") as f_in, open(agent, "w") as f_out: 83 | sh = Template(f_in.read()).substitute( 84 | image=devices[dev]["image"], 85 | skip_root_chkpt="true" if prog.endswith( 86 | "debug") or prog == "prog99" or prog == "prog98" or prog == "prog80" or prog == "prog81" \ 87 | else "false", 88 | skip_modprobe="false" if devices[dev]["module"] and not (prog == "prog80" or prog == "prog81" ) \ 89 | else "true", 90 | module=os.path.basename( 91 | devices[dev]["module"]).split(".")[0] if devices[dev]["module"] else "", 92 | module_relpath=devices[dev]["module"] if devices[dev]["module"] else "", 93 | prog=prog, 94 | ) 95 | f_out.write(sh) 96 | 97 | 98 | def copy_modules(mod, img, script): 99 | args = list() 100 | 101 | args = ["./%s" % ("copy-modules.sh")] 102 | args.append(mod) 103 | args.append(img) 104 | args.append(script) 105 | 106 | proc = subprocess.Popen( 107 | args, cwd=os.path.abspath(os.path.dirname("copy-modules.sh"))) 108 | 109 | proc.communicate() 110 | 111 | if proc.wait() != 0: 112 | raise Exception("proc exited with errors.") 113 | 114 | 115 | def add_arguments(parser): 116 | subparsers = parser.add_subparsers(dest="device") 117 | subparsers.required = True 118 | 119 | devparsers = list() 120 | 121 | devparsers.append(subparsers.add_parser("all")) 122 | 123 | for dev in devices: 124 | devparsers.append(subparsers.add_parser(dev)) 125 | 126 | for devparser in devparsers: 127 | devparser.add_argument( 128 | "-m", "--modules-dir", dest="modules_dir", 129 | help="default: %s" % (fuzz.default_modules_dir()), 130 | ) 131 | devparser.add_argument( 132 | "-d", "--drive-image-path", dest="img_path", 133 | help="", 134 | required=True, 135 | ) 136 | 137 | 138 | def parse_arguments(args): 139 | modules_dir = args.modules_dir 140 | if not modules_dir: 141 | modules_dir = fuzz.default_modules_dir() 142 | 143 | if not os.path.exists(modules_dir): 144 | raise Exception("%s does not exist." % (modules_dir)) 145 | if not os.path.exists(args.img_path): 146 | raise Exception("%s does not exist." % (args.img_path)) 147 | 148 | devs = list() 149 | if args.device == "all": 150 | devs.extend(devices.keys()) 151 | else: 152 | devs.append(args.device) 153 | 154 | setup_guest_agent("linux") 155 | setup_blacklist("linux") 156 | 157 | copy_modules(modules_dir, args.img_path, LINUX_AGENT_SH) 158 | 159 | 160 | def check_dependencies(): 161 | files_to_check = [ 162 | "copy-modules.sh", 163 | LINUX_AGENT_TMPL_SH, 164 | LINUX_AGENT_DEV_TMPL_SH, 165 | ] 166 | for f in files_to_check: 167 | if not os.path.exists(f): 168 | raise Exception("File '%s' does not exist." % (f)) 169 | 170 | 171 | def main(): 172 | check_dependencies() 173 | parser = argparse.ArgumentParser() 174 | add_arguments(parser) 175 | args = parser.parse_args() 176 | parse_arguments(args) 177 | 178 | 179 | if __name__ == "__main__": 180 | main() 181 | -------------------------------------------------------------------------------- /scripts/copy-modules.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [ $# -ne 3 ]; then 4 | echo "Usage: $0 " >&2 5 | exit 1 6 | fi 7 | 8 | MOD_DIR=$1 9 | IMG_NAME=$2 10 | AGENT_SCRIPT=$3 11 | 12 | if [ ! -f $IMG_NAME ]; then 13 | echo "$IMG_NAME does not exist." >&2 14 | exit 1 15 | fi 16 | 17 | if [ ! -d $MOD_DIR ]; then 18 | echo "$MOD_DIR does not exist." >&2 19 | exit 1 20 | fi 21 | 22 | if [ ! -f $AGENT_SCRIPT ]; then 23 | echo "$AGENT_SCRIPT does not exist." >&2 24 | exit 1 25 | fi 26 | 27 | set -eux 28 | 29 | MNT_DIR=/mnt/${IMG_NAME%.*} 30 | AGENT_SCRIPT_NAME=$(basename $AGENT_SCRIPT) 31 | 32 | echo "MOUNT_DIR $MNT_DIR" 33 | echo "AGENT_SCRIPT_NAME $AGENT_SCRIPT_NAME" 34 | sudo mkdir -p $MNT_DIR 35 | sudo mount -o loop $IMG_NAME $MNT_DIR 36 | sudo cp -rd $MOD_DIR/lib/modules/* $MNT_DIR/lib/modules/ 37 | sudo cp $AGENT_SCRIPT $MNT_DIR/root/ 38 | sudo cp ../guest/linux/agents/generated/agent-* $MNT_DIR/root/ 39 | sudo cp ../guest/linux/agents/agent-debug.sh $MNT_DIR/root/debug 40 | sudo chmod +x $MNT_DIR/root/debug 41 | sudo cp ../build/guest/linux/blacklist.conf $MNT_DIR/etc/modprobe.d/ 42 | sudo cp ../build/guest/linux/agents/agent-* $MNT_DIR/root/ 43 | sudo cp -p ../build/guest/linux/progs/prog* $MNT_DIR/root/ 44 | #sudo cp ../build/guest/linux/traces/trace* $MNT_DIR/root/ 45 | if [ -d $GOPATH ]; then 46 | sudo gcc $GOPATH/src/github.com/google/syzkaller/tools/syz-usbgen/keyboard.c -o $MNT_DIR/syz-usbgen-keyboard 47 | sudo cp -p $GOPATH/src/github.com/google/syzkaller/bin/linux_amd64/syz-* $MNT_DIR/ 48 | fi 49 | sudo cp -p ../build/guest/linux/syz/syz-executor $MNT_DIR/syz-executor.debug 50 | sudo chmod +x $MNT_DIR/root/$AGENT_SCRIPT_NAME 51 | sudo find $MNT_DIR/root -name "agent-*.sh" |sudo xargs chmod +x 52 | #sudo cp $RC_LOCAL /mnt/$MNT_DIR/etc/rc.local 53 | echo "#!/bin/sh -e" | sudo tee $MNT_DIR/etc/rc.local 54 | echo "nohup /root/$AGENT_SCRIPT_NAME" | sudo tee -a $MNT_DIR/etc/rc.local 55 | sudo chmod +x $MNT_DIR/etc/rc.local 56 | sudo umount $MNT_DIR 57 | -------------------------------------------------------------------------------- /scripts/create-debian-image.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # This file is a modified version of create-image.sh found in the syzkaller repository. 4 | # 5 | 6 | set -eux 7 | 8 | # Create a minimal Debian distribution in a directory. 9 | DIR=chroot 10 | 11 | # Variables affected by options 12 | RELEASE=stretch 13 | FEATURE=minimal 14 | 15 | display_help() { 16 | echo "Usage: $0 [option...] " >&2 17 | echo 18 | echo " -d, --distribution Set on which debian distribution to create" 19 | echo " -m, --modules Directory of linux kernel modules (make modules_install INSTALL_MOD_PATH=<..>" 20 | echo " -f, --feature Check what packages to install in the image, options are minimal, full" 21 | echo " -h, --help Display help message" 22 | echo 23 | } 24 | 25 | while true; do 26 | if [ $# -eq 0 ];then 27 | echo $# 28 | break 29 | fi 30 | case "$1" in 31 | -h | --help) 32 | display_help 33 | exit 0 34 | ;; 35 | -d | --distribution) 36 | RELEASE=$2 37 | shift 2 38 | ;; 39 | -f | --feature) 40 | FEATURE=$2 41 | shift 2 42 | ;; 43 | -*) 44 | echo "Error: Unknown option: $1" >&2 45 | exit 1 46 | ;; 47 | *) # No more options 48 | break 49 | ;; 50 | esac 51 | done 52 | 53 | ADD_PACKAGE=",firmware-brcm80211,firmware-iwlwifi,firmware-atheros,firmware-qlogic,firmware-realtek,firmware-ralink,firmware-libertas,firmware-adi,firmware-misc-nonfree,firmware-linux,pciutils,net-tools,wireless-tools,wireless-regdb" 54 | 55 | IMAGE_NAME="$RELEASE" 56 | 57 | if [ $FEATURE = "full" ]; then 58 | ADD_PACKAGE=$ADD_PACKAGE",make,sysbench,git,vim,tmux,usbutils" 59 | fi 60 | 61 | ADD_PACKAGE=$ADD_PACKAGE",gdb" 62 | ADD_PACKAGE=$ADD_PACKAGE",lsof" 63 | ADD_PACKAGE=$ADD_PACKAGE",ethtool" 64 | ADD_PACKAGE=$ADD_PACKAGE",i2c-tools" 65 | ADD_PACKAGE=$ADD_PACKAGE",neard-tools" 66 | ADD_PACKAGE=$ADD_PACKAGE",usbutils" 67 | 68 | if [ -d $DIR ]; then 69 | echo $DIR already exists. 70 | exit 71 | fi 72 | 73 | mkdir -p $DIR 74 | sudo debootstrap --components=main,contrib,non-free --include=openssh-server,curl,tar,gcc,libc6-dev,time,strace,sudo,less,psmisc"$ADD_PACKAGE" $RELEASE $DIR 75 | 76 | # Set some defaults and enable promtless ssh to the machine for root. 77 | sudo sed -i '/^root/ { s/:x:/::/ }' $DIR/etc/passwd 78 | echo 'T0:23:respawn:/sbin/getty -L ttyS0 115200 vt100' | sudo tee -a $DIR/etc/inittab 79 | printf '\nauto eth0\niface eth0 inet dhcp\n' | sudo tee -a $DIR/etc/network/interfaces 80 | echo '/dev/root / ext4 defaults 0 0' | sudo tee -a $DIR/etc/fstab 81 | echo 'debugfs /sys/kernel/debug debugfs defaults 0 0' | sudo tee -a $DIR/etc/fstab 82 | echo 'securityfs /sys/kernel/security securityfs defaults 0 0' | sudo tee -a $DIR/etc/fstab 83 | #echo 'configfs /sys/kernel/config/ configfs defaults 0 0' | sudo tee -a $DIR/etc/fstab 84 | echo 'binfmt_misc /proc/sys/fs/binfmt_misc binfmt_misc defaults 0 0' | sudo tee -a $DIR/etc/fstab 85 | echo "kernel.printk = 7 4 1 3" | sudo tee -a $DIR/etc/sysctl.conf 86 | echo 'debug.exception-trace = 0' | sudo tee -a $DIR/etc/sysctl.conf 87 | echo "net.core.bpf_jit_enable = 1" | sudo tee -a $DIR/etc/sysctl.conf 88 | echo "net.core.bpf_jit_kallsyms = 1" | sudo tee -a $DIR/etc/sysctl.conf 89 | echo "net.core.bpf_jit_harden = 0" | sudo tee -a $DIR/etc/sysctl.conf 90 | echo "kernel.softlockup_all_cpu_backtrace = 1" | sudo tee -a $DIR/etc/sysctl.conf 91 | echo "kernel.kptr_restrict = 0" | sudo tee -a $DIR/etc/sysctl.conf 92 | echo "kernel.watchdog_thresh = 60" | sudo tee -a $DIR/etc/sysctl.conf 93 | echo "net.ipv4.ping_group_range = 0 65535" | sudo tee -a $DIR/etc/sysctl.conf 94 | echo -en "127.0.0.1\tlocalhost\n" | sudo tee $DIR/etc/hosts 95 | echo "nameserver 8.8.8.8" | sudo tee -a $DIR/etc/resolve.conf 96 | echo "agamotto" | sudo tee $DIR/etc/hostname 97 | ssh-keygen -f $IMAGE_NAME.id_rsa -t rsa -N '' 98 | sudo mkdir -p $DIR/root/.ssh/ 99 | sudo mkdir -p $DIR/lib/modules/ 100 | cat $IMAGE_NAME.id_rsa.pub | sudo tee $DIR/root/.ssh/authorized_keys 101 | 102 | # Build a disk image 103 | ./build-image.sh $DIR $IMAGE_NAME.img 104 | -------------------------------------------------------------------------------- /scripts/create-overlay-image.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import argparse 4 | import fuzz 5 | import os 6 | import subprocess 7 | 8 | 9 | devices = fuzz.devices 10 | 11 | 12 | def default_results_dir(): 13 | # /scripts 14 | dirname = os.path.dirname(os.path.realpath(__file__)) 15 | # / 16 | dirname = os.path.dirname(dirname) 17 | 18 | # /results 19 | dirname = os.path.join(dirname, "results") 20 | 21 | return os.path.abspath(dirname) 22 | 23 | 24 | def create_overlay_image(img_path, overlay_img_path): 25 | args = list() 26 | 27 | args = ["./%s" % ("create-overlay-image.sh")] 28 | args.append(img_path) 29 | args.append(overlay_img_path) 30 | 31 | proc = subprocess.Popen( 32 | args, cwd=os.path.abspath(os.path.dirname("create-overlay-image.sh"))) 33 | 34 | proc.communicate() 35 | 36 | if proc.wait() != 0: 37 | print("proc exited with errors.") 38 | 39 | 40 | def _check_dependencies(): 41 | files_to_check = [ 42 | "create-overlay-image.sh", 43 | ] 44 | for f in files_to_check: 45 | if not os.path.exists(f): 46 | raise Exception("File '%s' does not exist." % (f)) 47 | return 48 | 49 | 50 | def add_arguments(parser): 51 | subparsers = parser.add_subparsers(dest="device") 52 | subparsers.required = True 53 | 54 | devparsers = list() 55 | devparsers.append(subparsers.add_parser("all")) 56 | devparsers.append(subparsers.add_parser("usb%")) 57 | 58 | for dev in devices: 59 | devparsers.append(subparsers.add_parser(dev)) 60 | 61 | for devparser in devparsers: 62 | devparser.add_argument( 63 | "-d", "--drive-image-path", dest="img_path", 64 | help="", 65 | required=True, 66 | ) 67 | devparser.add_argument( 68 | "-f", "--force", action="store_true", 69 | help="", 70 | ) 71 | 72 | 73 | def parse_arguments(args): 74 | if args.device == "all": 75 | devs = devices.keys() 76 | elif args.device == "usb%": 77 | devs = list(filter(lambda dev: dev.startswith("usb"), devices.keys())) 78 | else: 79 | devs = [args.device] 80 | 81 | devs = sorted(devs) 82 | 83 | img_path = os.path.abspath(args.img_path) 84 | 85 | os_ = "linux" 86 | 87 | for agent in fuzz.enumerate_guest_agents(os_): 88 | (_, dev, prog) = agent.split("-") 89 | if dev not in devs: 90 | continue 91 | 92 | overlay_img_dir = os.path.join( 93 | default_results_dir(), dev, prog) 94 | os.makedirs(overlay_img_dir, exist_ok=True) 95 | 96 | # overlay_img = "%s.qcow2" % (os.path.basename(img_path)) 97 | overlay_img = "overlay.qcow2" 98 | overlay_img_path = os.path.join(overlay_img_dir, overlay_img) 99 | 100 | if args.force and os.path.exists(overlay_img_path): 101 | os.remove(overlay_img_path) 102 | 103 | print(overlay_img_path) 104 | 105 | create_overlay_image(img_path, overlay_img_path) 106 | 107 | 108 | def main(): 109 | _check_dependencies() 110 | parser = argparse.ArgumentParser() 111 | add_arguments(parser) 112 | args = parser.parse_args() 113 | parse_arguments(args) 114 | 115 | 116 | if __name__ == "__main__": 117 | main() 118 | -------------------------------------------------------------------------------- /scripts/create-overlay-image.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [ "$#" -ne 2 ] || ! [ -f "$1" ]; then 4 | echo "Usage: $0 BASE_IMG_FILE OVERLAY_IMG_FILE" >&2 5 | exit 1 6 | fi 7 | 8 | BASE_IMG_FILE=$1 9 | OVERLAY_IMG_FILE=$2 10 | 11 | if [ -f "$OVERLAY_IMG_FILE" ]; then 12 | echo $OVERLAY_IMG_FILE already exists. >&2 13 | exit 1 14 | fi 15 | 16 | qemu-img create -f qcow2 $OVERLAY_IMG_FILE 2G -b $BASE_IMG_FILE -F raw 17 | -------------------------------------------------------------------------------- /scripts/fixup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import argparse 4 | import os 5 | import re 6 | 7 | import fuzz 8 | 9 | 10 | def add_arguments(parser): 11 | parser.add_argument( 12 | "-i", "--input", dest="input", 13 | help="", 14 | required=True, 15 | ) 16 | parser.add_argument( 17 | "-o", "--output", dest="output", 18 | help="", 19 | required=True, 20 | ) 21 | parser.add_argument( 22 | "-t", "--host", dest="host", 23 | help="", 24 | default="localhost", 25 | ) 26 | parser.add_argument( 27 | "-p", "--port", dest="port", 28 | help="", 29 | default=56841, 30 | ) 31 | parser.add_argument( 32 | "-w", "--workdir", dest="workdir", 33 | help="", 34 | default="workdir", 35 | ) 36 | parser.add_argument( 37 | "-c", "--vmcnt", dest="vmcnt", 38 | help="", 39 | default=1, 40 | ) 41 | parser.add_argument( 42 | "-r", "--runid", dest="runid", 43 | help="", 44 | default=0, 45 | ) 46 | 47 | 48 | def parse_arguments(args): 49 | if not os.path.exists(args.input): 50 | raise Exception() 51 | 52 | if "GOPATH" not in os.environ: 53 | raise Exception() 54 | 55 | gopath = os.environ["GOPATH"] 56 | if not os.path.exists(gopath): 57 | raise Exception() 58 | 59 | cfg_name = os.path.basename(args.input) 60 | cfg = re.compile("^[^-]*-([^-]*)[-.].*$").search(cfg_name) 61 | cfg = cfg.group(1) 62 | 63 | cwd = os.getcwd() 64 | os.chdir(os.path.dirname(__file__)) 65 | agents = fuzz.enumerate_guest_agents("linux") 66 | os.chdir(cwd) 67 | agent_id = agents.index("agent-%s-prog98" % (cfg)) 68 | 69 | root_scripts = os.path.dirname(os.path.abspath(__file__)) 70 | root = os.path.dirname(root_scripts) 71 | 72 | with open(args.input, "r") as infd: 73 | with open(args.output, "w") as outfd: 74 | outfd.truncate() 75 | for line in infd.readlines(): 76 | line = line.replace("$AGPATH", root) 77 | line = line.replace("$WORKDIR", args.workdir) 78 | line = line.replace("$GOPATH", gopath) 79 | line = line.replace("$AGENTID", str(agent_id)) 80 | line = line.replace("$HOST", args.host) 81 | line = line.replace("$PORT", args.port) 82 | line = line.replace("$VMCNT", str(args.vmcnt)) 83 | line = line.replace("$RUNID", str(args.runid)) 84 | outfd.write(line) 85 | 86 | 87 | def main(): 88 | parser = argparse.ArgumentParser() 89 | add_arguments(parser) 90 | args = parser.parse_args() 91 | parse_arguments(args) 92 | 93 | 94 | if __name__ == "__main__": 95 | main() 96 | -------------------------------------------------------------------------------- /scripts/fuzz.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import argparse 4 | import glob 5 | import os 6 | import multiprocessing 7 | from multiprocessing import Process 8 | import subprocess 9 | import string 10 | import threading 11 | import re 12 | 13 | TYPE_IO = 0x01 14 | TYPE_MEMORY = 0x00 15 | 16 | PCI_CLASS_NETWORK_ETHERNET = 0x0200 17 | PCI_CLASS_NETWORK_OTHER = 0x0280 18 | PCI_CLASS_WIRELESS_OTHER = 0x0d80 19 | PCI_CLASS_OTHERS = 0xff 20 | 21 | devices = { 22 | "aqc100": { 23 | "vendor": 0x1D6A, 24 | "device": 0x00B1, 25 | "revision": 0x0, 26 | "class": PCI_CLASS_NETWORK_ETHERNET, 27 | "mappings": [ 28 | {"size": 0x10000, "type": TYPE_MEMORY}, # FIXME 29 | ], 30 | "image": "aqtion", 31 | "module": "drivers/net/ethernet/aquantia/atlantic/atlantic.ko", 32 | }, 33 | "rtl8139": { 34 | "vendor": 0x10ec, 35 | "device": 0x8139, 36 | "revision": 0x20, 37 | "class": PCI_CLASS_NETWORK_ETHERNET, 38 | "subsystem_vendor": 0x0, 39 | "subsystem": 0x0, 40 | "mappings": [ 41 | {"size": 0x100, "type": TYPE_IO}, 42 | {"size": 0x100, "type": TYPE_MEMORY}, 43 | ], 44 | "image": "rtl8139", 45 | "module": "drivers/net/ethernet/realtek/8139cp.ko", 46 | }, 47 | "quark": { 48 | "vendor": 0x8086, 49 | "device": 0x937, 50 | "revision": 0x1, 51 | "class": PCI_CLASS_NETWORK_ETHERNET, 52 | "subsystem_vendor": 0x0, 53 | "subsystem": 0x0, 54 | "mappings": [ 55 | {"size": 0x2000, "type": TYPE_MEMORY}, 56 | ], 57 | "image": "stmmac", 58 | "module": "drivers/net/ethernet/stmicro/stmmac/stmmac-pci.ko", 59 | }, 60 | "snic": { 61 | "vendor": 0x1137, 62 | "device": 0x0046, 63 | "revision": 0x1, 64 | "class": ~0, 65 | "subsystem_vendor": 0x0, 66 | "subsystem": 0x0, 67 | "mappings": [ 68 | {"size": 0x4000, "type": TYPE_MEMORY}, 69 | {"size": 0x4000, "type": TYPE_MEMORY}, 70 | {"size": 0x4000, "type": TYPE_MEMORY}, 71 | ], 72 | "image": "snic", 73 | "module": "drivers/scsi/snic/snic.ko", 74 | }, 75 | "usb": { 76 | "image": "usb", 77 | "module": None, 78 | }, 79 | "usb.rsi": { 80 | "image": "usb", 81 | "module": None, 82 | }, 83 | "usb.mwifiex": { 84 | "image": "usb", 85 | "module": None, 86 | }, 87 | "usb.ar5523": { 88 | "image": "usb", 89 | "module": None, 90 | }, 91 | "usb.btusb": { 92 | "image": "usb", 93 | "module": None, 94 | }, 95 | "usb.pn533": { 96 | "image": "usb", 97 | "module": None, 98 | }, 99 | "usb.go7007": { 100 | "image": "usb", 101 | "module": None, 102 | }, 103 | "usb.si470x": { 104 | "image": "usb", 105 | "module": None, 106 | }, 107 | "usb.usx2y": { 108 | "image": "usb", 109 | "module": None, 110 | }, 111 | } 112 | 113 | LINUX_BUILD_DIR = "../build/guest/linux" 114 | WINDOWS_BUILD_DIR = "../build/guest/windows" 115 | 116 | QEMU_RUN_SH = "run-qemu.sh" 117 | 118 | 119 | def default_result_dir(dev, prog): 120 | # /scripts 121 | dirname = os.path.dirname(os.path.realpath("__file__")) 122 | # / 123 | dirname = os.path.dirname(dirname) 124 | # /results// 125 | dirname = os.path.join(dirname, "results", dev, prog) 126 | 127 | return dirname 128 | 129 | 130 | def default_drive_path(dev, prog): 131 | if dev not in devices: 132 | raise Exception("") 133 | 134 | dirname = default_result_dir(dev, prog) 135 | dirname = os.path.join(dirname, "overlay.qcow2") 136 | 137 | return os.path.abspath(dirname) 138 | 139 | 140 | def default_kernel_dir(dev): 141 | if dev not in devices: 142 | raise Exception("") 143 | 144 | # /scripts 145 | dirname = os.path.dirname(os.path.realpath("__file__")) 146 | # / 147 | dirname = os.path.dirname(dirname) 148 | 149 | guestos = "linux" 150 | img = devices[dev]["image"] 151 | if not img: 152 | raise Exception("") 153 | 154 | # /build/guest//image/ 155 | dirname = os.path.join(dirname, "build", "guest", guestos, "image", img) 156 | 157 | return dirname 158 | 159 | 160 | def default_modules_dir(dev=""): 161 | # /scripts 162 | dirname = os.path.dirname(os.path.realpath("__file__")) 163 | # / 164 | dirname = os.path.dirname(dirname) 165 | 166 | guestos = "linux" 167 | 168 | # /build/guest//image/modules 169 | dirname = os.path.join(dirname, "build", "guest", 170 | guestos, "image", "modules") 171 | if dev in devices and "image" in devices[dev]: 172 | dirname = os.path.join( 173 | dirname, 174 | "lib", 175 | "modules", 176 | "4.19.0%s+" % devices[dev]["image"], # TODO: glob 177 | ) 178 | 179 | return dirname 180 | 181 | 182 | def default_out_dir(dev, prog): 183 | if dev not in devices: 184 | raise Exception("") 185 | 186 | dirname = default_result_dir(dev, prog) 187 | 188 | if os.path.exists(dirname): 189 | return os.path.join(dirname, "out") 190 | 191 | dirname = "out-%s-%s" % (dev, prog) 192 | 193 | return dirname 194 | 195 | 196 | def default_dict_dir(dev): 197 | if dev not in devices: 198 | raise Exception("") 199 | 200 | return "dictionary" 201 | 202 | 203 | def io_desc(dev): 204 | if dev not in devices: 205 | raise Exception("") 206 | 207 | desc = list() 208 | for mapping in devices[dev]["mappings"]: 209 | if mapping["type"] == TYPE_MEMORY: 210 | desc.append("mmio=0x%x" % (mapping["size"])) 211 | if mapping["type"] == TYPE_IO: 212 | desc.append("io=0x%x" % (mapping["size"])) 213 | 214 | return ",".join(desc) 215 | 216 | 217 | def run_qemu(kernel_dir, drive_path, dev, prog, 218 | in_dir=None, dict_dir=None, out_file=None, 219 | load_vm=None, sync_id=None, instance_id=0, root_only=False, master=False, 220 | exec_file=None, exec_virtual=False, no_restore=False, 221 | normal_qemu=False, corpus_paths=[], out_dir=None, stdout_file=None, 222 | gdb=False): 223 | os.chdir(os.path.abspath(os.path.dirname(QEMU_RUN_SH))) 224 | 225 | args = ["./%s" % (QEMU_RUN_SH)] 226 | 227 | if gdb: 228 | args.append("-GDB") 229 | 230 | serial_output_file = "serial.txt" 231 | if sync_id: 232 | if master: 233 | args.extend(["-M", sync_id]) 234 | else: 235 | args.extend(["-S", sync_id]) 236 | serial_output_file = "serial.%s.txt" % (sync_id) 237 | 238 | if kernel_dir == "windows": 239 | args.append("-w") 240 | else: 241 | args.extend(["-k", kernel_dir]) 242 | 243 | if sync_id or not drive_path or not os.path.exists(drive_path): 244 | drive_path = os.path.abspath("stretch.img") 245 | if not os.path.exists(drive_path): 246 | raise Exception("%s not found. Please create one." % (drive_path)) 247 | 248 | args.extend(["-d", drive_path]) 249 | 250 | args.extend(["-p"]) 251 | 252 | if out_file: 253 | args.extend( 254 | ["-F", os.path.join(default_result_dir(dev, prog), out_file)] 255 | ) 256 | 257 | if exec_file and os.path.exists(exec_file): 258 | args.extend(["-x", os.path.abspath(exec_file)]) 259 | 260 | if in_dir and os.path.exists(in_dir): 261 | args.extend(["-I", in_dir]) 262 | 263 | if dict_dir and os.path.exists(dict_dir): 264 | args.extend(["-X", dict_dir]) 265 | 266 | if out_dir and os.path.exists(out_dir): 267 | args.extend(["-O", out_dir]) 268 | else: 269 | args.extend(["-O", default_out_dir(dev, prog)]) 270 | 271 | if "vendor" in devices[dev]: 272 | args.extend(["-V", "0x%x" % devices[dev]["vendor"]]) 273 | 274 | if exec_virtual: 275 | args.extend(["-D", dev]) 276 | else: 277 | args.extend(["-D", "0x%x" % devices[dev]["device"]]) 278 | args.extend(["-R", "0x%x" % devices[dev]["revision"]]) 279 | args.extend(["-C", "0x%x" % devices[dev]["class"]]) 280 | 281 | os_ = "linux" 282 | if kernel_dir == "windows": 283 | os_ = "windows" 284 | args.extend(["-G", "%d" % get_agent_id(os_, dev, prog)]) 285 | 286 | # args.extend(["-IOMMU"]) 287 | 288 | if os.path.exists("trace-events"): 289 | args.extend(["-t", "events=trace-events"]) 290 | 291 | if "subsystem_vendor" in devices[dev]: 292 | args.extend(["-SV", "0x%x" % devices[dev]["subsystem_vendor"]]) 293 | if "subsystem" in devices[dev]: 294 | args.extend(["-SD", "0x%x" % devices[dev]["subsystem"]]) 295 | 296 | if "mappings" in devices[dev]: 297 | args.extend(["-IO", io_desc(dev)]) 298 | 299 | if load_vm and load_vm != "": 300 | args.extend(["-l", load_vm]) 301 | 302 | args.extend(["--seed", "%d" % instance_id]) 303 | if root_only: 304 | args.extend(["--root-only"]) 305 | 306 | if no_restore: 307 | args.extend(["--no-restore"]) 308 | qemu_args = list() 309 | 310 | mem_path = os.path.join(default_result_dir(dev, prog), "mem") 311 | if sync_id: 312 | mem_path += ".%s" % sync_id 313 | 314 | qemu_args.extend([ 315 | "-mem-path", 316 | mem_path 317 | ]) 318 | qemu_args.extend([ 319 | "-mem-prealloc", 320 | ]) 321 | 322 | if prog == "debug": 323 | normal_qemu = True 324 | 325 | if not normal_qemu: 326 | args.extend( 327 | ["-f", os.path.join(default_result_dir(dev, prog), 328 | serial_output_file)] 329 | ) 330 | else: 331 | qemu_args.extend([ 332 | "-serial", "stdio" 333 | ]) 334 | 335 | if normal_qemu: 336 | args.extend(["-q"]) 337 | 338 | if corpus_paths and len(corpus_paths) > 0: 339 | if len(corpus_paths) > 10: 340 | raise Exception("Too many corpus paths") 341 | args.extend(["-c", ",".join([os.path.abspath(p) 342 | for p in corpus_paths])]) 343 | 344 | if sync_id: 345 | pid_file = os.path.join( 346 | default_result_dir(dev, prog), 347 | "vm.%s.pid" % (sync_id), 348 | ) 349 | else: 350 | pid_file = os.path.join( 351 | default_result_dir(dev, prog), 352 | "vm.pid" 353 | ) 354 | qemu_args.extend(["-pidfile", pid_file]) 355 | 356 | if len(qemu_args) > 0: 357 | args.append("--") 358 | args.extend(qemu_args) 359 | 360 | cmd = " ".join(args) 361 | print(cmd) 362 | 363 | if stdout_file: 364 | proc = subprocess.Popen( 365 | args, cwd=os.path.abspath(os.path.dirname(QEMU_RUN_SH)), 366 | stdout=stdout_file 367 | ) 368 | else: 369 | proc = subprocess.Popen( 370 | args, cwd=os.path.abspath(os.path.dirname(QEMU_RUN_SH)) 371 | ) 372 | 373 | try: 374 | proc.communicate() 375 | except KeyboardInterrupt: 376 | proc.kill() 377 | proc.wait() 378 | return 379 | 380 | if proc.wait() != 0: 381 | print("proc exited with errors.") 382 | 383 | 384 | def check_dependencies(): 385 | files_to_check = [QEMU_RUN_SH] 386 | for f in files_to_check: 387 | if not os.path.exists(f): 388 | raise Exception("File '%s' does not exist." % (f)) 389 | 390 | 391 | def check_linux_image(device, kernel_dir): 392 | if not os.path.exists(kernel_dir): 393 | raise Exception("'%s does not exist." % (kernel_dir)) 394 | if not os.path.exists(os.path.join(kernel_dir, "vmlinux")): 395 | raise Exception("vmlinux not found.") 396 | 397 | bzImage = os.path.join(kernel_dir, "arch", "x86", "boot", "bzImage") 398 | if not os.path.exists(bzImage): 399 | raise Exception("bzImage not found.") 400 | 401 | image = device 402 | if "image" in devices[device]: 403 | image = devices[device]["image"] 404 | localversion = '[45]\.[0-9]+\.[0-9]+.*%s\+' % (image) 405 | prog = re.compile(localversion) 406 | 407 | dev_found = False 408 | strings = subprocess.getoutput("strings %s" % (bzImage)).split("\n") 409 | for line in strings: 410 | if prog.match(line): 411 | dev_found = True 412 | break 413 | 414 | if not dev_found: 415 | raise Exception("Unexpected bzImage: %s" % bzImage) 416 | 417 | 418 | # Unique id for guest os 419 | def get_agent_id(os_, dev, prog): 420 | agents = enumerate_guest_agents(os_) 421 | return agents.index("agent-%s-%s" % (dev, prog)) 422 | 423 | 424 | def enumerate_guest_agents(os_): 425 | agents = list() 426 | 427 | # needs to be consistent 428 | sorted_devs = sorted(devices.keys()) 429 | sorted_devs = list(filter( 430 | lambda dev: 431 | "image" in devices[dev] 432 | and "module" in devices[dev], 433 | # and "mappings" in devices[dev] 434 | # and len(devices[dev]["mappings"]) > 0, 435 | sorted_devs 436 | )) 437 | sorted_progs = [prog.split("-")[1] 438 | for prog in sorted(_enumerate_progs(os_))] 439 | 440 | for dev in sorted_devs: 441 | for prog in sorted_progs: 442 | agent = "agent-%s-%s" % (dev, prog) 443 | agents.append(agent) 444 | 445 | return agents 446 | 447 | 448 | def _enumerate_progs(os_list): 449 | progs = list() 450 | 451 | if "linux" in os_list: 452 | progs.append("linux-debug") 453 | 454 | for prog in glob.glob("%s/progs/prog[0-9]*" % LINUX_BUILD_DIR): 455 | progs.append("linux-%s" % os.path.basename(prog)) 456 | 457 | for prog in glob.glob("%s/traces/trace[0-9]*" % LINUX_BUILD_DIR): 458 | progs.append("linux-%s" % os.path.basename(prog)) 459 | 460 | if "windows" in os_list: 461 | for prog in glob.glob("%s/progs/prog[0-9]*" % WINDOWS_BUILD_DIR): 462 | progs.append("windows-%s" % os.path.basename(prog)) 463 | 464 | for prog in glob.glob("%s/traces/trace[0-9]*" % WINDOWS_BUILD_DIR): 465 | progs.append("windows-%s" % os.path.basename(prog)) 466 | 467 | return progs 468 | 469 | 470 | def add_arguments(parser): 471 | subparsers = parser.add_subparsers(dest="device") 472 | subparsers.required = True 473 | 474 | devparsers = list() 475 | for dev in devices: 476 | devparsers.append(subparsers.add_parser(dev)) 477 | 478 | for devparser in devparsers: 479 | devparser.add_argument( 480 | "-g", '--guest-prog', type=str, 481 | choices=_enumerate_progs(["linux", "windows"]), 482 | help="", 483 | required=True, 484 | ) 485 | devparser.add_argument( 486 | "-w", "--windows", action="store_true", 487 | help="", 488 | ) 489 | devparser.add_argument( 490 | "-k", "--kernel", dest="kernel_dir", 491 | help="", 492 | ) 493 | devparser.add_argument( 494 | "-d", "--drive", dest="drive_path", 495 | help="", 496 | ) 497 | devparser.add_argument( 498 | "-N", "--num-instances", dest="num_instances", 499 | type=int, 500 | help="", 501 | ) 502 | devparser.add_argument( 503 | "-l", "--loadvm", dest="vm_image", 504 | help="", 505 | ) 506 | devparser.add_argument( 507 | "-i", "--in-dir", dest="in_dir", 508 | help="", 509 | ) 510 | devparser.add_argument( 511 | "-o", "--out-dir", dest="out_dir", 512 | help="", 513 | ) 514 | devparser.add_argument( 515 | "-ro", "--root-only", dest="root_only", action="store_true", 516 | help="only store root checkpoint" 517 | ) 518 | devparser.add_argument( 519 | "-nr", "--no-restore", dest="no_restore", action="store_true", 520 | help="disable checkpoint restore (for baseline testing)" 521 | ) 522 | devparser.add_argument( 523 | "-x", "--exec", dest="input_to_exec", 524 | help="run guest with a replay device, no fuzzing", 525 | ) 526 | devparser.add_argument( 527 | "-xv", "--exec-virtual", action="store_true", 528 | help="run guest with a virtual device, no fuzzing", 529 | ) 530 | devparser.add_argument( 531 | "-X", "--dict-dir", dest="dict_dir", 532 | help="" 533 | ) 534 | devparser.add_argument( 535 | "-q", "--normal-qemu", dest="normal_qemu", action="store_true", 536 | help="run guest, no fuzzing" 537 | ) 538 | devparser.add_argument( 539 | "-c", "--coverage", dest="corpus_path", 540 | nargs="+", 541 | help="A list of corpus dirs/files to collect coverage for.", 542 | ) 543 | devparser.add_argument( 544 | "-G", "--gdb", action="store_true", 545 | help="", 546 | ) 547 | 548 | 549 | def parse_arguments(args): 550 | if "windows" in args and args.windows: 551 | if args.kernel_dir: 552 | raise Exception("--windows and --kernel are mutually exclusive.") 553 | kernel_dir = "windows" 554 | else: # Linux 555 | kernel_dir = args.kernel_dir 556 | if not kernel_dir: 557 | kernel_dir = default_kernel_dir(args.device) 558 | check_linux_image(args.device, kernel_dir) 559 | 560 | guest_prog = "" 561 | if args.guest_prog: 562 | guest_prog = args.guest_prog.split("-")[1] 563 | 564 | drive_path = args.drive_path 565 | # if not args.drive_path: 566 | # drive_path = default_drive_path(args.device, guest_prog) 567 | 568 | if drive_path and not os.path.exists(drive_path): 569 | raise Exception("%s does not exist." % (drive_path)) 570 | 571 | dict_dir = args.dict_dir 572 | # if not args.dict_dir: 573 | # dict_dir = default_dict_dir(args.device) 574 | 575 | if args.num_instances and args.num_instances > 1: 576 | for ignored in ["corpus_path", "normal_qemu", "input_to_exec", "exec_virtual"]: 577 | if getattr(args, ignored): 578 | print("Ignoring %s: %s" % (ignored, getattr(args, ignored))) 579 | 580 | cpu_count = multiprocessing.cpu_count() 581 | cpu_count = min(100, cpu_count) 582 | if cpu_count <= 1: 583 | raise Exception("No multiple CPUs found.") 584 | 585 | num_instances = args.num_instances 586 | 587 | sync_ids = ["fuzzer%02d-M" % 0] 588 | for i in range(1, num_instances): 589 | sync_ids.append("fuzzer%02d-S" % (i)) 590 | 591 | out_files = list() 592 | for i in range(0, num_instances): 593 | out_files.append("cur%02d" % (i)) 594 | 595 | threads = list() 596 | for i in range(0, num_instances): 597 | master = False 598 | if i == 0: 599 | master = True 600 | thread = threading.Thread( 601 | target=run_qemu, 602 | kwargs={ 603 | "kernel_dir": kernel_dir, 604 | "drive_path": drive_path, 605 | "dev": args.device, 606 | "prog": guest_prog, 607 | "load_vm": args.vm_image, 608 | "in_dir": args.in_dir, 609 | "dict_dir": dict_dir, 610 | "out_dir": args.out_dir, 611 | "out_file": out_files[i], 612 | "sync_id": sync_ids[i], 613 | "instance_id": i, 614 | "root_only": args.root_only, 615 | "no_restore": args.no_restore, 616 | "master": master, 617 | }, 618 | ) 619 | threads.append(thread) 620 | 621 | try: 622 | for thread in threads: 623 | thread.start() 624 | 625 | except KeyboardInterrupt: 626 | print("TODO: Handling Ctrl+C") 627 | 628 | else: 629 | run_qemu( 630 | kernel_dir=kernel_dir, 631 | drive_path=drive_path, 632 | dev=args.device, 633 | prog=guest_prog, 634 | in_dir=args.in_dir, 635 | dict_dir=dict_dir, 636 | out_file="cur", 637 | out_dir=args.out_dir, 638 | load_vm=args.vm_image, 639 | exec_file=args.input_to_exec, 640 | exec_virtual=args.exec_virtual, 641 | normal_qemu=args.normal_qemu, 642 | corpus_paths=args.corpus_path, 643 | instance_id=0, 644 | root_only=args.root_only, 645 | no_restore=args.no_restore, 646 | gdb=args.gdb, 647 | ) 648 | 649 | 650 | def main(): 651 | check_dependencies() 652 | parser = argparse.ArgumentParser() 653 | add_arguments(parser) 654 | args = parser.parse_args() 655 | parse_arguments(args) 656 | 657 | 658 | if __name__ == "__main__": 659 | main() 660 | -------------------------------------------------------------------------------- /scripts/reset-overlay+fuzz.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [ $# -ne 3 ]; then 4 | echo "Usage: $0 rtl8139> stretch_mod.img> ../../linux_o_rtl8139_mod>" >&2 5 | exit 1 6 | fi 7 | 8 | 9 | DEV=$1 10 | IMG=$2 11 | KERN=$3 12 | OVRLAY=${IMG%.*} 13 | OVRLAY+="_overlay.qcow2" 14 | rm -r out-$DEV 15 | mkdir out-$DEV 16 | rm $OVRLAY 17 | ./create-overlay-image.sh $IMG $OVRLAY 18 | echo ./fuzz.py $DEV -k $KERN -d $OVRLAY -i in/ 19 | ./fuzz.py $DEV -k $KERN -d $OVRLAY -i in/ 20 | -------------------------------------------------------------------------------- /scripts/run-qemu.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | display_help() { 4 | echo "Usage: $0 [option...] " >&2 5 | echo 6 | echo " -k, --kernel-root-dir Linux kernel root directory" 7 | echo " -w, --windows Boot Windows" 8 | echo " -g, --graphic Remove -nographic" 9 | echo " -d, --drive-img-file System image file" 10 | echo " -l, --load-vm VM snapshot to load" 11 | echo " -s, --monitor-to-socket Open monitor as a Unix socket" 12 | echo " -m, --monitor Open monitor" 13 | echo " -f, --serial-to-file A file to redirect serial output to" 14 | echo " -q, --normal-qemu Normal QEMU mode w/o fuzzing enabled" 15 | echo " -t, --trace QEMU's --trace; consult QEMU for detail" 16 | echo " -c, --coverage Comma separated list of corpus files/dirs" 17 | echo " -n, --nic Attach a NIC" 18 | echo " -p, --pseudo-device Pseudo device for direct communication w/ guest kernel" 19 | echo " -V, --vendor-id Vendor ID" 20 | echo " -D, --device-id Device ID" 21 | echo " -R, --revision-id Revision ID" 22 | echo " -C, --class-id Class ID" 23 | echo " -SV, --subsystem-vendor-id Subsystem Vendor ID" 24 | echo " -SD, --subsystem-id Subsystem ID" 25 | echo " -se, --seed AFL Seed" 26 | echo " -ro, --root-only Create only root checkpoint" 27 | echo " -IO I/O mapping descriptions" 28 | echo " -IOMMU Enable I/OMMU" 29 | echo " -I, --fuzzer-in-dir A path to fuzzer input seed directory" 30 | echo " -F, --fuzzer-out-file A path to fuzzer out file" 31 | echo " -O, --fuzzer-out-dir A path to fuzzer out directory" 32 | echo " -M, --master-id ID for master fuzzer instance" 33 | echo " -S, --secondary-id ID for secondary fuzzer instance" 34 | echo " -x, --exec-input-file Path to an input file to execute" 35 | echo " -X, --fuzzer-dict-dir Path the afl dictionary" 36 | echo " -GDB, --gdb GDB debug" 37 | echo " -- ... Additional QEMU options" 38 | echo " -h, --help Display help message" 39 | echo 40 | } 41 | 42 | while true; do 43 | if [ $# -eq 0 ];then 44 | echo $# 45 | break 46 | fi 47 | case "$1" in 48 | -h | --help) 49 | display_help 50 | exit 0 51 | ;; 52 | -k | --kernel-root-dir) 53 | KERNEL_ROOT_DIR=$2 54 | shift 2 55 | ;; 56 | -w | --windows) 57 | WINDOWS=1 58 | shift 1 59 | ;; 60 | -g | --graphic) 61 | GRAPHIC=1 62 | shift 1 63 | ;; 64 | -d | --drive-img-file) 65 | DRIVE_IMG_FILE=$2 66 | shift 2 67 | ;; 68 | -l | --load-vm) 69 | LOADVM=$2 70 | shift 2 71 | ;; 72 | -s | --monitor-to-socket) 73 | MONITOR_TO_SOCKET=$2 74 | shift 2 75 | ;; 76 | -m | --monitor) 77 | MONITOR=$2 78 | shift 2 79 | ;; 80 | -f | --serial-to-file) 81 | SERIAL_TO_FILE=$2 82 | shift 2 83 | ;; 84 | -q | --normal-qemu) 85 | NORMAL_QEMU=1 86 | shift 1 87 | ;; 88 | -t | --trace) 89 | TRACE=$2 90 | shift 2 91 | ;; 92 | -c | --coverage) 93 | CORPUS_FILES=$2 94 | shift 2 95 | ;; 96 | -n | --nic) 97 | NIC=1 98 | shift 1 99 | ;; 100 | -p | --pseudo-device) 101 | PSEUDO_DEVICE=kcov_vdev 102 | shift 1 103 | ;; 104 | -V | --vendor-id) 105 | VENDOR_ID=$2 106 | shift 2 107 | ;; 108 | -D | --device-id) 109 | DEVICE_ID=$2 110 | shift 2 111 | ;; 112 | -R | --revision-id) 113 | REVISION_ID=$2 114 | shift 2 115 | ;; 116 | -C | --class-id) 117 | CLASS_ID=$2 118 | shift 2 119 | ;; 120 | -SV | --subsystem-vendor-id) 121 | SUBSYSTEM_VENDOR_ID=$2 122 | shift 2 123 | ;; 124 | -SD | --subsystem-id) 125 | SUBSYSTEM_ID=$2 126 | shift 2 127 | ;; 128 | -se | --seed) 129 | AFL_SEED=$2 130 | shift 2 131 | ;; 132 | -nr | --no-restore) 133 | NO_RESTORE=1 134 | shift 1 135 | ;; 136 | -ro | --root-only) 137 | ROOT_ONLY_CHKPT=1 138 | shift 1 139 | ;; 140 | -IO) 141 | IO_MEMORY_DESC=$2 142 | shift 2 143 | ;; 144 | -IOMMU) 145 | IOMMU=true 146 | shift 1 147 | ;; 148 | -I | --fuzzer-in-dir) 149 | FUZZER_IN_DIR=$2 150 | shift 2 151 | ;; 152 | -X | --fuzzer-dict-dir) 153 | FUZZER_DICT_DIR=$2 154 | shift 2 155 | ;; 156 | -F | --fuzzer-out-file) 157 | FUZZER_OUT_FILE=$2 158 | shift 2 159 | ;; 160 | -O | --fuzzer-out-dir) 161 | FUZZER_OUT_DIR=$2 162 | shift 2 163 | ;; 164 | -G | --guest-agent-id) 165 | GUEST_AGENT_ID=$2 166 | shift 2 167 | ;; 168 | -M | --master-id) 169 | MASTER_ID=$2 170 | shift 2 171 | ;; 172 | -S | --secondary-id) 173 | SECONDARY_ID=$2 174 | shift 2 175 | ;; 176 | -x | --exec-input-file) 177 | EXEC_FILE=$2 178 | shift 2 179 | ;; 180 | -T | --test-print-only) 181 | PRINT_ONLY=1 182 | shift 1 183 | ;; 184 | -GDB | --gdb) 185 | GDB=1 186 | shift 1 187 | ;; 188 | --) 189 | ADDITIONAL_ARGS=${@:2} 190 | break 191 | ;; 192 | -*) 193 | echo "Error: Unknown option: $1" >&2 194 | exit 1 195 | ;; 196 | *) # No more options 197 | break 198 | ;; 199 | esac 200 | done 201 | 202 | 203 | if [ ! -z $WINDOWS ]; then 204 | echo "Booting Windows..." 205 | GRAPHIC=1 206 | elif [ ! -d $KERNEL_ROOT_DIR ]; then 207 | echo "--kernel-root-dir invalid." >&2 208 | else 209 | KERNEL_IMG_FILE=$KERNEL_ROOT_DIR/arch/x86/boot/bzImage 210 | fi 211 | 212 | BASE_DIR=$(dirname "$0")/.. 213 | 214 | LIBAGAMOTTO=$BASE_DIR/build/libagamotto/libagamotto.so 215 | 216 | if [ ! -f $DRIVE_IMG_FILE ]; then 217 | DRIVE_IMG_FILE=$BASE_DIR/scripts/stretch.img 218 | echo "--drive-img-file invalid." >&2 219 | exit 1 220 | fi 221 | 222 | QEMU=`which qemu-system-x86_64` 223 | 224 | if [ ! -f $QEMU ]; then 225 | echo qemu not found. 226 | exit 1 227 | fi 228 | 229 | if [ ! -z $FUZZER_IN_DIR ]; then 230 | if [ ! -d $FUZZER_IN_DIR ]; then 231 | echo $FUZZER_IN_DIR not found. 232 | exit 1 233 | fi 234 | export __PERISCOPE_IN_DIR=$FUZZER_IN_DIR 235 | fi 236 | 237 | if [ ! -z $FUZZER_DICT_DIR ]; then 238 | if [ ! -d $FUZZER_DICT_DIR ]; then 239 | echo $FUZZER_DICT_DIR not found. 240 | exit 1 241 | fi 242 | export __PERISCOPE_DICT_DIR=$FUZZER_DICT_DIR 243 | fi 244 | 245 | if [ ! -z $FUZZER_OUT_FILE ]; then 246 | if [ -f $FUZZER_OUT_FILE ]; then 247 | echo $FUZZER_OUT_FILE will be overwritten. 248 | fi 249 | export __PERISCOPE_OUT_FILE=$FUZZER_OUT_FILE 250 | fi 251 | 252 | if [ ! -z $FUZZER_OUT_DIR ]; then 253 | if [ -d $FUZZER_OUT_DIR ]; then 254 | echo $FUZZER_OUT_DIR will be reused. 255 | fi 256 | export __PERISCOPE_OUT_DIR=$FUZZER_OUT_DIR 257 | fi 258 | 259 | if [ ! -z $MASTER_ID ]; then 260 | export __PERISCOPE_MASTER_ID=$MASTER_ID 261 | fi 262 | 263 | if [ ! -z $SECONDARY_ID ]; then 264 | export __PERISCOPE_SECONDARY_ID=$SECONDARY_ID 265 | fi 266 | 267 | if [ ! -z $AFL_SEED ]; then 268 | export __PERISCOPE_AFL_SEED=$AFL_SEED 269 | fi 270 | if [ ! -z $ROOT_ONLY_CHKPT ]; then 271 | export __PERISCOPE_ROOT_ONLY_CHKPT="root_only" 272 | fi 273 | if [ ! -z $NO_RESTORE ]; then 274 | export __PERISCOPE_NO_RESTORE="no_restore" 275 | fi 276 | 277 | echo 278 | echo Using $QEMU... 279 | echo 280 | 281 | sleep 0.5 282 | 283 | QEMU_CMD="" 284 | QEMU_CMD+=" -smp 1" 285 | QEMU_CMD+=" -net none" 286 | 287 | if [ ! -z $IOMMU ]; then 288 | QEMU_CMD+=" -machine q35,accel=kvm" 289 | else 290 | QEMU_CMD+=" -cpu host" 291 | fi 292 | QEMU_CMD+=" -nodefaults" 293 | 294 | if [ ! -z $WINDOWS ]; then 295 | QEMU_CMD+=" -m 4G" 296 | else 297 | QEMU_CMD+=" -m 512M" 298 | fi 299 | 300 | if [ ! -z $KERNEL_IMG_FILE ]; then 301 | QEMU_CMD+=" -kernel $KERNEL_IMG_FILE" 302 | fi 303 | 304 | if [ ! -z $WINDOWS ]; then 305 | QEMU_CMD+=" -drive driver=qcow2,file=$DRIVE_IMG_FILE,if=virtio" 306 | QEMU_CMD+=" -drive file=virtio-win.iso,index=3,media=cdrom" 307 | else 308 | QEMU_CMD+=" -hda $DRIVE_IMG_FILE" 309 | fi 310 | 311 | if [ -z $GRAPHIC ]; then 312 | QEMU_CMD+=" -nographic" 313 | fi 314 | 315 | QEMU_CMD+=" -enable-kvm" 316 | 317 | if [ ! -z $NIC ]; then 318 | QEMU_CMD+=" -net nic -net user,hostfwd=tcp:127.0.0.1:11023-:23456,hostfwd=tcp:127.0.0.1:11022-:22" 319 | #QEMU_CMD+=" -net nic" 320 | fi 321 | 322 | if [ ! -z $CORPUS_FILES ]; then 323 | QEMU_CMD+=" -device $PSEUDO_DEVICE,trace-pc=on" 324 | else 325 | if [ ! -z $PSEUDO_DEVICE ]; then 326 | QEMU_CMD+=" -device $PSEUDO_DEVICE" 327 | fi 328 | fi 329 | 330 | ## SD Card or SDIO? 331 | #QEMU_CMD+=" -device sdhci-pci,id=sdhci0" 332 | #QEMU_CMD+=" -device generic-sdhci,id=sdhci0" # gives an error 333 | 334 | #QEMU_CMD+=" -usb" 335 | #QEMU_CMD+=" -device usb-periscope" 336 | 337 | ## I2C or SMBus 338 | #QEMU_CMD+=" -device periscope-pci-i2c" 339 | #QEMU_CMD+=" -device periscope-i2c,address=0x30" 340 | 341 | DEVICE_NAME="periscope" # our exploratory device 342 | 343 | if [ ! -z $DEVICE_ID && [ "$DEVICE_ID" != "0x"* ] ]; then 344 | DEVICE_FOUND=$($QEMU -device ? | grep name | awk -F", " "{print \$1}" | awk "{print \$2}" | grep \"$DEVICE_ID\") 345 | if [ ! -z $DEVICE_FOUND ]; then 346 | LIBAGAMOTTO= 347 | DEVICE_NAME=$DEVICE_ID # existing emulated device 348 | else 349 | echo No emulated device \"$DEVICE_ID\" found. 350 | echo 351 | exit 1 352 | fi 353 | fi 354 | 355 | if [ ! -z $IOMMU ]; then 356 | QEMU_CMD+=" -device ioh3420,id=pcie.0,chassis=1" 357 | QEMU_CMD+=" -device $DEVICE_NAME,bus=pcie.0" 358 | elif [ ! -z $DEVICE_NAME ]; then 359 | QEMU_CMD+=" -device $DEVICE_NAME" 360 | fi 361 | 362 | # XXX uncomment for kvm api test 363 | #QEMU_CMD+=" -device kvm_api_test" 364 | 365 | # QCA6174 366 | if [ -z $VENDOR_ID ]; then 367 | VENDOR_ID=0x168c 368 | fi 369 | if [ -z $DEVICE_ID ]; then 370 | DEVICE_ID=0x3e 371 | fi 372 | if [ -z $REVISION_ID ]; then 373 | REVISION_ID=0x20 374 | fi 375 | if [ -z $CLASS_ID ]; then 376 | CLASS_ID=0x0280 377 | fi 378 | if [ -z $SUBSYSTEM_VENDOR_ID ]; then 379 | SUBSYSTEM_VENDOR_ID=0x0 380 | fi 381 | if [ -z $SUBSYSTEM_ID ]; then 382 | SUBSYSTEM_ID=0x0 383 | fi 384 | 385 | if [ -z $GUEST_AGENT_ID ]; then 386 | GUEST_AGENT_ID="3735928559" # 0xDEADBEEF 387 | fi 388 | 389 | QEMU_CMD+=" -periscope" 390 | QEMU_CMD+=" vendor=$VENDOR_ID,device=$DEVICE_ID,revision=$REVISION_ID,class=$CLASS_ID" 391 | QEMU_CMD+=",subsystem_vendor_id=$SUBSYSTEM_VENDOR_ID,subsystem_id=$SUBSYSTEM_ID" 392 | 393 | if [ ! -z $IO_MEMORY_DESC ]; then 394 | QEMU_CMD+=",$IO_MEMORY_DESC" 395 | fi 396 | 397 | if [ ! -z $CORPUS_FILES ]; then 398 | LIBAGAMOTTO= 399 | QEMU_CMD+=" -fuzzer kcov:$GUEST_AGENT_ID,$CORPUS_FILES" 400 | elif [ ! -z $EXEC_FILE ]; then 401 | LIBAGAMOTTO= 402 | QEMU_CMD+=" -fuzzer exec:$GUEST_AGENT_ID,$EXEC_FILE" 403 | elif [ ! -z $NORMAL_QEMU ]; then 404 | LIBAGAMOTTO= 405 | QEMU_CMD+=" -fuzzer none:$GUEST_AGENT_ID" 406 | else 407 | export __PERISCOPE_GUEST_AGENT_ID=$GUEST_AGENT_ID 408 | fi 409 | 410 | export __PERISCOPE_CHKPT_POOL_SIZE=12288 411 | 412 | QEMU_CMD_KERNEL_APPEND="console=ttyS0 root=/dev/sda debug earlyprintk=serial slub_debug=QUZ net.ifnames=0 nokaslr" 413 | if [ ! -z $IOMMU ]; then 414 | QEMU_CMD_KERNEL_APPEND+=" intel_iommu=strict" 415 | fi 416 | QEMU_CMD_KERNEL_DYNDBG_APPEND="file kernel/module.c +p;" 417 | QEMU_CMD_KERNEL_DYNDBG_APPEND+=" module 8139too +p;" 418 | QEMU_CMD_KERNEL_DYNDBG_APPEND+=" module 8139cp +p;" 419 | QEMU_CMD_KERNEL_DYNDBG_APPEND+=" module vmxnet3 +p;" 420 | QEMU_CMD_KERNEL_DYNDBG_APPEND+=" module ne2k-pci +p;" 421 | QEMU_CMD_KERNEL_APPEND+=" dyndbg=\"$QEMU_CMD_KERNEL_DYNDBG_APPEND\"" 422 | 423 | if [ ! -z $IOMMU ]; then 424 | QEMU_CMD+=" -device intel-iommu,caching-mode=true" 425 | fi 426 | 427 | if [ ! -f $MONITOR_TO_SOCKET ]; then 428 | QEMU_CMD+=" -monitor unix:$MONITOR_TO_SOCKET,server,nowait" 429 | else 430 | if [ -z $MONITOR ]; then 431 | QEMU_CMD+=" -monitor null" 432 | else 433 | QEMU_CMD+=" -monitor $MONITOR" 434 | fi 435 | fi 436 | 437 | if [ ! -z $SERIAL_TO_FILE ]; then 438 | QEMU_CMD+=" -serial file:$SERIAL_TO_FILE" 439 | fi 440 | 441 | if [ ! -z $TRACE ]; then 442 | QEMU_CMD+=" --trace $TRACE" 443 | fi 444 | 445 | QEMU_CMD+=" "$ADDITIONAL_ARGS 446 | 447 | if [ ! -z $LOADVM ]; then 448 | echo Restoring $LOADVM... 449 | QEMU_CMD+=" -loadvm $LOADVM" 450 | fi 451 | 452 | QEMU_CMD+=" -snapshot" 453 | 454 | if [ -z $PID_FILE ]; then 455 | PID_FILE=vm.pid 456 | 457 | if [ ! -z $MASTER_ID ]; then 458 | PID_FILE=vm-$MASTER_ID.pid 459 | fi 460 | 461 | if [ ! -z $SECONDARY_ID ]; then 462 | PID_FILE=vm-$SECONDARY_ID.pid 463 | fi 464 | fi 465 | 466 | echo $QEMU $QEMU_CMD 467 | 468 | if [ ! -z $PRINT_ONLY ]; then 469 | echo LD_PRELOAD=$LIBAGAMOTTO ${QEMU} ${QEMU_CMD} -append "$QEMU_CMD_KERNEL_APPEND" 470 | exit 0 471 | fi 472 | 473 | if [ ! -z $WINDOWS ]; then 474 | set -eux 475 | 476 | LD_PRELOAD=$LIBAGAMOTTO ${QEMU} ${QEMU_CMD} \ 477 | -usb -device usb-tablet 478 | else 479 | if [ ! -z $GDB ]; then 480 | echo set startup-with-shell off | tee /tmp/gdb.cmd 481 | echo set exec-wrapper env LD_PRELOAD=${LIBAGAMOTTO} | tee -a /tmp/gdb.cmd 482 | # echo b blockdev.c:933 | tee -a /tmp/gdb.cmd 483 | echo run ${QEMU_CMD} -append "$QEMU_CMD_KERNEL_APPEND" | tee -a /tmp/gdb.cmd 484 | 485 | gdb ${QEMU} -x /tmp/gdb.cmd 486 | exit 0 487 | fi 488 | 489 | set -eux 490 | LD_PRELOAD=$LIBAGAMOTTO ${QEMU} ${QEMU_CMD} \ 491 | -append "$QEMU_CMD_KERNEL_APPEND" 492 | fi 493 | -------------------------------------------------------------------------------- /scripts/seed/Agamotto: -------------------------------------------------------------------------------- 1 | Agamotto -------------------------------------------------------------------------------- /setup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | mkdir build 4 | 5 | pushd libafl 6 | ./setup.sh 7 | popd 8 | --------------------------------------------------------------------------------