  Control-Flow Hijacking attacks are the dominant attack vector against C/C++
programs. Control-Flow Integrity (CFI) solutions mitigate these attacks on the
forward edge,i.e., indirect calls through function pointers and virtual calls.
Protecting the backward edge is left to stack canaries, which are easily
bypassed through information leaks. Shadow Stacks are a fully precise mechanism
for protecting backwards edges, and should be deployed with CFI mitigations. We
present a comprehensive analysis of all possible shadow stack mechanisms along
three axes: performance, compatibility, and security. For performance
comparisons we use SPEC CPU2006, while security and compatibility are
qualitatively analyzed. Based on our study, we renew calls for a shadow stack
design that leverages a dedicated register, resulting in low performance
overhead, and minimal memory overhead, but sacrifices compatibility. We present
case studies of our implementation of such a design, Shadesmar, on Phoronix and
Apache to demonstrate the feasibility of dedicating a general purpose register
to a security monitor on modern architectures, and the deployability of
Shadesmar. Our comprehensive analysis, including detailed case studies for our
novel design, allows compiler designers and practitioners to select the correct
shadow stack design for different usage scenarios.
