Posted by
Hemos
on from the crushing-them-beneath-your-heel dept.
A reader writes:"There's a story on ZDNet that describes how Theo de Raadt & co. are hoping to eliminate buffer-overrun exploits for good. On closer inspection, it's a scheme to stop a buffer-overrun leading to executable code. It doesn't stop the buffer-overrun itself."
It's a shame that segments work the way they do.
by
wowbagger
·
· Score: 4, Interesting
I'm about to say something I would have never dreamed of saying a couple of years ago.
It is a shame that Intel made segments work the way they do, because a minor tweak and segments would have been the perfect way to prevent buffer overflows in hardware.
Consider: what if, instead of segment descriptors having to live in the GDT and LDT, they could be loaded into a register from a normal memory limit? True, they would then have been useless for OS level protection, but I assert that is what the page map is for (yes, the page mapper didn't exist prior to the 386, and enhanced segments showed up in the 286).
In some of the DSPs that I work with, you have registers to specify a region of memory. When you access off these registers, memory bounds are enforced by the chip (this allows for circular regions of memory, bit reversed addressing, and other weird things you need when doing DSP work).
What if you could have done something like this: buffer:
ds 1024 ; a buffer of stuff buffer_descr:
dd buffer ; where buffer starts
dd 1024 ; sizeof(buffer)...
LDPROT ES,buffer_descr ; set limits checking
LD ES:(ESI),EAX ; store to buffer with checking.
Thus, any access out of bounds would throw a SIGSEGV.
Then, the code could have provided protection against overflows without explicit checking on every array access. True, this would not protect you if all you were given was the buffer address, but in the presense of this sort of hardware, GCC could have been modified to make a char (*a)[] (pointer to array of char) be three elements - base, sizeof(), index.
Includes ProPolice
by
dwheeler
·
· Score: 4, Informative
The buffer overflow work is based on StackGuard,
which was originally developed as a gcc extension
and tried out in Immunix (a Linux distribution).
However, instead of StackGuard, they're using
IBM's ProPolice. ProPolice implements the same
basic idea, but the patch itself works more cleanly
across CPU architectures. Also, ProPolice has
a simple optimization - it only enables the
canary protection if the function has a
char (like) array. This is a heuristic, but
a reasonable one - most buffer overflow attacks
exploit such arrays, and by doing this
ProPolice has a lower performance overhead
(without losing much in the way of protection).
Libsafe only protects a few built-in functions;
it's not a bad idea, but it's FAR less
effective than StackGuard or ProPolice.
The Openwall kernel patch is actually a
collection of nifty capabilities.
The "no executable stack" option is probably
what you mean, but it turns out that there's
a trivial way around it... so that part is
only effective BECAUSE few people use it.
Openwall has other stuff that's nice, though.
I think the reason these capabilities aren't
in use everywhere (yet) is the
conservatism of most distributions.
Many distributions worry about any performance
loss or compatibility loss. OpenBSD's
primary focus is on security, so losing
performance or backwards compatibility is
not as serious an issue for them.
I have hopes that these features will become
more mainstream.
What about stackguard? Why isn't it in use everywhere? Or libsafe for that matter? Or Openwall Project kernel patch for Linux? Can anyone please tell me why no one uses it?
I'm about to say something I would have never dreamed of saying a couple of years ago.
...
It is a shame that Intel made segments work the way they do, because a minor tweak and segments would have been the perfect way to prevent buffer overflows in hardware.
Consider: what if, instead of segment descriptors having to live in the GDT and LDT, they could be loaded into a register from a normal memory limit? True, they would then have been useless for OS level protection, but I assert that is what the page map is for (yes, the page mapper didn't exist prior to the 386, and enhanced segments showed up in the 286).
In some of the DSPs that I work with, you have registers to specify a region of memory. When you access off these registers, memory bounds are enforced by the chip (this allows for circular regions of memory, bit reversed addressing, and other weird things you need when doing DSP work).
What if you could have done something like this:
buffer:
ds 1024 ; a buffer of stuff
buffer_descr:
dd buffer ; where buffer starts
dd 1024 ; sizeof(buffer)
LDPROT ES,buffer_descr ; set limits checking
LD ES:(ESI),EAX ; store to buffer with checking.
Thus, any access out of bounds would throw a SIGSEGV.
Then, the code could have provided protection against overflows without explicit checking on every array access. True, this would not protect you if all you were given was the buffer address, but in the presense of this sort of hardware, GCC could have been modified to make a char (*a)[] (pointer to array of char) be three elements - base, sizeof(), index.
www.eFax.com are spammers
Libsafe only protects a few built-in functions; it's not a bad idea, but it's FAR less effective than StackGuard or ProPolice. The Openwall kernel patch is actually a collection of nifty capabilities. The "no executable stack" option is probably what you mean, but it turns out that there's a trivial way around it... so that part is only effective BECAUSE few people use it. Openwall has other stuff that's nice, though.
I think the reason these capabilities aren't in use everywhere (yet) is the conservatism of most distributions. Many distributions worry about any performance loss or compatibility loss. OpenBSD's primary focus is on security, so losing performance or backwards compatibility is not as serious an issue for them. I have hopes that these features will become more mainstream.
- David A. Wheeler (see my Secure Programming HOWTO)