Bugtraq mailing list archives
Re: machine independent protection from stack-smashing attack
From: John Viega <viega () LIST ORG>
Date: Thu, 10 Aug 2000 09:05:57 -0700
Our understanding is that the biggest reason why StackGuard hasn't been ported to more architectures is that there's not really a portable source of randomness available, such as a /dev/random. It wouldn't be all that hard to just port StackGuard to each architecture; sure, you would either need to add architecture-dependent code for each platform, or it would need to be rewritten in a way that operated on the GCC internal representation (which may or may not require a compiler change to allow easy access to the return address) However, neither is all that hard. Moreover, one of these solutions is potentially necessary. In particular, you fall prone to the problem that Crispan recently had to fix with StackGuard; the canary is not bound to the actual return address, so in some cases it is possible to "jump" the canary. You are using boundary canarys instead of xor canarys. Sure, you're lining up arrays next to each other, but that doesn't solve every case. Consider the following example, slightly modified from the StackGuard page: foo(char * arg) { char * p[1]; // a vulnerable pointer char a[25]; // the buffer that makes the pointer vulnerable p[0] = arg; gets(a); // using gets() makes you vulnerable gets(p[0]); // this is the good part } You could fix this particular problem by having one guard variable per buffer. However, we're not completely convinced that there still wouldn't be some way to circumvent the mechanism; We feel much better when the return address is actually tied in, for example, by XORing in the canary. Another problem comes up in the section on "pointer protection". Let's say you have the following code: void f(int x, void (*p)()){ void (**p2)() = &p; ... } Assuming we understand you correctly, it is effectively rewritten as such: void f(int x, void (*p)()){ void (*tmp1)(); void (**p2)() = &tmp1; ... } Even though you assert otherwise, this does break the ANSI C standard, because the standard requires the value of p2 to equal to the address following &x. Nonetheless, we don't think this is such a horrible way to break the standard, given the protection it affords and the rarity of programs that rely on this behavior. In short, we believe the following: 1) Your patch is not all that portable because of its reliance on a source for secure random numbers, for which there is not currently a portable solution. 2) StackGuard provides better protection in most cases, and wouldn't be all that hard to port. 3) We do like your idea of moving variables around and protecting function pointers, even if it isn't perfect. However, it really does need to be integrated in a way that doesn't defeat anyone's expectations when using the compiler, yet still affords people protection by default. Note that this kind of protection doesn't need to be implemented as a compiler hack. We've written a tool along with Greg Hoglund that we call SO WHAT. It works with Visual C++ by wrapping the compiler with a preprocessor. The preprocessor inserts assembly code at the beginning of functions, and prior to function returns. At the beginning of the function, the return address is XOR'd with a canary. At the exit points, it is XOR'd back. This technique doesn't give you the chance to recover from attacks gracefully because if there's an attack, you jump to a random memory address. However, this could be fixed pretty easily by sticking the XOR'd canary into the first local instead of just XORing the return address directly; we were just building something quick and dirty. The advantage here is that you can port this technique to any compiler on any platform just by adding a few lines of assembly, and then writing a small bit of code to hook the thing up to a compiler (one thing you have to do is always make sure that frame pointer omission is turned off on most platforms). We basically provide the exact same protection you get by using StackGuard, but implemented in a way that's easy to port to any platform and compiler. All you need is a good random number generator. We'll probably release the tool for free once we finish building a good entropy accumulator for NT (and validate our Yarrow implementation), so that we can be confident of the quality of our random numbers. We expect that to be about two months. In the meantime, it would be really easy to port this to any platform using GCC that has managed to install /dev/random, if there's interest in that. John Viega and Tim Hollebeek On Wed, Aug 09, 2000 at 06:59:49PM +0900, Hiroaki Etoh wrote:
I have been investigating a machine-independent change to GCC that would generate code to protect applications from stack-smashing attacks. The main characteristics are low performance overhead of the protection code, protecting against different varieties of stack-smashing attacks, and supporting various processors. A research report is ready on the web (http://www.trl.ibm.co.jp/projects/security/propolice). I would like some feedback whether it is worth pursuing getting it assigned to the FSF for inclusion in GCC. --- Hiroaki Etoh, Tokyo Research Laboratory, IBM Japan
Current thread:
- machine independent protection from stack-smashing attack Hiroaki Etoh (Aug 09)
- Re: machine independent protection from stack-smashing attack John Viega (Aug 10)
- Re: machine independent protection from stack-smashing attack Yarrow Charnot (Aug 15)
- Re: machine independent protection from stack-smashing attack Ariel Waissbein (Aug 18)
- PRNGs (was Re: machine independent protection from stack-smashing attack) John Viega (Aug 18)
- Re: PRNGs (was Re: machine independent protection from stack-smashingattack) Crispin Cowan (Aug 18)
- Re: PRNGs (was Re: machine independent protection from stack-smashingattack) Andrea Glorioso (Aug 21)
- Re: PRNGs (was Re: machine independent protection from stack-smashingattack) John Viega (Aug 22)
- Re: machine independent protection from stack-smashing attack Yarrow Charnot (Aug 15)
- Re: machine independent protection from stack-smashing attack John Viega (Aug 10)
- Re: machine independent protection from stack-smashing attack Gerardo Richarte (Aug 18)
- <Possible follow-ups>
- Re: machine independent protection from stack-smashing attack Hiroaki Etoh (Aug 15)
- Re: machine independent protection from stack-smashing attack John Viega (Aug 15)
- Re: machine independent protection from stack-smashing attack der Mouse (Aug 18)