  CPU registers are small discrete storage units, used to hold temporary data
and instructions within the CPU. Registers are not addressable in the same way
memory is, which makes them immune from memory attacks and manipulation by
other means. In this paper, we take advantage of this to provide a protection
mechanism for critical program data; both active local variables and control
objects on the stack. This protection effectively eliminates the threat of
control- and data-oriented attacks, even by adversaries with full knowledge of
the active stack. Our solution RegGuard, is a compiler register allocation
strategy that utilises the available CPU registers to hold critical variables
during execution. Unlike conventional allocations schemes, RegGuard prioritises
the security significance of a program variable over its expected performance
gain. Our scheme can deal effectively with saved registers to the stack, i.e.,
when the compiler needs to free up registers to make room for the variables of
a new function call. With RegGuard, critical data objects anywhere on the
entire stack are effectively protected from corruption, even by adversaries
with arbitrary read and write access. While our primary design focus is on
security, performance is very important for a scheme to be adopted in practice.
RegGuard is still benefiting from the performance gain normally associated with
register allocations, and the overhead is within a few percent of other
unsecured register allocation schemes for most cases. We present detailed
experiments that showcase the performance of RegGuard using different benchmark
programs and the C library on ARM64 platform.
