Hardening Linux against buffer overflows
[Posted May 6, 2003 by corbet]
Whenever kernel hacker Ingo Molnar disappears for a while, it is reasonable
to expect that he will resurface with some interesting new development. In
the past, he has materialized with the TUX in-kernel web server, the O(1)
scheduler, and the new kernel threads implementation. His most recent
offering, however, has to do with making Linux systems more resilient in
the face of buffer overflow vulnerabilities.
The new "Exec Shield" patch (which applies
to the 2.4.21 release candidate kernel) takes several steps to fight buffer
overflows, including:
- Engaging in some x86 segmentation magic to minimize the range of
addresses where the processor can execute code. This approach is
essentially a hack to work around the inconvenient fact that the x86
architecture lacks a page table flag for controlling execute
permission. By playing with segments, this patch makes it impossible
to execute code on the stack and in as much of the data area as
possible. As a result, the execution of exploit code delivered via
buffer overflows becomes far more difficult.
- As much executable code as possible is moved into the lowest part
of the virtual address space - below 16MB. Addresses in this range
begin with a zero byte, making them hard to create with purely ASCII
overflows. Many applications which deal with C strings cannot be
overflowed with a string containing NULL bytes. Others, of course,
will read any sort of data and will not be affected by this particular
change. For applications for which this measure is effective, however
(and that set includes most web-based applications), this shift into
the "ASCII armor" area will block exploits which work by jumping into
library code which might, say, execute a shell.
- A subsequent release of the patch
includes shared library and stack address randomization. These
measures make mass exploits harder, since each target process is
different.
This approach, note, is different from that used in the recent OpenBSD 3.3 release. OpenBSD does not (yet)
provide executable stack protection on the x86 architecture; instead, it
relies on detecting buffer overflows with a modified compiler that installs
(and checks) "canaries" on the stack. The OpenBSD "W^X" execute permission
control will be extended to the x86 architecture in 3.4.
So does this approach bring any real security? Non-executable stack
patches have failed to get into the Linux kernel before, since Linus does not believe in
them:
In short, anybody who thinks that the non-executable stack gives
them any real security is very very much living in a dream
world. It may catch a few attacks for old binaries that have
security problems, but the basic problem is that the binaries allow
you to overwrite their stacks.
The real solution, says Linus, is to fix the applications. That is
undoubtedly true, but fixing all of the applications out there (and keeping
them fixed) is not an easy task. In the meantime, raising the bar for
potential attackers may well be the right thing to do. It would not be
surprising to see this patch find its way into the kernels shipped by the
major distributors, even if Linus does not accept it into the mainline.
(
Log in to post comments)