Hardening Linux against buffer overflows
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:
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.
