Video Boffins from ETH Zurich have devised a novel fuzzer for finding bugs in RISC-V chips and have used it to find more than three dozen.
Fuzzing is a technique that involves feeding random input to software or hardware to see how it responds. It’s commonly used for identifying code errors or architectural flaws, and is widely used in the security community.
But current CPU fuzzers have limitations that make them less effective. For example, they may not cover the entire instruction set architecture (ISA) or they may not manage control flow well, which means that bugs get missed. So a new approach is being put to the test.
Flavien Solt and Katharina Ceesay-Seitz, doctoral students at ETH Zurich, and Kaveh Razavi, assistant professor at ETH Zurich, call the project Cascade.
“Flavien started by looking at the test cases that other fuzzers generate and quickly realized that they are either too simple or fail early, which make existing fuzzers largely ineffective,” explained Razavi to The Register. “So he started thinking about how to make arbitrarily long and complex programs? This is what led to the design of Cascade.”
Unlike other CPU fuzzers, Cascade can construct long random programs that manage the control flow during execution. This allows the fuzzer to more thoroughly probe the silicon. The technique is described in a paper [PDF] that’s scheduled to be presented next year at USENIX Security ’24.
What separates Cascade from similar tools is that it relies on a technique called asymmetric ISA pre-simulation.
“The basic idea is to use the ISA simulator to figure out how to entangle the randomized control flow with the randomized data flow,” explained Razavi.
“This entanglement gives some nice properties: the program always terminates correctly on a CPU that executes all of it correctly, despite the randomized control and data flows. So if it doesn’t, it means it triggered a CPU bug. The entanglement also allows Cascade to build arbitrarily large yet highly complex test programs which can fuzz the CPU very efficiently.”
Razavi explained that Cascade initially generates an intermediate program in which the control flow is independent of the data stream, but includes placeholders to add this dependency later.
“Cascade then uses the ISA simulator to figure out how to update these placeholders and makes the control flow dependent on the data flow, generating the ultimate test program,” he said. You can see it in action below.
When applied to six actual RISC-V CPUs – VexRiscv, PicoRV32, Kronos, CVA6, Rocket, and BOOM – Cascade found 37 new bugs (translating to 29 CVEs) in five of these six designs. These flaws, which the authors say have been responsibly disclosed, have consequences such as allowing information leakage, denial of service, control-flow hijacking, missing checks, and spurious exceptions that break isolation boundaries from higher privilege levels.
The ETH Zurich computer scientists claim that compared to other fuzzers like TheHuzz and DifuzzRTL, Cascade achieved similar coverage but 28 to 97 times faster. They also report finding a critical bug in the Yosys framework for Verilog RTL synthesis that results in a wrong netlist.
Razavi said that the RISC-V ISA works well with Cascade because it’s not too complicated. “RISC-V is a simple ISA by construction,” he explained. “That’s where the R in the RISC comes from (R=Reduced). This simplicity made it tractable to build a fuzzer that exercises a large fraction of the functionalities provided by the ISA and implemented by the CPUs.”
“Doing something like Cascade for an ISA such as x86 which is a CISC (C=Complex), while conceptually similar, will be a more massive engineering undertaking. I think someone should do it though!” ®