Announcing security hardened kernels for testing

pageexec at freemail.hu pageexec at freemail.hu
Wed Jan 5 19:28:19 CST 2005


> Thanks for the great info. I'll CC this to wine-devel as I think it's of
> general interest, I hope you don't mind.

sure, no problem (let's hope i don't bounce by not being subscribed ;-).

> http://lists.debian.org/debian-devel/2003/11/msg00206.html
> 
> in which the PaX author and Ingo Molnar who did exec-shield discuss the
> differences.

a better description of PaX is at http://pax.grsecurity.net/docs/ .

for a quick recap: PaX has techniques to prevent exploiting memory
corruption bugs (i.e., the various exploit techniques, not the
manifestation of bugs themselves). for practical reasons, we categorize
these techniques into 3 sets, the first one being the abuse of the
privilege of runtime code generation (this is what you mostly find
in published exploits, "shellcode executed on the stack/heap/etc").
so PaX makes it possible to take away this privilege (and this obviously
is in conflict with the apps that need it).

last year i proposed to make wine work with the strictest PaX settings
(which would make running windows apps more secure than it is under
windows itself, SP2 or not). this means that i don't mind if a windows
app wants to generate code at runtime, but i'd like to make sure that
the base wine runtime doesn't. yes, this is my itch to scratch and i
don't actually expect you to do the work, but i'm definitely interested
in your ideas and help. the rest of my comments are inline.

> OK. I don't remember this thread I'm afraid

just for your reference, it was between Alexandre, you and me around last
march, for some reason i thought it had gone to the list as well.

> Presumably if WineHQ/CodeWeavers were to ship binary packages we'd have
> to do the same to work on such a distribution. But it's just an ELF flag
> right?

for historical reasons, there're 2 marks. the older one (controlled by
chpax) abuses an otherwise (or yet) unused field in the ELF header, i
personally don't encourage the use of it. the other one (controlled by
paxctl) is based on a new ELF program header type called PT_PAX_FLAGS
and requires a binutils patch (being specific to PaX and in direct
conflict with PT_GNU_STACK, it has about 0 chance to end up upstream).

with that said, i don't think you should be worried about marking
executables yourselves, better leave it to the various distros/users
who are already aware of what changes PaX requires in some apps (and as
i said, ideally wine would not require anything, more on this below).

> We do this because some Windows programs and DLLs cannot cope with
> getting pointers >2gig, so we need to ensure that the kernel does not
> give us mappings above this point. The only way to do this currently is
> to do an iterative reservation to map as much of this address space as
> possible which is what you're seeing here.

my problem wasn't that you reserved all address space 'upstairs', but
that the algo wine has can end up in an infinite loop (requesting kernel
space memory is another thing, but given how non-existant is a decent
API for learning about the address space layout in linux, i won't blame
this on you ;-).

interestingly, i also have this need to have some control over the
address space and have a plan to do this eventually. the idea is to
introduce a new ELF program header (because this is the easiest to parse
at execve() time in the kernel), that would describe the desired
TASK_SIZE, stack placement and other info you might need. how something
like this would fly with upstream (both binutils and the kernel),
i can't tell however.

> >      as you can see, wine insists on an address until it gets it,
> >      without using MAP_FIXED.
> 
> We have no choice in the matter, I think we can't use MAP_FIXED as
> that'd risk blowing away any mappings already made above the 2gig
> boundary. Actually this code was originally written to support the 4G/4G
> VM patch that was put into Fedora for a while (it's gone now).

you're right with the behaviour of MAP_FIXED, but then i still think
that something is wrong with the allocation algo if it can loop forever
(or i wasn't patient enough).

> > 3. there's at least /usr/lib/wine/ntdll.dll.so which is marked with
> >    an executable PT_GNU_STACK program header, suggesting that it
> >    needs an executable stack (or there's some build problem).
> 
> Last time I looked documentation on exactly what triggers this flag is
> scarce or non-existant.

some time ago when related problems showed up for grsecurity/PaX users,
i posted my generic thoughts on the matter, you may find it useful too:

http://forums.grsecurity.net./viewtopic.php?t=673
http://forums.grsecurity.net./viewtopic.php?t=807

if you need more info, feel free to ask. for your particular question,
it's always been about the compiler detecting the use of nested function
trampolines (never inline asm and other ways of runtime code generation)
and the linker erring on the side of backwards compatibility.

> but I have no idea why gcc has decided it's needed now. If you look at
> ntdll in the sources:
>
> http://source.winehq.org/source/dlls/ntdll/
> 
> It's fairly harmless, there is some assembly in there but I don't
> remember seeing any code which assumed an executable stack.

after reading my posts on the grsecurity forum, you'll see that this case
is probably a false positive, stemming from an unmarked or badly marked .o
file that ended up in the .so in question. it's a small detective work,
i'll see what caused it on my box.

> I'm afraid Wine cannot operate in an environment that doesn't allow us
> to map pages as executable and fill them with generated code. This
> technique is:

ok, this is the really interesting part for me, so let's discuss it a bit
more.

> a) Used by some Windows programs

this is fine and can't be helped of course. my hope is that most apps, or
rather, the ones i'm personally interested in don't generate code runtime.

> b) Used by the Wine DLL loader

what is this use exactly? can it be reworked to not require runtime code
generation (remember that i'm willing to scratch my own itch, i just need
some pointers)?

> c) Required to implement DCOM universal interface proxies

required as in 'cannot be implemented any other way'? and same question
as above of course. also, this feature doesn't sound like something that
all windows apps need, so i wouldn't have a problem with allowing it (note
that i'm talking about PaX based systems only, not wine in general, so no
worries about me trying to force something on you) if i can run the rest
of the apps with full PaX enabled.

> So if PaX denies this as a matter of course then it will never work.
> Having read the thread with Ingo I must say I agree with him that
> runtime code generation is a legitimate technique and not a bug.

i've never sad it wasn't legitimate, just that it's a privilege and if we
want protection from exploits, then we'd better revoke it from apps that
don't need it (and which get it by default and cause security problems).

obviously my goal is to run as many apps as possible without this privilege
(especially those that process untrusted user input, be that server daemons
or client apps like mail clients, web browsers, etc). if there're fundamental
reasons why wine cannot work without such a privilege, then so be it, it'll
go the way of java on PaX systems and be exempted.

> Service Pack 2 may well make the default process heap NX but it
> also has a huge infrastructure in place to deal with backwards
> compatibility concerns, including a large database of badly behaved
> apps, user-accessible GUIs to disable the protections and I believe it
> also has code to catch NX faults (on hardware that supports that) and
> ask the user if they wish to disable the protections for that
> application.

don't worry about the infrastructure of handling exceptions, it'll be
the concern for distros (that use PaX), not wine developers. and it's
easy to solve with two preloaders, with one allowed and the other denied
the privilege of runtime code generation.

> They have to be fixed otherwise the kernel may place them in the middle
> of a reserved area which would cause initialisation to fail. This cannot
> be changed.

i meant something like a new switch to configure that would let you specify
a new compile/link time base address, that can surely be arranged...

> It can't and I don't see any way to make it able to operate under such
> conditions in future. Is there a way to brand the binaries as excluded
> from PaX at build time without a special tool? If not would you be
> willing to submit a build system patch to detect the branding tool on
> PaX systems and use it on the relevant binaries automatically?

there's already such support in the binutils patch i mentioned above:
'ld -z execheap/-z noexecheap' (you'd use the former to mark the preloader
which in turn would allow runtime code generation). post linking, you
can use 'paxctl -spmr' (or the deprecated chpax) to disable all non-exec
enforcement and randomization. but as i suggested at the beginning, this
should not be your concern but that of the distro guys (and pending the
questions i raised, it may very well turn out to be unnecessary, at least
i'll try my best to make it happen).




More information about the wine-devel mailing list