The Boston Diaries

The ongoing saga of a programmer who doesn't live in Boston, nor does he even like Boston, but yet named his weblog/journal “The Boston Diaries.”

Go figure.

Friday, June 26, 2015

There's no reason for C to have just a single stack

This patch adds the safe stack instrumentation pass to LLVM, which separates the program stack into a safe stack, which stores return addresses, register spills, and local variables that are statically verified to be accessed in a safe way, and the unsafe stack, which stores everything else. Such separation makes it much harder for an attacker to corrupt objects on the safe stack, including function pointers stored in spilled registers and return addresses. You can find more information about the safe stack, as well as other parts of or control-flow hijack protection technique in our OSDI paper on code-pointer integrity (http://dslab.epfl.ch/pubs/cpi.pdf) and our project website (http://levee.epfl.ch).

Via Hacker News, Protection against stack-based memory corruption errors using SafeStack ⋅ llvm-mirror/llvm@7ffec83

I'm really surprised this wasn't done sooner. There's nothing in the C Standard that mandates how the call stack must be implemented, but it seems that for the past forty years or so, the system stack (the stack the CPU uses to store return addresses for subroutine calls or state information when handling interrupts) has been the default place to store the call stack, which is the prime reason why buffer overflows are so dangerous (because with a buffer overrun, the attacker can embed machine code and cause the CPU to return to the embedded machine code to do nefarious things). Sure, it might appear that dedicating another CPU register to point to this secondary stack might be wasteful, but most C compilers on modern systems already use a second CPU register to point to the primary stack (to make it easier to generate stack frames when debugging or analyzing a core dump). Also, the system stack wouldn't have to be so big—even an 8K stack on a 64-bit machine would easily allow a call-depth (A calls B which calls C which calls D is a call-depth of 4) of over 500 (technically, 1,024 but this would disallow other uses of the stack, such as temporarily saving registers, or handling of interrupts) which should handle most programs (the exception being badly written programs with unbounded recursion; sidenote to Google: good one, you got me).

This patch, however, seems to still save the call stack in the system stack with the exeception of arrays or items whose address is taken, and it stores the pointer to the “unsafe stack” in a thread-specific variable. It turns out the performance loss isn't that bad as most routines don't have such problematic variables to begin with.

Obligatory Picture

[It's the most wonderful time of the year!]

Obligatory Contact Info

Obligatory Feeds

Obligatory Links

Obligatory Miscellaneous

You have my permission to link freely to any entry here. Go ahead, I won't bite. I promise.

The dates are the permanent links to that day's entries (or entry, if there is only one entry). The titles are the permanent links to that entry only. The format for the links are simple: Start with the base link for this site: http://boston.conman.org/, then add the date you are interested in, say 2000/08/01, so that would make the final URL:

http://boston.conman.org/2000/08/01

You can also specify the entire month by leaving off the day portion. You can even select an arbitrary portion of time.

You may also note subtle shading of the links and that's intentional: the “closer” the link is (relative to the page) the “brighter” it appears. It's an experiment in using color shading to denote the distance a link is from here. If you don't notice it, don't worry; it's not all that important.

It is assumed that every brand name, slogan, corporate name, symbol, design element, et cetera mentioned in these pages is a protected and/or trademarked entity, the sole property of its owner(s), and acknowledgement of this status is implied.

Copyright © 1999-2021 by Sean Conner. All Rights Reserved.