This is Revizor, a microarchitectural fuzzer. It is a rather unconventional fuzzer as, instead of finding bugs in programs, Revizor searches for microarchitectural vulnerabilities in CPUs.
What is a microarchitectural vulnerability? In the context of Revizor, it is a violation of out expectations about the CPU behavior, expressed as contract violations (see Contracts). The most prominent examples would be Spectre and Meltdown. Alternatively, a "bug" could also be in a form of a microarchitectural backdoor or an unknown optimization, although we are yet to encounter one of those.
See our Paper for details (also in open access here).
Note: If you find missing or confusing explanations, or a bug in Revizor, don't hesitate to open an issue.
Warning: Revizor executes randomly generated code in kernel space. As you can imagine, things could go wrong. We did our best to avoid it and to make Revizor stable, but still, no software is perfect. Make sure you're not running these experiments on an important machine.
So far, Revizor supports only Intel CPUs. It was tested on Intel Core i7-6700 and i7-9700, but it should work on any other Intel CPU just as well.
- Linux v5.6+ (tested on Linux v5.6.6-300 and v5.6.13-100; there is a good chance it will work on other versions as well, but it's not guaranteed).
# check linux version
cat /proc/version
- Linux Kernel Headers
# On Ubuntu
sudo apt-get install linux-headers-$(uname -r)
- MSR Tools
# On Ubuntu
sudo apt install msr-tools
# On Ubuntu 18
sudo apt install python3.9 python3.9-distutils
sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.9 2
sudo update-alternatives --config python3
# you may also need
pip3 install --upgrade setuptools
pip3 install --upgrade pip
pip3 install --upgrade distlib
sudo apt install unicorn
- Python bindings to Unicorn
pip3 install --user unicorn
# OR, if installed from sources
cd bindings/python
sudo make install
- Python packages
pyyaml
,types-pyyaml
,numpy
:
pip3 install --user pyyaml types-pyyaml numpy
Tests:
- Bash Automated Testing System
- mypy
GNU datamash
Documentation:
For more stable results, disable hyperthreading (there's usually a BIOS option for it). If you do not disable hyperthreading, you will see a warning every time you invoke Revizor; you can ignore it.
Optionally (and it really is optional), you can boot the kernel on a single core by adding -maxcpus=1
to the boot parameters (how to add a boot parameter).
In addition, you might want to stop any other actively-running software on the tested machine. We never encountered issues with it, but it might be useful.
cd src/x86/isa_loader
./get_spec.py --extensions BASE SSE SSE2 CLFLUSHOPT CLFSH
cd src/x86/executor
make uninstall # the command will give an error message, but it's ok!
make clean
make
make install
cd src/tests
./runtests.sh
If a few (up to 3) "Detection" tests fail, it's fine, you might just have a slightly different microarchitecture. But if other tests fail - something is broken.
- Fuzz in a violation-free configuration:
./cli.py fuzz -s x86/isa_spec/base.json -i 50 -n 100 -c tests/test-nondetection.yaml
No violations should be detected.
- Fuzz in a configuration with a known contract violation (Spectre V1):
./cli.py fuzz -s x86/isa_spec/base.json -i 20 -n 1000 -c tests/test-detection.yaml
A violation should be detected within a few minutes, with a message similar to this:
================================ Violations detected ==========================
Contract trace (hash):
0111010000011100111000001010010011110101110011110100000111010110
Hardware traces:
Inputs [907599882]:
_____^______^______^___________________________________________^
Inputs [2282448906]:
___________________^_____^___________________________________^_^
Congratulations, you just found your first Spectre! You can find the violating test case in generated.asm
.
To start a real fuzzing campaign, write your own configuration file (see description here and an example config here), and launch the fuzzer.
Below is a example launch command, which will start a 24-hour fuzzing session, with 50 input classes per test case:
./cli.py fuzz -s x86/isa_spec/base.json -c tests/big-fuzz.yaml -i 50 -n 100000000 --timeout 86400 -w `pwd` --nonstop
For more examples, see the demo/
directory.
The fuzzer is controlled via a single command line interface cli.py
(located in src/cli.py
). It accepts the following arguments:
-s, --instruction-set PATH
- path to the ISA description file-c, --config PATH
- path to the fuzzing configuration file-n , --num-test-cases N
- number of test cases to be tested-i , --num-inputs N
- number of input classes per test case. The number of actual inputs = input classes * inputs_per_class, which is a configuration option-t , --testcase PATH
- use an existing test case instead of generating random test cases--timeout TIMEOUT
- run fuzzing with a time limit [seconds]--nonstop
- don't stop after detecting a contract violation-w
- working directory where the detected violations will be stored
For more details, see docs/main.md.
This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.
When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.
This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.
This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow Microsoft's Trademark & Brand Guidelines. Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos are subject to those third-party's policies.