SHAKTI-MS: a RISC-V processor for memory safety in C
SHAKTI-MS: a RISC-V processor for memory safety in C
I spent 6 months at the start of 2018 working at the reconfigurable intelligent systems lab, during which time I worked on designing a hardware+compiler solution to memory corruption attacks. memory corruption attacks have existed for more than 30 years, and while there have been mitigation strategies like ASLR and stack canaries that make them difficult, there are very few solution that offer total spatial and temporal memory safety without significant overheads.
Related work
Looking at papers previously published on this topic, I came across a few proposed solutions.
- Watchdog:Hardware for safe and secure manual memory management and full memory safety
- WatchdogLite: Hardware-Accelerated Compiler-Based Pointer Checking
- CETS: Compiler-Enforced Temporal Safety for C
- SoftBound: Highly Compatible and Complete Spatial Memory Safety for C
Softbound and CETS are compiler-only solutions based on LLVM. Watchdog and WatchdogLite required special hardware, for which no simulators were available. They all had significant memory and execution time overheads, with up to 300% memory overhead for full spatial and temporal safety in Watchdog.
Our solution
Pointer design
Pointers are 128 bits long. The virtual address space is limited to 32 bits, and the remaining 96 bits are used for storing spatial and temporal metadata.
The structure of a pointer is as follows:
Pointer | Hash | Base | Bound |
---|---|---|---|
0-31 | 32-63 | 64-95 | 96-127 |
Hash is a unique random number assigned to an object at the time of creation. Any pointers refering to it are only valid if they contain the same hash in their metadata. Base and bound determine the range beyond which access with that pointer is deemed illegal. This is also determined at the time of object creation and written to the pointer created to reference the object.
Hardware extension
While a software-only solution was possible (and implemented in early testing), a modified RISC-V core was made with custom instrucitons to accelerate certain tasks performed for pointer creation and validation. The hardware is an extension of IIT Madras’ Shakti Class C processor. In addition to the standard RISCV instruction set, we added two instructions.
Hash
This instruction (poor choice of name, not to be confused with the section of the fat pointer used to store the cookie) writes a random number generated through a hardware random number generator in the core, into the memory location passed through rs1. It then calculates a one-way hash of this number and stores it inside rd1. The IV for the hash function used will be randomly generated on boot for additional security.
Val
The val instruction is inserted by the compiler before any memory access to ensure that the pointer being used is pointing to an object that has not been freed, and that the pointer is not accessing outside its bounds.
Flexibility
Our solution uses modified hardware along with a modified compiler to leverage the modifications to the hardware. We designed the hardware to be fully backwards compatible with existing RISC-V binaries and compilers, to the point where a single program can use both protected and unprotected libraries and objects at the same time. Any objects/libraries compiled with the modified compiler will ensure safety within itself by adding and validating metadata to variables. Calls across protected libraries preserve the metadata, while calls to unprotected libraries will strip the metadata before passing the arguments.
Publication
Published in LCTES 2019: Proceedings of the 20th ACM SIGPLAN/SIGBED International Conference on Languages, Compilers, and Tools for Embedded Systems.