Exec-Shield vs. PaX
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) ex
Re: Exec-Shield vs. PaX
you are willing to pay is i believe way too high. good luck in your trying to fix the problem (speaking of the PaX attack model again here), you'd be the first one to do it without the measures that PaX takes. > > 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. [...] > > many areas of PaX conflict with one of the most basic rule of Linux: > >http://lwn.net/Articles/32980/ i hope you realize that Linus's declaration is not on the same level as internationally accepted standards, don't mix them up. as for not breaking userland: sure, that's what i'd like to have as well, but i have only so many hours in a day to work on that. also, you did break userland yourself as well, otherwise how would you explain the patches RedHat made to the XFree86 server? see, there're just cases when userland is plain wrong and must be fixed. on another note, how did you get java to work under Exec-Shield while maintaining all those non-executable regions (see more on this below)? > > 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), [...] > > i'm not sure it's acceptable to put _any_ restriction on the layout of the > user VM. no problem, PaX as it is makes no restrictions on the layout, we'll just be stuck with the 1.5 GB task size on i386 (or the usual 3 GB if you can take the performance hit of PAGEEXEC on i386). > The rule exec-shield follows is this: whenever the kernel gets a > chance to chose it will group mappings smartly, but it will follow > requests for executability no matter what. So while this doesnt _force_ > good protection, for most apps it provides a pretty acceptable layout. > > i guess this is a hard-to-solve philosophy difference again. indeed, especially since your philosophy seems to be 'do something while breaking absolutely no apps' where 'something' is yet to be explained and whatever it is, you still broke apps with it (such as XFree86). > a fair number of users got real happy when we extended the x86 user VM > from 3GB to 4GB. Going from 3 GB to 1.5 GB is really not an option i'm > afraid. It's also not an option to say that "your app is secure only as > long as it fits into 1.5 GB". It also not an option to say "this box is > pretty secure, except for your huge database server". that's your personal opinion. others (e.g., PaX users) have the exact opposite as their personal opinions, so be it ;-). since you've talked so much about what does not fit into 1.5 GB, could you please provide us with a list of applications that are used by the majority of users and fail when run in a 1.5 GB address space? > obsoleted by ia64/amd64 systems anyway. But i'd hate to lose users to > Windows just because distros only support 1.5GB of VM. Windows has a 2 GB userland, seems to be closer to 1.5 than 3. other than that, Microsoft is moving into the PaX direction [2] (i'm referring to runtime code generation and memory protection in particular). > i really dont think we can realistically isolate the code generation > capability and still have a nice and flexible system. it's not about 'isolation' (did you mean 'removal'?) but control. control by the distro maker, system administrator or the end user. what is subject to discussion how it should best be done. you say it should not be done at all, that's your opinion and is in complete disagreement with experts in the information security field. > I dont see anything wrong in apps executing scripts. Or apps writing > scripts and executing them. Or apps doing JIT stuff, or just doing > some quick runtime fixup. there's nothing wrong with it as long as you write bugfree code or don't want guaranteed security from certain exploit methods. there are people who want the latter because they have much at stake and know that the former is not true. > It's quite widely done and it would not be Linux anymore if we try to > exterminate or second-class such techniques. And it's even more common in > the Windows world, and i really hope those Windows apps continue to come > over to Linuxland. i know i'm repeating myself, but i'll say it again: there's no problem with runtime code generation as long as it's under control. let's do it, but be aware of it when it's done because it's a dangerous privilege when abused. come up with a system that allows one to easily define and maintain defaults and policies, and i'll be the happiest person. > static predictable addresses. I dont think this should be tagged via
Re: Exec-Shield vs. PaX
> >first of all, it's multithreaded. [...] > > paxtest does not link to libpthread, nor does it create threads, at all. > How can you claim it's multithreaded? i did not. if you quote my post like this: >let me get back to the topic of java as i promised above. java >is a nice animal as it shows several issues with Exec-Shield. > >first of all, it's multithreaded. glibc creates executable >thread stacks by default. [...] it will be clear that i was referring to java. > > glibc creates executable thread stacks by default. [...] > > to the contrary, glibc does this: > [snip] > $ rpm -q glibc > glibc-2.3.2-101 that's what RedHat's glibc does. and this is what i get on gentoo (again, sorry for the plug, although i think other distros like debian would show the same as well): $ epm -q glibc glibc-2.3.2-r8 excerpt from the maps file of /opt/blackdown-jdk-1.4.1/bin/java (running under PaX but without non-exec pages, randomization was still on): b7b7f000-b7b8 +++p 00:00 0 b7b8-b7b8e000 RWXp 1000 00:00 0 b7b8e000-b7b91000 +++p f000 00:00 0 b7b91000-b7c0 RWXp 00012000 00:00 0 b7d7f000-b7d8 +++p 00:00 0 b7d8-b7d8e000 RWXp 1000 00:00 0 b7d8e000-b7d91000 +++p f000 00:00 0 b7d91000-b7e0 RWXp 00012000 00:00 0 b7f7f000-b7f8 +++p 00:00 0 b7f8-b800 RWXp 1000 00:00 0 b850-b850a000 RWXp 00:00 0 b850a000-b850d000 +++p 00:00 0 b86f2000-b86fb000 RWXp 8000 00:00 0 regardless of whether RedHat fixed this or not (i hope it will enter the main glibc tree btw), the fundemantal problem of changing memory protections without asking stays there (LinuxThreads was just one known way to trigger it).
Re: Exec-Shield vs. PaX
> > [...] also, you did break userland yourself as well, otherwise how would > > you explain the patches RedHat made to the XFree86 server? > > actually, unmodified XFree86 works just fine. It will have an executable > stack but it will work out of box - so no app was broken. false! my unmodified X server (gentoo) dies with the following core when trying to run it under [1]: (gdb) bt #0 0x00caf471 in kill () from /lib/libc.so.6 #1 0x00caf215 in raise () from /lib/libc.so.6 #2 0x00cb07bb in abort () from /lib/libc.so.6 #3 0x0806eb99 in AbortDDX () #4 0x080ed43a in FatalError () #5 0x0808522c in xf86SigHandler () #6 #7 0x0a226000 in ?? () #8 0x080a6f98 in LoadModule () #9 0x0806fa3c in xf86LoadModules () #10 0x0806db2a in InitOutput () #11 0x080d36c1 in main () does LoadModule() ring a bell? why don't you realize that there's a world beyond RedHat and that you *do* break those people's system? heck, you did break RedHat users' systems as well, you say so yourself: [2] or [3]. every time you suggest that a user upgrade X means that you have broken his existing binary - a clear no-no by your own rules. > X does break if you force exec-shield=2, and it did break even with > exec-shield=1 in earlier iterations of exec-shield, but that bug has been > fixed. excerpt from [1]: --- linux/kernel/sysctl.c.orig +++ linux/kernel/sysctl.c @@ -52,6 +52,9 @@ extern int core_uses_pid; extern char core_pattern[]; extern int cad_pid; +int exec_shield = 2; +int exec_shield_randomize = 1; that to me means that *everyone* will have his *existing* binary broken, by your own admission. it also means that you have violated the very rule of Linus you had referred to before. > the XFree86 patching you refer to above we did was to enable non-exec > stack. But this was an iterative thing to enhance security, not something > we had to do because X broke due to exec-shield itself. XFree86 never needed an executable stack as far as i know, what was there to 'enhance' then? it is clear that XFree86 did break because of Exec-Shield and you had to modify both to get it to work and be able to claim that it works out of the box. incidentally, if i were to make use of PT_GNU_STACK in PaX, i could claim the same - now what was your point of fighting this silly issue? by the way, on another look at your patch i noticed the following: 1. you added a new parameter to fs/binfmt_elf.c:create_elf_tables() but don't make use of it, probably it's not needed at all now. 2. in fs/exec.c:setup_arg_pages() you may create an inconsistent state between mpnt->vm_page_prot and mpnt->vm_flags, the former should be derived from the latter, just like do_mmap_pgoff() does it. [1] http://people.redhat.com/mingo/exec-shield/exec-shield-2.4.22-G4 [2] http://marc.theaimsgroup.com/?l=linux-kernel&m=106482772021534&w=2 [3] http://marc.theaimsgroup.com/?l=linux-kernel&m=106502603232695&w=2
Re: Exec-Shield vs. PaX
> You are trying to make a big fuss about this for no good reason. Ingo, please. it was *you* who objected to PaX's default enforcement policy because it broke Linus's rule. yet you did the same with your own default *and* contested the fact that you hadn't broken anything. i don't have a problem with your choice for default policies, i have a problem when you have a double standard ('kettos merce' in your mother tongue).
Re: Exec-Shield vs. PaX
> > [...] randomization serves NO purpose in the grand scheme, it does not > > provide guaranteed protection against the PaX attack model (arbitrary > > read/write access to the address space). [...] > > there's another, practical aspect of address-space randomization which i > find to be the most important: to make worms uneconomic in network > bandwidth terms. having non-executable pages achieves the same *and* guarantees failure (vs. the probabilistic failure/success rate of randomization), that's why i said that randomization played no role 'in the grand scheme'. the fact it's still useful these days is the consequence of our inability to effectively protect against the attack methods 2 and 3 i had referred to earlier (luckily for the defense side, existing worms have used attack method 1 but i would not rely on that in the future). > i took the 'they are broken for good' as equivalent to 'concepts flawed by > design', and 'important privilege that should be carefully managed' as a > signal of your belief that the ability to generate code should be > restricted. I do not agree with this direction. 'they are broken for good' means just that, they are no longer able to run under PaX without tagging (at least not when PaX is configured in its optimal form, that is, with non-exec pages and MPROTECT on). you're correct with what i meant by 'managed' although i think you may not like it because of the choice of my wording, not because what i meant. if i say 'we need an API to allow userland to generate code at runtime', will you still disagree with that (meaning 'disagree on principles', not the suggested implementation)? > The moment you start to 'manage' stuff that you believe is > 'broken for good' it ends up being less accessible to people. 'root for everyone!' - isn't that concept 'broken for good' (in the sense you originally interpreted it, i.e., 'flawed by design')? see, we do change systems to be able to 'manage stuff' even if that means that we'll make that stuff 'less accessible to people' (how many times do system admins have to do things on behalf of their users because said users are now not allowed to do it themselves?). so what am i getting at here? the fact that secure (heck, even just usable) systems should follow the principle of 'least privilege'. in the multi-user system case, it says (among others) that if a user does not need to have the privilege of root (read: complete system control), then he should not have it, hence we have the concept of UIDs (and capabilites, as the case may be). in the PaX memory protection case it means that if an application does not need the privilege to generate code at runtime, then it should not have it. interestingly enough, this is exactly what i say in [3] - did you read/understand it? if you did, then you should have realized that you can argue only about whether you want to follow a least privilege policy in this case, you cannot argue about how to do it because there's just one way (the memory protection concept of PaX). > I would like to see all these security technologies to show up on Joe > Average's desktop, so government-style manual need-to-know access control > just doesnt cut it. It might work if packaged very very carefully with > lots of care towards making it simple, but i see zero efforts in that > direction. i would not call [1] or [2] 'zero efforts'. > > you said a lot about what you don't agree with in PaX, what exactly > > prevented you from changing it *yourself*? what prevents *you* from > > disabling MPROTECT by default for example? > > we did take a look at the PAX_SEGMEXEC portion of PaX for Fedora (you did > seem to be a reasonable person with tons of experience and this matters > alot when considering patches) and the killer at that time was the 1.5 GB > VM limitation on x86. Exec-shield, as coarse as it might be, does here and > today offer quite acceptable non-executability coverage of all actual apps > we checked, and this is what counts. (Nobody puts bogus mprotect(argv) > calls into these apps to disable exec-shield so exec-shield just works.) [...] > the mprotect argument came not from my ability to enable or disable it in > PaX, but from the claim/impression that the (mprotect) tests in paxtest > constitude actual 'Vulnerabilities'. So i simply said i dont intend to > restrict mprotect semantics in exec-shield and explained my reasons for > doing so. i'm sorry that you still haven't realized what PaX/paxtest are about. PaX works against *exploit*methods* and paxtest simulates the core steps of those methods to determine to what extent they work on a given system. what you call 'bogus' again shows your misunderstanding of how one writes exploits. let's do some thinking: why did you write Exec-Shield (non-exec pages, randomization)? to make exploit methods non-working. now the question is, have you achieved that goal or not? or a bit harder question: what did you achieve exactly? my answers are below: Exec-
Re: Exec-Shield vs. PaX
> > It is in fact a simulation of a multithreaded application. [...] > > The test incorrectly assumes that thread stacks are executable. I suspect > we both agree that it's desirable to have thread stacks non-executable as > well. while i agree with you on this one, it is in stark contrast to what you said earlier: > there's nothing wrong about an executable stack though. It's been part of > Linux ever since. also, the test does not only demonstrate that thread stacks are executable or not, it demonstrates a fundemental design flaw in Exec-Shield: whenever an executable region is created in the address space, *everything* below that becomes executable as well. i believe it is important that Exec-Shield users are aware of this flaw, could you write a test for this as well please?
Re: Exec-Shield vs. PaX
> "The test incorrectly assumes that thread stacks are executable" is not > equivalent to "thread stacks are non-executable". And there's no conflict > in what i say above. ok, i was quoting too much and you interpreted the wrong part. the bit i was referring to is this: > I suspect we both agree that it's desirable to have thread stacks > non-executable as well. on one hand you acknowledge that it's better to have non-exec thread stacks but on the other hand you argued that > it's not a bugfix to break apps that rely on an executable stack - the > stack _is_ executable. ^ as they say, you can't have it both ways. > > also, the test does not only demonstrate that thread stacks are > > executable or not, it demonstrates a fundemental design flaw in > > Exec-Shield: whenever an executable region is created in the address > > space, *everything* below that becomes executable as well. [...] > > thanks, the cat is finally out of the bag - you admit here that the > incriminating paxtest code is there to demonstrate what you characterise > as a flaw in exec-shield. the cat has always been out of the bag, way back in my very first mail in this thread (and it's now the second time i've quoted this bit): > 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. since you have such a problem with paxtest doing the explicit mprotect() itself i decided to change it to a simple nested function, it will achieve the same and hopefully satisfy you as well. > Note that none of your arguments tries to claim > that any real application indeed does "mprotect(argv)", which is pretty > telling by itself. indeed. if you read my mails again (i'm getting tired of quoting myself all over again), i told you explicitly what paxtest is for: testing for regressions, situations when stuff fails. Exec-Shield fails under the above mentioned situation. it also fails when gcc nested functions are used, you'll see that in 0.9.6. i hope you won't argue that no real application uses nested functions (and before you object even to that, as you said yourself, nested functions are just one way to trigger the heuristics in gcc, other code constructs from real life would do the same as well). > As i have explained it a hundred times, this behavior is a well-known > property of exec-shield, and that we've done a quite good job of reducing > this effect. In fact i've put it into my exec-shield announcement: *none* of your public postings discusses the inherent problem with memory regions becoming executable when something above them does. the quote from your README talks about the ascii-armor region and data being executable in there. it does not talk about how the main application's data or the heap or even the entire stack can become unexpectedly executable. on a related note, PT_GNU_STACK support as implemented in Exec-Shield suffers from the same problem: you make not only the stack executable but *everything* else below it, i could not find a note from you talking about it. > ( sorry, but i'm going to stop contributing to this thread. You are > getting increasingly irrational and emotional, there's nothing more i > could add to this thread. I do acknowledge that PaX is more secure, but i > also say that exec-shield is a hell alot of a difference from a stock > distro. You expressed your feelings that exec-shield is insecure in one > area and apparently you conclude that it's thus useless. There's nothing i > can do to change this irrational bad logic of yours. ) Ingo, if you read one of my previous posts, you will realize that i did say that Exec-Shield was mostly good enough against current exploit methods (which blindly expect their injected payload to be executable). what it's not good enough for is protecting against future attacks which will (because they can) adapt and circumvent Exec-Shield in certain cases. this is not true for PaX and obviously that decides what i'm going to use (and have been for all these past 3 years). and finally on a personal note: you're quick to call people by names, that's not professional especially when none of the facts support your position. --- i was not cc'd on this, but i'd still like to reply here: Henning Makholm said: > Hm, what I've been able