Description
Return Oriented Programming (ROP) represents a category of code reuse attacks targeting binary programs, wherein attackers leverage gadgets within the program’s code section to gain control of the execution flow.
While the open-source RISC-V architecture presents novel challenges for executing ROP attacks, recent research has demonstrated the feasibility of deploying ROP techniques on this architecture.
Two notable distinctions from the x86 architecture include the split of the function return into two instructions: one for loading the return address from the stack and another for register-based jumps.
Additionally, RISC-V introduces a clear demarcation between preserved registers, which are saved and restored during function calls, and non-preserved registers.
We present two compiler-based transformations that leverage these architectural features to harden binaries against ROP attacks while incurring minimal overhead.
Importantly, these approaches do not rely on hardware-specific features and are designed to ensure compatibility with existing hardening tools.
Early Return Address Load (ERAL) involves extending the minimum lengths of ROP gadgets within function epilogues by relocating the instruction responsible for loading the return address to an earlier point in the function.
Explicit Register Clear (ERC) focuses on instrumenting function epilogues by inserting instructions to clear non-preserved registers just before the return jump.
We implemented both designs as an LLVM compiler pass.
Our evaluation, using state-of-the-art benchmarks, indicates negligible overhead for ERAL, with variable length increases constrained by the structure of the control flow graph.
For ERC, we observed runtime overhead ranging from an average of 0.66% to 5.48%.
Notably, this approach significantly reduces or eliminates gadgets involving non-preserved registers within function epilogues.
|