Slashdot Mirror


OpenBSD Stomping On Buffer Overflows

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."

7 of 47 comments (clear)

  1. Re:New idea? by Anonymous Coward · · Score: 3, Informative
  2. What about by Anonymous Coward · · Score: 4, Interesting

    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?

  3. Already slashdotted by Anonymous Coward · · Score: 3, Informative

    Software tweak may make operating systems safer
    09:43 Monday 14th April 2003
    Robert Lemos, CNET News.com

    The OpenBSD project is making changes in its latest operating system release that it believes could eliminate a class of security bugs that has plagued computers for decades

    The OpenBSD project hopes new changes to its latest release will eliminate "buffer overflows", a software issue that has been plaguing security experts for more than three decades.

    Theo de Raadt, the project leader for the group, believes that the group's latest improvements to the Unix variant, due to be released on 1 May, will make causing a buffer overflow extremely difficult, if not impossible. A buffer overflow is a memory error in software that allows an attacker to run a malicious program.

    "I could say that I am killing buffer overflows, but I am in the security community, so I have to put it in quotes," he told attendees at the CanSecWest security show on Thursday.

    The memory bugs have resisted extermination for almost 30 years, and de Raadt said that any claims that an open-source group has done so would need to be tested.

    Some attendees are already incredulous that the changes will eliminate buffer overflows. "It's just adding another layer" to the security, said Nicolas Fischbach, senior manager for security at Colt Telecom, a European communications provider. "It won't make a huge difference because there are always bugs that are found in software."

    An overflow exploit generally works when an attacker sends a program requesting too much information. The data usually includes two components: one that crashes the application and one that's either a program or a memory address that points to a program that the attacker would like to run. When the application crashes due to the first component, the operating system will execute the second.

    The OpenBSD team hardened the operating system to this type of attack using three tactics.

    The group randomised where in memory the "stack" -- a structure that holds applications and their data -- resides, so that code designed to exploit buffer overflows will have to be tailored to the system's memory layout.

    "Buffer overflows take advantage of a certain memory layout," de Raadt said. "It's a tiny waste of memory, with very little overhead, but it makes things a little bit more difficult. We are trying to make the (code) crackers work a little bit more."

    In addition, the group restructured how critical addresses are stored on the stack, so that it's harder to get buffer overflows to result in a running program. The team placed a small tag, called a canary, in the memory structure to detect if addresses had been modified, a common method hackers use to get a legitimate program to run malicious code.

    Finally, the group found a way to hack the BSD file system and divide main memory into a writable portion and an executable portion. Pieces of programs and data, known as pages, that are stored to memory will be placed into one of the two areas.

    "We want to make sure that no page is both executable or writable simultaneously," he said. "The goal is that no hackers should be able to write code and then execute it."

    The problem for the OpenBSD group is that while 64-bit processors have such memory protections available, the most-popular 32-bit processors don't. So the group has had to work around the issue and break up a computer's memory into writable and executable areas.

    "You can draw a line in the sand -- before that line you can execute, above you can't," de Raadt said.

    While the other security features will be available in the 1 May release, the protected memory page structure for 32-bit processors -- such as Intel x86 chips and the PowerPC chips -- won't be ready for another six months, he said.

    The research was funded by a $2.3m (about £1.5m) grant from the Defense Advanced Research Projects Agency (DARPA) to the OpenBSD Project, but the latest changes go be

  4. 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.

  5. Is the randomization per machine, per build, etc? by blinka · · Score: 3, Interesting
    It's hard to be sure from the article itself (given that reporters are unlikely to understand the distinction, much less care), but in what way is this stack manipulation random? Quoting the article:

    The group randomised where in memory the "stack" -- a structure that holds applications and their data -- resides, so that code designed to exploit buffer overflows will have to be tailored to the system's memory layout.

    but this is still vague. It could be:

    • Per kernel. (All processes on this box have the same stack layout)
    • Per process. (All processes have a different stack layout, though threads and forked versions may have the same.)
    • Per binary. (Each program's stack layout is determined at compile time and will not change on invocation.)
    • Completely random (Each program is different every time, or better yet each function call is different each time.)
    This would have a very import impact on how well a hacker could brute force your processes. If a given process always has the same stack layout then you can eventually brute force it, just like we currently can brute force offsets. The bar is higher of course - only one variable is being manipulated - and a hacker will probably go to easier machines before too long. But a truly randomized per process invocation or better yet per function call invocation would be such a moving target that it should be extreemly unlikely to succeed. I'm really excited.
  6. buffer over flow exploits not truly eliminated by mzs · · Score: 3, Interesting

    It is clear from gems like this from the article that the reporter was confused so that it is impossible from the article itself to really undrestand how the three approaches would work:

    "An overflow exploit generally works when an attacker sends a program requesting too much information. The data usually includes two components: one that crashes the application and one that's either a program or a memory address that points to a program that the attacker would like to run. When the application crashes due to the first component, the operating system will execute the second.

    It is important to point out that this looks to be yet another in the attempts at making buffer over flow exploits difficult yet not quite impossible. Once you put return addresses on the stack (the same stack with an over flow) an exploit can jump to any place it likes in text even without an executable stack.

    The details about the tag around import addresses and the random stack offsets could make exploits _very_ difficult. If the base of the stack is random from one invocation of the program to the next that does not give much more once you cannot execute on the stack so it is probably more than that. Also if the tag around important addresses (say the address of the buffer to system(3C)) incorpates randomness from one invocation of the program to the next then it would be hard to over flow a buffer and exploit it.

    In any case even if you had a sytem where a buffer over flow could not be exploited to run arbitrary code but almost any random junk will still crash the broken prorgam, that does not do much to prevent DoS now does it.

  7. 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.

    --
    - David A. Wheeler (see my Secure Programming HOWTO)