since a few points have been made regarding $subject, let me clear up a few of them:
1. 'It seems that exec-shield does 99% of what PaX does' i don't know the origin of that number above, for now i'll just stick to the facts i know: - PaX implements perfect non-executable pages on amd64, i386, ia64, parisc, ppc, sparc and sparc64 whereas Exec-Shield has some imitation of it only on i386 (it's not true per-page). - PaX implements a concept about how runtime code generation should be done, there's nothing similar in Exec-Shield, and it seems that Ingo does not even understand why this is important (for Ingo: please read and understand [1] before you call something bogus, see below for more). - PaX implements best-effort randomization of the entire address space, Exec-Shield does it too but at a higher code complexity and a lower entropy rate while having a worse effect on the kernel entropy pool. 2. paxtest 'proofs' i saw several people point to paxtest results to 'prove' how good Exec-Shield it is. it is not. first, Exec-Shield has a fundamental design problem stemming from the lack of understanding or design on Ingo's part (what i call MPROTECT in PaX). you'll really have to read the PaX design docs to understand its role in the grand scheme of things (see below for a bit more). second, paxtest had some bugs which Exec-Shield exposed and made Exec-Shield appear better than it is. i've fixed them here and expect to release 0.9.5 today or so. the results now look like: PaXtest - Copyright(c) 2003 by Peter Busser <[EMAIL PROTECTED]> Released under the GNU Public Licence version 2 or later It may take a while for the tests to complete Test results: PaXtest - Copyright(c) 2003 by Peter Busser <[EMAIL PROTECTED]> Released under the GNU Public Licence version 2 or later Executable anonymous mapping : Vulnerable Executable bss : Vulnerable Executable data : Vulnerable Executable heap : Vulnerable Executable stack : Vulnerable the above changes are the result of Ingo's approach to create non-executable memory on i386, they're not per page as a simple mprotect on the top of the stack shows. before i get accused of specifically rigging the tests, i'll tell you that running multithreaded apps would have almost the same effect (only the main stack would stay non-exec under Exec-Shield). needless to say, PaX passes all the above as before. Executable anonymous mapping (mprotect) : Vulnerable Executable bss (mprotect) : Vulnerable Executable data (mprotect) : Vulnerable Executable heap (mprotect) : Vulnerable Executable shared library bss (mprotect) : Vulnerable Executable shared library data (mprotect): Vulnerable Executable stack (mprotect) : Vulnerable Anonymous mapping randomisation test : 8 bits (guessed) Heap randomisation test (ET_EXEC) : 13 bits (guessed) Heap randomisation test (ET_DYN) : 13 bits (guessed) Main executable randomisation (ET_EXEC) : No randomisation Main executable randomisation (ET_DYN) : 12 bits (guessed) Shared library randomisation test : 12 bits (guessed) Stack randomisation test (SEGMEXEC) : 17 bits (guessed) Stack randomisation test (PAGEEXEC) : 17 bits (guessed) Return to function (strcpy) : Vulnerable Return to function (strcpy, RANDEXEC) : Vulnerable Return to function (memcpy) : Vulnerable Return to function (memcpy, RANDEXEC) : Vulnerable Executable shared library bss : Vulnerable Executable shared library data : Vulnerable these two had bugs in them (they were trying to execute code from the wrong location). i find it somewhat funny that the Exec-Shield proponents (including Ingo himself) have used the previous false results as a justification for their claims. apparently none of you understood what the tests and Exec- Shield did, otherwise you would have known that Exec-Shield cannot possibly pass these tests due to its design (or at least not without going down the OpenBSD road). Writable text segments : Vulnerable 3. MPROTECT is bogus it is not. Ingo says so because he did not understand how PaX works. the short story (there's no substitute to reading the docs!) is that in PaX we want to handle the problems posed by memory corruption bugs. all such bugs. the approach chosen in PaX is based on preventing exploit techniques from working (vs. preventing specific bug situations from occuring, at least for now, efficient full runtime bounds checking will have to wait a bit). in the docs you will find a classificaiton of exploit techniques: (1) introduce/execute arbitrary code (2) execute existing code out of original program order (3) execute existing code in original program order with arbitrary data every possible exploit technique against memory corruption bugs belongs to one of the above (note that it is a classification of exploit techniques, not bugs, that is, a given technique can be used against different bugs and a given bug can be exploited by more than one technique). the idea in PaX is that we try to prevent entire classes of exploit techniques from working, starting with the easy ones and going up to the hard problems. in the present situation (1) has been dealt with, (2) is in the works, and (3) is somewhere in the future (pending some research). dispite Ingo's claim, restricting page protection transitions on memory pages (which is what the mprotect() restrictions do) is mandatory for our purposes, far from being bogus. without it, it remains possible to introduce/execute new code into a process. with MPROTECT and the ACL system (or a read-only chroot) to prevent arbitrary file mappings and/or creation you can prevent attack method (1), guaranteed. the fact that PaX does not contain the ACL part is the simple consequence of its being used by different projects who want to do it their way, i explicitly chose not to stand in there (for the same reason PaX itself does not prevent information leaking in /proc, that's up to the patch integrators). Ingo also implied that executing an in-memory shell script via system() does (1). it does not, it does (2). think about it, (1) is about executable machine code, a shell script is not machine code. Ingo also confuses MPROTECT with mprotect() restrictions, the former is much more than the latter, it's about separating the writable pages from executable ones for the purposes of preventing (1), something that Exec-Shield doesn't (cannot) do. Ingo also argues about non-completness... in the main doc there's an explicit paragraph for people like him, please read it again. it will explain to you why you cannot judge a building block on its own, only together with others. the combined effect is much more than what the individual pieces are capable of. PaX is not a finished project, there are several pieces of the puzzle yet to be written. 4. PaX breaks apps, specs, whatnot i chose to enable most of PaX by default (while allowing as many apps to run as possible, e.g., that's why ELF text relocs are allowed by default). since PaX explicitly wants to prevent runtime code generation, obviously apps that want to do it will no longer work. there are two categories of such apps and two ways to fix them. - apps that don't really need to generate code runtime but still do it for whatever reason: they are buggy and must be fixed at the source level. one prime example is the module loader code in XFree86 which assumes that malloc()'ed memory was executable whereas it was not (run strace on any app and you'll see how glibc uses mmap() to request memory). another good example is the various .plt stubs that are runtime generated on many risc archs, for now i added emulation to them, but eventually they'd better be redesigned a la i386. - apps that by their nature want to generate code runtime (e.g., java). they're broken for good which many people noticed by now. that's good, that was my purpose because i wanted to draw attention to the fact that runtime code generation is an important privilege that should be carefully managed (as it happens to be also one of the exploit techniques). of course if you don't agree with my exploit technique classification and the general solution approach i took with PaX, then there's nothing to discuss and you can stop reading this ;-). for those who are interested in solving this problem, please read my proposal in mprotect.txt (available at [1]). about PaX breaking specs: i urge Ingo and others saying this to point me to the precise location in SUSv3 or POSIX 1003.1-2001 that PaX conflicts with. for all i know, none of these standards give ANY guarantees about the ability to generate code at runtime. and rightly so, just think of non-coherent cache systems, you need explicit userland (or kernel assisted, not sure how all such systems solve it) flush interfaces, nothing like that is in the standards (msync() is for something else, nor is it used by any code i know that generates code at runtime, so they'd be non-compliant even if msync() was meant for this purpose). about SEGMEXEC and the 1.5GB limit: yes, it's true, yes, it could be changed (if one can live with a more limited range for executable mappings), yes, it would need some userland tagging, yes, i have ideas for it, no, it's got nothing to do with PT_GNU_STACK. the longer story is that the majority of users don't need to care about this address space limit, it's mainly databases and some scientific applications that run into. mind you, they already had this problem before when people were using 1-2 GB userlands (which back then was the way to allow the kernel to use more than 1 GB RAM, and even these days it's the only way to go if you don't want HIGHMEM). as for userland tagging: i'd like to have much more control over what userland can request from the kernel than what PT_GNU_STACK allows. for one, requesting executable stacks is irrelevant, it should be about requesting permission to generate code at runtime (or just use my proposed mmap() interface changes), request randomization, etc. i'd also like to have control over the placement of the stack and the userland address space size in the future. for now chpax is the quick & dirty solution for tagging, although users of complete systems with ACLs (grsec or RSBAC in Adamantix) can control the PaX flags via ACLs, no need for binary modifications. mind you, it's somewhat misleading to state that PT_GNU_STACK is a better solution than chpax, after all, someone HAS to decide whether a given module needs it or not (before someone points it out, trampolines are only a small and least important part of the problem), the toolchain cannot automatically determine it, so it needs the exact same manual work as chpax. i'm sure i left questions unanswered, feel free to ask here or in private. [1] http://pageexec.virtualave.net/docs/ PS: please CC on responses.