intel / kernel-fuzzer-for-xen-project

Kernel Fuzzer for Xen Project (KF/x) - Hypervisor-based fuzzing using Xen VM forking, VMI & AFL
MIT License
466 stars 79 forks source link

Add convenient option to auto infer input address during fuzzing #40

Closed aashays closed 3 years ago

aashays commented 3 years ago

The input address is not guaranteed to be stable and so inferring it from the extended-mark helps speed up the process.

The parent VM being past the CPUID instruction presents some challenges. Input size has been clobbered already and cannot be retrieved. Also rewinding the VM to confirm we're paused at the harness is tricky. The current implementation is a bit hacky and avoids capstone for simplicity.. but is safe as long as the VM was setup as instructed.

tklengyel commented 3 years ago

Under what situation would you need to worry about not being paused at the harness site? Also, IMHO saving the target address & size to a log during setup and then reading from there should be fairly painless already. You could achieve the same with just a couple lines of shell scripts.

kfx --setup -c ... > setup.log
address=$(grep Target setup.log | awk '{ print $5 }')
size=$(grep Target setup.log | awk '{ print $6 }')
kfx --address $address --input-limit $size ...

It does require you to keep track of that log file which might complicate things if you expect to distribute that VM state to multiple machines. But as a practical matter we always keep that log file saved as it helps during triaging.

Anyway, I wouldn't object adding this auto option but I would recommend some changes. To keep all information kept in the VM's state you should stuff them back into vCPU regs after Xen finished processing the CPUID event and its done clobbering the registers. In setup.c you can edit the parent VM's registers in cpuid_done and stuff information back into RAX, RBX, RCX and RDX safely. You can set one of them back to a magic value so that you don't have to do this hacky cpuid disassembly check and set another to the size. RSI doesn't get clobbered by Xen so that would have the target address already. All auto mode need to do at that point is check the parent register values, check for the magic value and proceed with the values found in the other regs.

aashays commented 3 years ago

Thanks for your comments :)

Under what situation would you need to worry about not being paused at the harness site?

I wanted to have at least some basic sanity check on the state of the VM to make it less error prone. Since inferring the wrong address would likely go unnoticed. One realistic concern would be the VM being paused at a breakpoint harness instead of a cpuid harness. Or setup not using an extended-mark -- which I admit isn't caught by the current implementation.

Also, IMHO saving the target address & size to a log during setup and then reading from there should be fairly painless already

It's pretty much what you said about log file logistics. Also I generally don't consider kfx stdout to be a stable API. Using the VM itself to transfer this state for us is less brittle IMO.

To keep all information kept in the VM's state you should stuff them back into vCPU regs after Xen finished processing the CPUID event and its done clobbering the registers

Great idea.. let me work on this and get back to you.

aashays commented 3 years ago

Done. I also decided to drop the "auto"s and reused the --extended-mark flag instead.

tklengyel commented 3 years ago

Thanks!