Linux: Exec Shield Overflow Protection

Submitted by Jeremy
on May 3, 2003 - 7:26am

Ingo Molnar [interview] has announced a new kernel-based security feature for Linux/x86 called "Exec Shield". He describes the patch, which is against the 2.4.20-rc1 kernel, as:

"The exec-shield feature provides protection against stack, buffer or function pointer overflows, and against other types of exploits that rely on overwriting data structures and/or putting code into those structures. The patch also makes it harder to pass in and execute the so-called 'shell-code' of exploits. The patch works transparently, ie. no application recompilation is necessary."

Ingo goes on to provide a lengthy and quite informative description of Exec Shield, beginning with a little background describing the problem that the patch works to fix. This is followed with a longer section devoted to describing how the solution has been implemented, followed by an examination of its limitations. The final section describes how the patch is installed and used. Read on for Ingo's excellent writeup, and some of the resulting discussion.


From: Ingo Molnar
To: linux-kernel mailing list
Subject: [Announcement] "Exec Shield", new Linux security feature
Date: Fri, 2 May 2003 12:37:23 -0400 (EDT)

We are pleased to announce the first publically available source code
release of a new kernel-based security feature called the "Exec Shield",
for Linux/x86. The kernel patch (against 2.4.21-rc1, released under the
GPL/OSL) can be downloaded from:

	http://redhat.com/~mingo/exec-shield/

The exec-shield feature provides protection against stack, buffer or
function pointer overflows, and against other types of exploits that rely
on overwriting data structures and/or putting code into those structures.
The patch also makes it harder to pass in and execute the so-called
'shell-code' of exploits. The patch works transparently, ie. no
application recompilation is necessary.

Background:
-----------

It is commonly known that x86 pagetables do not support the so-called
executable bit in the pagetable entries - PROT_EXEC and PROT_READ are
merged into a single 'read or execute' flag. This means that even if an
application marks a certain memory area non-executable (by not providing
the PROT_EXEC flag upon mapping it) under x86, that area is still
executable, if the area is PROT_READ.

Furthermore, the x86 ELF ABI marks the process stack executable, which
requires that the stack is marked executable even on CPUs that support an
executable bit in the pagetables.

This problem has been addressed in the past by various kernel patches,
such as Solar Designer's excellent "non-exec stack patch". These patches
mostly operate by using the x86 segmentation feature to set the code
segment 'limit' value to a certain fixed value that points right below the
stack frame. The exec-shield tries to cover as much virtual memory via the
code segment limit as possible - not just the stack.

Implementation:
---------------

The exec-shield feature works via the kernel transparently tracking
executable mappings an application specifies, and maintains a 'maximum
executable address' value. This is called the 'exec-limit'. The scheduler
uses the exec-limit to update the code segment descriptor upon each
context-switch. Since each process (or thread) in the system can have a
different exec-limit, the scheduler sets the user code segment dynamically
so that always the correct code-segment limit is used.

the kernel caches the user segment descriptor value, so the overhead in
the context-switch path is a very cheap, unconditional 6-byte write to the
GDT, costing 2-3 cycles at most.

Furthermore, the kernel also remaps all PROT_EXEC mappings to the
so-called ASCII-armor area, which on x86 is the addresses 0-16MB. These
addresses are special because they cannot be jumped to via ASCII-based
overflows. E.g. if a buggy application can be overflown via a long URL:

  http://somehost/buggy.app?realyloooooooooooooooooooong.123489719875

then only ASCII (ie. value 1-255) characters can be used by attackers. If
all executable addresses are in the ASCII-armor, then no attack URL can be
used to jump into the executable code - ie. the attack cannot be
successful. (because no URL string can contain the \\0 character.) E.g. the
recent sendmail remote root attack was an ASCII-based overflow as well.

With the exec-shield activated, and the 'cat' binary relinked into the the
ASCII-armor, the following layout is created:

  $ ./cat-lowaddr /proc/self/maps
  00101000-00116000 r-xp 00000000 03:01 319365     /lib/ld-2.3.2.so
  00116000-00117000 rw-p 00014000 03:01 319365     /lib/ld-2.3.2.so
  00117000-0024a000 r-xp 00000000 03:01 319439     /lib/libc-2.3.2.so
  0024a000-0024e000 rw-p 00132000 03:01 319439     /lib/libc-2.3.2.so
  0024e000-00250000 rw-p 00000000 00:00 0
  01000000-01004000 r-xp 00000000 16:01 2036120    /home/mingo/cat-lowaddr
  01004000-01005000 rw-p 00003000 16:01 2036120    /home/mingo/cat-lowaddr
  01005000-01006000 rw-p 00000000 00:00 0
  40000000-40001000 rw-p 00000000 00:00 0
  40001000-40201000 r--p 00000000 03:01 464809     locale-archive
  40201000-40207000 r--p 00915000 03:01 464809     locale-archive
  40207000-40234000 r--p 0091f000 03:01 464809     locale-archive
  40234000-40235000 r--p 00955000 03:01 464809     locale-archive
  bfffe000-c0000000 rw-p fffff000 00:00 0

In the above layout, the highest executable address is 0x01003fff, ie.
every executable address is in the ASCII-armor.

this means that not only the stack is non-executable, but lots of
mmap()-ed data areas and the malloc() heap is non-executable as well.  
(some data areas are still executable, but most of them are not.)

the first 1MB of the ASCII-armor is left unused to provide NULL pointer
dereference protection and leave space for 16-bit emulation mappings used
by XFree86 and others.

Compare this with the memory layout without exec-shield:

  08048000-0804b000 r-xp 00000000 16:01 3367       /bin/cat
  0804b000-0804c000 rw-p 00003000 16:01 3367       /bin/cat
  0804c000-0804e000 rwxp 00000000 00:00 0
  40000000-40012000 r-xp 00000000 16:01 3759       /lib/ld-2.2.5.so
  40012000-40013000 rw-p 00011000 16:01 3759       /lib/ld-2.2.5.so
  40013000-40014000 rw-p 00000000 00:00 0
  40018000-40129000 r-xp 00000000 16:01 4058       /lib/libc-2.2.5.so
  40129000-4012f000 rw-p 00111000 16:01 4058       /lib/libc-2.2.5.so
  4012f000-40133000 rw-p 00000000 00:00 0
  bffff000-c0000000 rwxp 00000000 00:00 0

In this layout none of the executable areas are in the ASCII-armor, plus
the exec-limit is 0xbfffffff (3GB) - ie. including all userspace mappings.

Note that the kernel will relocate every shared-library to the
ASCII-armor, but the binary address is determined at link-time. To ease
the relinking of applications to the ASCII-armor, Arjan Van de Ven has
written a binutils patch (binutils-2.13.90.0.18-elf-small.patch), which
adds a new 'ld' flag "ld -melf_i386_small" (or "gcc -Wl,-melf_i386_small")
to relink applications into the ASCII-armor. (The patch can be found at
the exec-shield URL as well.)

Overhead:
---------

the patch was designed to be as efficient as possible. There's a very
minimal (couple of cycles) tracking overhead for every PROT_MMAP
system-call, plus there's the 2-3 cycles cost per context-switch.

Limitations:
------------

This feature will not protect against every type of attack.

E.g. if an overflow can be used to overwrite a local variable which
changes the flow of control in a way that compromises the system. But we
do believe that this feature will stop every attack that is purely
operating by overflowing the return address on the stack, or overflowing a
function pointer in the heap. Furthermore, exec-shield makes it quite hard
to mount a successful attack even in the other cases, because it inhibits
the execution of exploit shell-code, in most cases.

also, if the overflow is within the exec-shield itself (e.g. within the
data section of one of the shared library objects in the ASCII-armor) then
the overflow might be possible to exploit.

All in one, exec-shield is one barrier against attacks, not blanket 100%
protection in any way. The most efficient security can be provided by
installing as many layers as possible.

To provide as good protection as possible, there's no trampoline
workaround in the exec-shield code - ie. exec-limit violations in the
trampoline case are never let through. Applications that need to rely on
gcc trampolines will have to use the per-binary ELF flag to make the stack
executable again. (The ELF flag is the same as used by Solar Designer's
non-exec stack patch, to provide as much compatibility with existing
non-exec-stack installations as possible.)

The exec-shield feature will uncover applications that incorrectly assumed
that PROT_READ allows execution on x86. One such example is the XFree86
module loader. The latest XFree86 on rawhide.redhat.com fixes this
problem. For those who cannot install the XFree86 bugfix at the moment
there's a workaround added by the patch, which can be activated via:

    echo 1 > /proc/sys/kernel/X-workaround

This will make every iopl() using application (such as X) have the
exec-shield disabled. Other applications (sendmail, etc.) will still have
the exec-shield enabled. This workaround is default-off. We strongly
encourage to solve this problem by upgrading X, or by using the 'chkstk'
utility to make X's stack forced-executable.

Using it:
---------

Apply the exec-shield-2.4.21-rc1-B6 kernel patch to the 2.4.21-rc1 kernel,
recompile & install the kernel and reboot into it, that's all.

There is a new boot-time kernel command line option called exec-shield=,
which has 4 values. Each value represents a different level of security:

 exec-shield=0    - always-disabled
 exec-shield=1    - default disabled, except binaries that enable it
 exec-shield=2    - default enabled, except binaries that disable it
 exec-shield=3    - always-enabled

the current patch defaults to 'exec-shield=2'. The security level can also
be changed runtime, by writing the level into /proc:

  echo 0 > /proc/sys/kernel/exec-shield

IMPORTANT: security-relevant applications that were started while the
exec-shield was disabled, will have an executable stack and will thus have
to be restarted if the exec-shield is enabled again.

I've also uploaded a modified version of Solar Designer's chstk.c code,
which adds the options necessary to change the 'enable non-exec stack' ELF
flag:

  $ ./chstk
  Usage: ./chstk OPTION FILE...
  Manage stack area executability flag for binaries

    -e    enable execution permission
    -E    enable non-execution permission
    -d    disable execution permission
    -D    disable non-execution permission
    -v    view current flag state

ie. there are two distinct flags, one for forcing an executable stack, one
for forcing a non-executable stack. If both flags are zero then the binary
will follow the system default.

ie. it's possible to use an exec-shield level of 1, and enable the
non-exec stack on a per binary basis, by using the 'exec-shield=1' boot
option and changing binaries one at a time:

   ./chstk -E /usr/sbin/sendmail

(People migrating production environments to an exec-shield kernel might
prefer this variant.)

anyway, comments, suggestions and test feedback is welcome.

	Ingo


From: Davide Libenzi Subject: Re: [Announcement] "Exec Shield", new Linux security feature Date: Fri, 2 May 2003 10:12:56 -0700 (PDT) On Fri, 2 May 2003, Ingo Molnar wrote: > > We are pleased to announce the first publically available source code > release of a new kernel-based security feature called the "Exec Shield", > for Linux/x86. The kernel patch (against 2.4.21-rc1, released under the > GPL/OSL) can be downloaded from: > > http://redhat.com/~mingo/exec-shield/ > > The exec-shield feature provides protection against stack, buffer or > function pointer overflows, and against other types of exploits that rely > on overwriting data structures and/or putting code into those structures. > The patch also makes it harder to pass in and execute the so-called > 'shell-code' of exploits. The patch works transparently, ie. no > application recompilation is necessary. [ very cool stuff ] Ingo, do you want protection against shell code injection ? Have the kernel to assign random stack addresses to processes and they won't be able to guess the stack pointer to place the jump. I use a very simple trick in my code : #define MAX_STKSHIFT 1024 struct thrunner { int (*proc)(void *); void *data; } static int thread_runner(void *data) { struct thrunner *thr = data; alloca(myrand(MAX_STKSHIFT)); return thr->proc(thr->data); } int my_thread_create(int (*proc)(void *), void *data) { struct thrunner *thr; ... thr->proc = proc; thr->data = data; pthread_create(..., thread_runner, thr, ... ); ... } int main(int argc, char *argv[]) { mysrand(); ... } Same thing can be done for non threaded programs : int main(int argc, char *argv[]) { mysrand(); alloca(myrand(MAX_STKSHIFT)); return real_main(argc, argv); } Yes, there's still the possibility that an attacker get lucky ( this get lower increasing MAX_STKSHIFT ) and yes you waste some stack space. But, oh well, it works w/out any kernel modification and it's portable on all systems that have alloca(). - Davide
From: Arjan van de Ven Subject: Re: [Announcement] "Exec Shield", new Linux security feature Date: 02 May 2003 19:18:21 +0200 > Ingo, do you want protection against shell code injection ? Have the > kernel to assign random stack addresses to processes and they won't be > able to guess the stack pointer to place the jump. I use a very simple > trick in my code : stack randomisation is already present in the kernel, in the form of cacheline coloring for HT cpus...
From: Ingo Molnar Subject: Re: [Announcement] "Exec Shield", new Linux security feature Date: Fri, 2 May 2003 13:32:20 -0400 (EDT) On 2 May 2003, Arjan van de Ven wrote: > > Ingo, do you want protection against shell code injection ? Have the > > kernel to assign random stack addresses to processes and they won't be > > able to guess the stack pointer to place the jump. I use a very simple > > trick in my code : > > stack randomisation is already present in the kernel, in the form of > cacheline coloring for HT cpus... we could make it even more prominent than just coloring, to introduce the kind of variability that Davide's approach introduces. It has to be a separate patch obviously. This would further reduce the chance that a remote attack that has to guess the stack would succeed on a random box. Ingo

From: Matthias Andree
Subject: Re: [Announcement] "Exec Shield", new Linux security feature
Date: Fri, 2 May 2003 19:05:28 +0200

On Fri, 02 May 2003, Ingo Molnar wrote:

> We are pleased to announce the first publically available source code
> release of a new kernel-based security feature called the "Exec Shield",
> for Linux/x86. The kernel patch (against 2.4.21-rc1, released under the
> GPL/OSL) can be downloaded from:

Am I the only one under the impression that this looks as though this
had waited for OpenBSD 3.3 to say "Blbrrrrrrrrp! we're first to have
stack protection in the kernel and don't need to hack gcc." (Their W^X
isn't enabled on the i386 architecture, but is due (on i386) in 3.4.)


From: Marc-Christian Petersen Subject: Re: [Announcement] "Exec Shield", new Linux security feature Date: Fri, 2 May 2003 19:12:04 +0200 On Friday 02 May 2003 19:05, Matthias Andree wrote: Hi Matthias, > Am I the only one under the impression that this looks as though this > had waited for OpenBSD 3.3 to say "Blbrrrrrrrrp! we're first to have > stack protection in the kernel and don't need to hack gcc." (Their W^X > isn't enabled on the i386 architecture, but is due (on i386) in 3.4.) hehehe ;) Well, they cannot say this even w/o exec shield b/c www.grsecurity.net. :) ciao, Marc

From: Carl-Daniel Hailfinger
Subject: Re: [Announcement] "Exec Shield", new Linux security feature
Date: Fri, 02 May 2003 23:48:33 +0200

Ingo Molnar wrote:
> 
> Furthermore, the kernel also remaps all PROT_EXEC mappings to the
> so-called ASCII-armor area, which on x86 is the addresses 0-16MB. These
[snipped]
> In the above layout, the highest executable address is 0x01003fff, ie.
> every executable address is in the ASCII-armor.

If my math is correct,
0x01000000 is 16 MB boundary
0x01003fff is outside the ASCII-armor.

Another question:
Last time I checked, there were some problems with binary only drivers
(to name one, NVidia graphics) and a non-executable stack. Has this been
resolved?

Regards,
Carl-Daniel
-- 
http://www.hailfinger.org/


From: Ingo Molnar Subject: Re: [Announcement] "Exec Shield", new Linux security feature Date: Sat, 3 May 2003 02:52:21 -0400 (EDT) On Fri, 2 May 2003, Carl-Daniel Hailfinger wrote: > Ingo Molnar wrote: > > > > Furthermore, the kernel also remaps all PROT_EXEC mappings to the > > so-called ASCII-armor area, which on x86 is the addresses 0-16MB. These > [snipped] > > In the above layout, the highest executable address is 0x01003fff, ie. > > every executable address is in the ASCII-armor. > > If my math is correct, > 0x01000000 is 16 MB boundary > 0x01003fff is outside the ASCII-armor. the ASCII-armor, more precisely, is between addresses 0x00000000 and 0x0100ffff. Ie. 16 MB + 64K. [in the remaining 64K the \\0 character is in the second byte of the address.] So the 0x01003fff address is still inside the ASCII-armor. > Another question: Last time I checked, there were some problems with > binary only drivers (to name one, NVidia graphics) and a non-executable > stack. Has this been resolved? i'm not using any binary-only drivers, so i have no idea. But as long as they use PROT_EXEC areas for code, they should be safe. Ingo
From: Carl-Daniel Hailfinger Subject: Re: [Announcement] "Exec Shield", new Linux security feature Date: Sat, 03 May 2003 11:56:47 +0200 Ingo Molnar wrote: > On Fri, 2 May 2003, Carl-Daniel Hailfinger wrote: > > >>Ingo Molnar wrote: >> >>>Furthermore, the kernel also remaps all PROT_EXEC mappings to the >>>so-called ASCII-armor area, which on x86 is the addresses 0-16MB. These What happens if the ASCII-armor area is full, i.e. sum(PROT_EXEC sizes) >16MB for a given binary (Mozilla comes to mind)? Does loading fail or does the binary run without any errors, giving the user a false sense of security? >> >>[snipped] >> >>>In the above layout, the highest executable address is 0x01003fff, ie. >>>every executable address is in the ASCII-armor. >> >>If my math is correct, >>0x01000000 is 16 MB boundary >>0x01003fff is outside the ASCII-armor. > > > the ASCII-armor, more precisely, is between addresses 0x00000000 and > 0x0100ffff. Ie. 16 MB + 64K. [in the remaining 64K the \\0 character is in > the second byte of the address.] So the 0x01003fff address is still inside > the ASCII-armor. Thanks. However, that brings me to the next question: 01000000-01004000 r-xp 00000000 16:01 2036120 /home/mingo/cat-lowaddr I was wondering why the executable parts of the binary start at the 16 MB boundary. Is this always the case or just something that happens with cat? In the first case, that would be bad for any binary with a contiguous executable area bigger than 64K. Thanks for answering, Carl-Daniel
From: Arjan van de Ven Subject: Re: [Announcement] "Exec Shield", new Linux security feature Date: 03 May 2003 14:48:35 +0200 On Sat, 2003-05-03 at 11:56, Carl-Daniel Hailfinger wrote: > Ingo Molnar wrote: > > On Fri, 2 May 2003, Carl-Daniel Hailfinger wrote: > > > > > >>Ingo Molnar wrote: > >> > >>>Furthermore, the kernel also remaps all PROT_EXEC mappings to the > >>>so-called ASCII-armor area, which on x86 is the addresses 0-16MB. These > > What happens if the ASCII-armor area is full, i.e. sum(PROT_EXEC sizes) > >16MB for a given binary (Mozilla comes to mind)? Does loading fail or > does the binary run without any errors, giving the user a false sense of > security? the binary will run without errors. And all the libs are still below the main binary (the space for that is much bigger, like 128Mb) so the executable limit is still the end of the main binary. > > > the ASCII-armor, more precisely, is between addresses 0x00000000 and > > 0x0100ffff. Ie. 16 MB + 64K. [in the remaining 64K the \\0 character is in > > the second byte of the address.] So the 0x01003fff address is still inside > > the ASCII-armor. > > Thanks. However, that brings me to the next question: > > 01000000-01004000 r-xp 00000000 16:01 2036120 /home/mingo/cat-lowaddr > > I was wondering why the executable parts of the binary start at the 16 > MB boundary. Is this always the case or just something that happens with > cat? In the first case, that would be bad for any binary with a > contiguous executable area bigger than 64K. the start address of the binary is determined by ld at link time. This cat binary was forced to go at exactly this address. The patch to binutils in Ingo's directory will add the linker option to move apps in this area; it will actually use a lower address than 01000000 to allow for bigger binaries. Obviously this 16Mb zone won't fit all apps, but daemons like sendmail and sshd etc all just fit.

Related Links:

  • Exec Shield Home
  • Story: OpenBSD: Buffer Overflow "Solutions"
  • grsecurity (Access Control List support for Linux)
  • cut off

    Anonymous
    on
    May 3, 2003 - 9:56am

    Looks like the implementation description is cut off mid-stream.

    Re: cut off

    Anonymous
    on
    May 3, 2003 - 10:07am

    The given website contains a file ANNOUNCE-exec-shield with the full text.

    follow the link...

    Anonymous
    on
    May 3, 2003 - 10:11am

    and read the file ANNOUNCE-exec-shield

    re: cut off

    Jeremy
    on
    May 3, 2003 - 10:36am

    Ack - it's fixed.

    (At some point it got terminated on a '\0')

    What about kernel 2.5.* and beyond?

    Anonymous
    on
    May 3, 2003 - 10:11am

    Does the new development kernel already have equivalent protection?

    Re: What about kernel 2.5.* and beyond?

    Anonymous
    on
    May 4, 2003 - 11:53am

    No. Probably won't have for a while, either.

    Works, but...

    Anonymous
    on
    May 4, 2003 - 9:30am

    I've tried the patch. The result:

    What is work with it? ADSL connection, X, gkrellm, Opera, Xchat, MPlayer, Abiword, OpenOffice.org, Gimp, Apache, Bind, SSH, Return to Castle Wolfenstein: Enemy Territory

    What is not work? Mozilla, Evolution, any Java application, becasue the Java VM not work, UT2003, Duke Nukem 3D, Xmms, GNOME progz, Galeon, MySQL

    Work?

    Anonymous
    on
    May 4, 2003 - 7:12pm

    it is work

    Works, but...

    Anonymous
    on
    October 24, 2003 - 2:34am

    Hmm, I don't have any problems running Mozilla or Xmms, but Mplayer crashes if I try to change volume level in module: key_events

    The Linux syndrome - patching the patches

    Anonymous
    on
    May 5, 2003 - 6:02am

    This is another pathetic attempt of "patching the patches", creating a mediocre interim solution that does halfway work and halfway destroys other things, just because nobody wants to implement the "big solution" like OpenBSD tries to do with OpenBSD 3.4.

    That's the Linux way of doing things...

    Troll bait

    Anonymous
    on
    May 5, 2003 - 7:06am

    What you're missing is that in this case (a crappy architecture with no discrete executable-permissions control on memory), there's no Big Solution*. About all we can do for x86 is an ugly hack, and every approach tends to have major drawbacks in some area.

    Besides which, I doubt this is even a final implementation. We're just witnessing an interesting branch of development here.

    If you want a real solution for the problem, you generally have to step outside the x86 world--i.e. run Linux+GRSecurity on Alpha (where PaX features are supported), or run Solaris 9 with buffer-overflow protection+performance hit, or... (etc. etc.)

    *(Yes, I know the real solution would be for all software to be bug-free.)

    equivalent... what u can do and what u cant do

    Anonymous
    on
    May 6, 2003 - 9:42am

    yeah, u cant fix the hardware problem directly in your software / kernel...

    but software is "ever" equivalent to hardware...

    so what u can do (for example) is... put on a virtual machine (emulate another machine with the capabilities and specs u need)... and run your software in this machine... and the machine you create does have this kind of protection your real hardware doesnt give u...

    but such a machine would be slow... and all u gain is a non-executeable stack or such thing... what it can not do is to protect the programmer for doing mistakes... and there is of course a lot more than buffer overflow... and remember! end-sollutions do not exist, never.

    that linux patch is crap indeed... read linus t., he only needs very few words to proof this is not realy a sollution at all... and nothing is more annoying that to believe to be secure while u aint secure at all...

    and i dont think openbsd will will be our final destination.. sure the people are hard working on security... thats what openbsd is all about... but all these chroot / jail / securelevel stuff and such addons are just another closed door, while the attacker is in your house yet, fully armed...! just read the prack article about smashing the openbsd kernel stack...

    Eugene

    Did you even know what this is about?

    Anonymous
    on
    May 6, 2003 - 11:41am

    If you don't know what the patch does, what it does, how it does it, and where it is all going you shouldn't make comments like this. If you know Linus a little, he always has his own strong opinions about things... they are not nescesarily right/true, just his word is the law. Secondly... it is a software problem, overflows.

    The patch implements a sollution to a problem which exists, it isn't tidy but there is just no tidy sollution to this. PAX and ExecShield both use tricks to enforce PROT_EXEC, one better then the other ofcourse.

    Mergability is NOT an issue with this kind of work, I can't see any of this work getting merged in any mainline kernel just because it tends to break things, and disabled by default is not really a sollution either... Redhat might decide to do so ofcourse, probably some advanced server distro... but what do I know.

    As mentioned before PAX has already implemented to where this is going... If you check the new C5 patch you will see Mingo implemented some randomisation in the stack and mmap...

    OpenBSD 3.4

    Anonymous
    on
    May 5, 2003 - 9:54am

    Since part of the problem is x86's funky memory scheme, I'm curious to see how OpenBSD 3.4 implements this of x86. Will it be any more effective or elegant than this Linux exec-shield?

    How things should be done

    Anonymous
    on
    May 5, 2003 - 12:15pm

    If you want to see how things SHOULD be done, you need to look at PaX.
    http://pageexec.virtualave.net/docs

    If you read the above documentation, you will see how all these other implementations are missing the "big picture."

    It's surprising that all these newcomers are getting press for their half-baked implementations of ideas that have already been implemented for years. (and the newcomers don't like to point out that such previous work exists, since they know (to some extent) that their implementations are clearly inferior).

    How posts should be done

    somercet
    on
    May 7, 2003 - 11:47am

    If you want to see how things SHOULD be done, you need to look at PaX.
    http://pageexec.virtualave.net/docs

    Oh, please, do troll some more. Marc-Christian Petersen, in the article above, noted that even OpenBSD's efforts postdated grsecurity, of which PaX claims to be a part. I didn't see Molnar protesting this claim on behalf of PaX/grsecurity, and I also see PaX credits several other projects for some of their work.

    What's your problem?

    OpenBSD 3.4 and Exec Shield

    Anonymous
    on
    May 5, 2003 - 3:07pm

    they pretty much do the same thing, as far as the kernel part is concerned: first, they keep the code/data/stack segments all 0 based but apply a per task (address space) dynamic limit on the code one. effectively all mappings above this limit will be non-executable. the limit is tracked throughout the lifetime of the process (mmap/mprotect can change it). OpenBSD also changes userland to accomodate this new address space layout by relinking all ELF files (main executable + libs) so that their code/data segments are separated by 1GB and hence the data will be mapped high enough in the address space to become non-executable. on the other hand Exec Shield tries to keep these file mappings in the 'ascii armor' area, that is, where the high byte of the address has a 0 in it, in the hope the ascii string based overflows will be hard to exploit this way.

    ascii armor

    Anonymous
    on
    May 8, 2003 - 2:56am

    this may be a stupid question...but can somebody tell me how is the ascii armor enforced? what if I write zeros or random bytes into the armored region? would that cause a page fault? is ascii armor some sort of flag you specify for a page table entry? and is this an x86 specific thing?

    ascii armor

    Anonymous
    on
    May 8, 2003 - 3:42am

    'ascii armor' is not about what you can write into the armored region but that you cannot (well, sort of) spoof addresses in there in your exploit payload - or so goes the theory. 'ascii armor' is a memory region defined by 0x00000000-0x00ffffff on 32 bit archs (like i386). notice that every address in this region has a 0 the high byte, so when you write your textbook buffer overflow exploit, you will have to stuff in a 0 byte into the payload and that will also terminate ascii string operations (one of which is presumably the culprit in the overflow in the first place). now this alone doesn't mean much, but when you consider that the stack (where presumably the overflowed buffer is) is non-executable (along with the heap, more or less), then you realize that your textbook exploit technique won't work directly (i.e., returning directly to the payload on the stack), so you will have to resort to something called the 'return to libc' style (check some Phrack articles on the topic). this exploit technique requires that you return to already existing code in the task's address space - this is where 'ascii armor' kicks in as all such code is supposed to be found there (not always true, but you get the idea). this is still not a big deal as i386 is little endian, that is, when you overflow your stack buffer (from lower to higher addresses) and overwrite the saved EIP value, you can easily have the string operation put the terminating 0 at the last byte of the saved EIP and hence you'd still be able to return into the 'ascii armor' area. what you won't be able to do however is pass arguments to the function you return to since those would come after the terminating 0... ooops. now, this is the thinking that underlies Exec Shield but unfortunately reality is different.

    1. statically linked executables are not protected at all (unless someone relinks them as well to the base of 0x00110000 or so).

    2. there's no guarantee that a copy of the exploit payload cannot be found on the heap and that the heap is non-executable (e.g., Linuxthreads creates executable thread stacks by default and in the ES scheme that would raise the executable region limit high enough that all the heap would suddenly become executable).

    3. there's no guarantee that the stack layout in any given exploit situation doesn't already hold the proper arguments needed for the attack (be that a simple invocation of system() or others) in which case 'ascii armor' doesn't matter at all.

    4. there's nothing to prevent a return into the *middle* of some function (or even executable data, as all the .data sections of mapped libraries are still executable) and if the current CPU registers hold proper values already, one can simply bypass the function epilogue code and have a successful exploit.

    5. if the overflowed function was compiled with the frame pointer enabled (EBP register on i386), then one can also control the value of it (as the caller's saved EBP is below the saved EIP) and that combined with the 'return into the middle' technique allows even more control over the passed arguments (EBP need not point to the stack at all).

    ascii armor

    Anonymous
    on
    May 8, 2003 - 11:21pm

    thanks for your clarification. It all make sense now. I got confused earlier because I thought the contents of 0-16MB was in ascii armor format.

    actually........

    Anonymous
    on
    May 10, 2003 - 11:06am

    Just to be pedandtic - the first address that doesn't have a 0 byte in it is 0x01010101 which is 16 MB + 64 KB + 256 bytes + 1 byte.

    Re: [Announcement] "Exec Shield", new Linux security feature

    Anonymous
    on
    June 21, 2003 - 11:59am

    Well,

    "[...] The patch also makes it harder to pass in and execute the so-called 'shell-code' of exploits. The patch works transparently, ie. no application recompilation is necessary."

    It seems that you need recompilation for ET_EXEC randomization.
    (not randomiz only the mmaped() aread but the main binary).

    As you said the sendmail vuln was a ASCII Only exploitation, and the exploit is still possible. Mine use partial overwrite of the MciCache pointer, and even against randomization it will work since MciCache is pointing already on the heap. I just have to done a little of heap filling the put the fake Mci ** at the rigth place.

    So,
    my second question is, is the "ascii armor" always at same address ?
    (same range for each -recompiled- binary ?)

    Thanks

    --
    sauron

    > It seems that you need reco

    Anonymous
    on
    June 22, 2003 - 4:30am

    > It seems that you need recompilation for ET_EXEC randomization.

    correct (more precisely, relinking, but that in practice means
    recompilation as well).

    > is the "ascii armor" always at same address ?

    not sure what you mean here... the 'ascii armor' region is independent
    of any app, so it's always the 'same'.

    The patch implements a

    Anonymous (not verified)
    on
    May 5, 2009 - 3:42pm

    The patch implements a sollution to a problem which exists, it isn't tidy but there is just no tidy sollution to this. PAX and ExecShield both use tricks to enforce PROT_EXEC, one better then the other ofcourse. Muhabbet mirc sohbet Mergability is NOT an issue with this kind of work, I can't see any of this work getting merged in any mainline kernel just because it tends to break things, and disabled by default is not really a sollution either... Redhat might decide to do so ofcourse, probably some advanced server distro... but what do I know. As mentioned before PAX has already implemented to where this is going... If you check the new C5 patch you will see Mingo implemented some randomisation in the stack and mmap...

    Comment viewing options

    Select your preferred way to display the comments and click "Save settings" to activate your changes.