Note
Refer to the end of the file for instructions for artifact evaluation, but make sure to read these more generic notes first.
This directory provides the implementation of RISCover. RISCover is split into server and client.
The framework largely depends on Nix for package retrieval.
If not done already run direnv allow.
This should expand FRAMEWORK_ROOT and load the needed packages.
The server generates inputs, receives outputs from the clients, compares them and logs reproducers on differences. The server is implemented in Python and can be started like:
python server/diffuzz-server.py --floats --seq-len 5 --generator RandomDiffFuzzGeneratorThe server logs results in results/ as YAML reproducer files.
The file format is as follows:
results/reproducers/reproducer-00000100-000001218860.yaml
00000100: 100th reproducer of the current run.000001218860: Difference (reproducer) occurred after 1218860 inputs.
To quickly skim over these reproducers run:
for dir in results/reproducers/*; do find "$dir" -maxdepth 1 -type f | head -n 1; done | xargs bat --style=header --line-range :50The main client of RISCover is the diffuzz-client, implemented in client/src/diffuzz-client.c.
It runs instructions sequences and sends the resulting state to the server.
The client compilation depends on the flags used by the server. To generate the set of build flags run:
python server/diffuzz-server.py --floats --seq-len 5 --generator RandomDiffFuzzGenerator --print-flags
This prints:
-DMAX_SEQ_LEN=5 -DWITH_REGS -DCOMPRESS_RECV -DFLOATS
This can be used to build the client like:
build-client --build-flags "-DMAX_SEQ_LEN=5 -DWITH_REGS -DCOMPRESS_RECV -DFLOATS" --target diffuzz-client --out diffuzz-clientThis produces a static binary diffuzz-client which can be copied to any Linux machine, including Android (e.g., via Termux).
The client can then be started like:
./diffuzz-client <server-ip> <server-port>Reproducer files (yaml) can be compiled to static binaries for quick reproduction. The framework provides multiple commands for that.
init-repro-template produces a C program that can be compiled and run:
init-repro-template results/reproducers/reproducer-00000100-000001218860.yamlCreates a file results/reproducers/reproducer-00000100-000001218860.c.
This file can then be compiled with:
build-repro results/reproducers/reproducer-00000100-000001218860.cThis produces a static binary results,reproducers,reproducer-00000100-000001218860.
build-repro-run-on allows for quickly building and running on a machine using ssh:
build-repro-run-on results/reproducers/reproducer-00000100-000001218860.c -- <ssh/hostname>init-build-run-on allows for quickly initializing, building and running on a machine using ssh:
init-build-run-on results/reproducers/reproducer-00000100-000001218860.yaml -- -- <ssh/hostname>For all these scripts the following flags can be used:
--orig-seq: Use the original bytes as sequence and not assemble the recovered assembly instructions.--no-sig: Build the reproducer without signal handling, i.e., plain. This is not that useful for the reproducers generated byarchitectural-sc-fuzzer.
The server accepts various flags, which can be inspected by calling:
python server/diffuzz-server.py --helpImportant
For the offline sequence generation, a server that can execute RISC-V binaries is needed. binfmt is a good option for non-RISC-V machines.
The most relevant ones are:
--filter-thead: Filter out halting T-Head sequences and GhostWrite to not crash the machines.--print-flags: Print the flags needed to be used to compile the client viabuild-client --build-flags "<FLAGS>".--seq-len: The used sequence length.--weighted: If weighted generation should be used.--floats: If FP-support should be enabled.--vector: If vector-support should be enabled.--seed: The RNG seed.--generator: The generator,RandomDiffFuzzGeneratorfor on-server,OfflineRandomDiffFuzzGeneratorfor on-device generation.
To evaluate the artifact we propose a differential fuzzing campaign using T-Head XuanTie C910 and another RISC-V machine. We will initially fuzz without vector support so the C910 does not crash due to GhostWrite.
The following commands must be executed within the directory of this file (RISCover_framework) on the fuzzing server.
First, obtain the flags to compile the client:
$ python server/diffuzz-server.py --floats --seq-len 5 --generator RandomDiffFuzzGenerator --print-flags
(...)
-DMAX_SEQ_LEN=5 -DWITH_REGS -DCOMPRESS_RECV -DFLOATSThen, compile the client:
$ build-client --build-flags "-DMAX_SEQ_LEN=5 -DWITH_REGS -DCOMPRESS_RECV -DFLOATS" --target diffuzz-client --out diffuzz-client-novec
(...)
ELF hash is: cdb6dd0750231c1ccc34ac9ebc04374dNow, you can copy the diffuzz-client-novec binary to the C910 and the other machine.
Once this is done, the server can be started:
$ python server/diffuzz-server.py --floats --seq-len 5 --generator RandomDiffFuzzGenerator
(...)
Press Enter to begin.When the server is ready, you can ssh to the C910 and the other machine and start the diffuzz-client-novec binary:
$ ./diffuzz-client-novec <ip-of-server> 1337
(...)
Connected!Now you can press Enter in the server terminal and watch as reproducers start coming in. You can now terminate the server and clients.
To run the reproducers, you can follow the instructions above.
If you follow the steps above but compile with vector support (--vector in addition to --floats), the C910 should hang almost instantly after starting the fuzzing campaign, indicating that GhostWrite (in the vector extension) was triggered.