Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 91122 - Enhancement to paxctl to allow PaX flags to be set on most foreign binaries
Summary: Enhancement to paxctl to allow PaX flags to be set on most foreign binaries
Status: RESOLVED FIXED
Alias: None
Product: Gentoo Linux
Classification: Unclassified
Component: [OLD] Core system (show other bugs)
Hardware: All Linux
: High enhancement (vote)
Assignee: The Gentoo Linux Hardened Team
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-05-02 00:19 UTC by Kevin F. Quinn (RETIRED)
Modified: 2006-07-24 16:21 UTC (History)
1 user (show)

See Also:
Package list:
Runtime testing required: ---


Attachments
Add -f option to force paxctl to hijack PT_NOTE, PT_GNU_STACK (paxctl-0.2-force.patch,7.96 KB, patch)
2005-05-02 00:21 UTC, Kevin F. Quinn (RETIRED)
Details | Diff
Attempt 1 at extending the first PT_LOAD downwards (add-elf-phdr.c,6.71 KB, text/plain)
2005-05-04 15:43 UTC, Kevin F. Quinn (RETIRED)
Details
Working proof-of concept PHDR insertion widget (add-elf-phdr.c,6.91 KB, text/plain)
2005-05-06 00:14 UTC, Kevin F. Quinn (RETIRED)
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Kevin F. Quinn (RETIRED) gentoo-dev 2005-05-02 00:19:49 UTC
Any foreign binaries provided externally rather than compiled locally do not have the PT_PAX_FLAGS header, so cannot be controlled via paxctl - only the legacy chpax flags currently work.

The patch that follows allows paxctl to set flags on most alien binaries (e.g. java).

The patch modifies paxctl so that it can "hijack" the PT_GNU_STACK or PT_NOTE headers (PT_GNU_STACK is a no-op on PaX systems; PT_NOTE is no-op on all systems by definition) and reuse them as a PT_PAX_FLAGS header.  It turns out that almost all alien binaries have a PT_NOTE field.

A new option, "-f", is implemented to enable the new functionality, which is off by default.
Comment 1 Kevin F. Quinn (RETIRED) gentoo-dev 2005-05-02 00:21:05 UTC
Created attachment 57800 [details, diff]
Add -f option to force paxctl to hijack PT_NOTE, PT_GNU_STACK
Comment 2 solar (RETIRED) gentoo-dev 2005-05-02 04:40:50 UTC
We have concerns about hijacking the NOTE and not removing the elf segment headers 
(.note .note.ABI.tag) For the NOTE I'm also pretty sure that if it has a section 
header note and it's marked with the A (alloc) flag marking you should not hijack
it.

PT_GNU_STACK (great idea)
Comment 3 solar (RETIRED) gentoo-dev 2005-05-02 04:41:25 UTC
What would be really ideal is to inject a new program header.
Comment 4 Kevin F. Quinn (RETIRED) gentoo-dev 2005-05-02 11:58:52 UTC
My reading of the TIS ELF spec v1.2 is that the PT_NOTE and SHT_NOTE sections are not permitted to affect execution behaviour (book 1, 2-5 second note).  A corollary of this is that the executable cannot therefore alter its execution behaviour as a result of the existence or contents of NOTEs.  So as far as actually running an executable is concerned, hijacking PT_NOTE should be harmless.  I figure that anyone on Gentoo implementing, for example, a signature verifier using the PT_NOTE header to hold the signature, will have modified the toolchain to do that and therefore will be building from source anyway.

It's fun hijacking PT_GNU_STACK :-> but of limited real use as it tends not to exist on vendor-supplied binaries.  If it exists on an ELF file, more often than not it's a shared library not the launch executable, which isn't much use with PaX.

I did consider injecting a new header, but pageexec suggested that it may be problematic.  I'm still working through the ELF spec to find all the gotchas; in particular the implications of the PT_PHDR header (2-3 last paragraph) may not be trivial.
Comment 5 PaX Team 2005-05-02 16:20:46 UTC
first of all, i'm very sorry that i hadn't gotten back to you for such a long time... now i finally kicked my own butt and offer the following for testing: grsecurity.net/~paxguy1/test/paxctl-0.3.tar.gz . it is different from your approach in that it deals explicitly with PT_GNU_STACK only. as for PT_NOTE, it does affect execution behaviour, but only at startup, e.g., the .note.ABI-tag section tells ld.so which is the minimum required version of the kernel for the given binary (normally it matters for glibc only i think, this is what prevents you from booting a too old kernel under a glibc that expects a certain minimum kernel ABI, i.e., syscalls), on other archs it can tell which kind of emulation ABI is needed for the given binary (iirc, the BSDs mark their own executables in PT_NOTE).
Comment 6 Kevin F. Quinn (RETIRED) gentoo-dev 2005-05-03 00:07:48 UTC
Sorry pageexec; didn't think to cc you.

Unfortunately in practice hijacking PT_GNU_STACK doesn't get us very far; none of  the foreign binaries I have contain it.

Seems like the only way to deal with that is to rewrite the ELF file.  Maybe libelf can help; I'll have a go.
Comment 7 PaX Team 2005-05-03 03:32:25 UTC
'execstack -[cs] binary; paxctl -c binary' ;-). if that fails, we can hardly do any better without some major ELF hacking (reducing the first PT_LOAD's base and adding space there). i didn't want to lift the code from execstack because IMHO it's just not worth the effort, prelink is installed everywhere these days, so is execstack.
Comment 8 solar (RETIRED) gentoo-dev 2005-05-03 06:00:18 UTC
In the case of java and probably most other programs provided by a 3rd party 
vendor we wont really be able to inject a PT_GNU_STACK header for later conversion 
into PT_PAX_FLAGS using execstack. tigger pointed out to me that execstack only 
works with ET_DYN. I tested this and found it to be true.

cp /opt/blackdown*/bin/java . ;  execstack.dyn -s ./java
execstack.dyn: ./java: Reshuffling of objects to make room for
program header entry only supported for shared libraries
Comment 9 PaX Team 2005-05-03 07:12:06 UTC
before trying reshuffling, execstack tries a few trivial injection methods, i meant to rely on those. reshuffling ET_EXEC files is not possible in general that's why execstack doesn't do it. one method that could work is the extension of the first PT_LOAD segment downwards to make room for the expanded program header, but that's not a 5-minute hack (this is not meant to discourage anyone, just trying to explain why i'm trying to keep changes minimal/simple).
Comment 10 Kevin F. Quinn (RETIRED) gentoo-dev 2005-05-03 10:49:22 UTC
How about adding a PT_LOAD segment to be loaded at the end of the executable; i.e. at VirtAddr+MemSiz of the highest existing PT_LOAD segment, and place the expanded PHDR there (adjusting the Elf header appropriatey).  If I read right, the PHDR entry in the PHDR itself has to be before that of any PT_LOAD segment, but it shouldn't be a problem locating the actual header segment itself anywhere.  The elf spec explicitly states that only the location of the ELF header can be assumed, so presumably anthing that wants to access the PHDR segment has to find it through the Elf header.
Comment 11 PaX Team 2005-05-03 13:49:48 UTC
adding another PT_LOAD on the top has a potential issue with the .bss and the brk() based heap since in normal files they're closely related, however sticking a PT_LOAD between the two will change this (it's a somewhat similar issue to what arises with brk() randomization, i think emacs during build breaks because of that). so really the safest approach is to put the program headers below the image, not above it (which then raises the nice implementation problems ;-).
Comment 12 PaX Team 2005-05-03 13:55:33 UTC
i released paxctl 0.3 that converts PT_GNU_STACK into PT_PAX_FLAGS, further development (if any) will go into 0.4.
Comment 13 Kevin F. Quinn (RETIRED) gentoo-dev 2005-05-04 15:43:00 UTC
Created attachment 58078 [details]
Attempt 1 at extending the first PT_LOAD downwards

Well, here goes nothing.  For simplicity, I've restricted myself to ELF files
that conform to a few rules, at least for proof (or otherwise) of concept.

Unfortunately, although it looks like it does what I intended it to do
(comparing readelf output before and after indicates as much), the resulting
ELFs are killed immediately by the kernel.  Perhaps because the lowest address
is below 08004800 - in which case the whole game is a no-go.

On the other hand, maybe I've done something stupid...
Comment 14 The ELFsh crew 2005-05-05 15:37:22 UTC
In your output binary the PT_PHDR segment is starting in the middle of the ELF header, which is why your binary is killed. You need to extend down of 1 page the first PT_LOAD segment and adapt the PT_PHDR in order to have the room for additional PHT entries.

The function : elfsh_inject_code_section() in section.c shows an example of this manipulation (not used for the same thing however since here a complete section is added in the additional pages)

http://elfsh.devhell.org/files/elfsh-0.51b3/libelfsh/section.c

- The ELF shell crew
Comment 15 Kevin F. Quinn (RETIRED) gentoo-dev 2005-05-06 00:14:28 UTC
Created attachment 58186 [details]
Working proof-of concept PHDR insertion widget

Got it - problem was that when I moved the first PT_LOAD segment, I didn't take
account of its alignment.  This updated widget hard-codes the alignment to
0x1000, just to demonstrate the trick works (obviously it should really get the
alignment from the PT_PHDR of the PT_LOAD segment).

I've only tested that relevant executables load ok and run as far as dumping
out usage text, but so far it seems to work!  It remains to be seen whether it
breaks execution at all, but it looks promising.  I've rigged my blackdown-jdk
binaries with it, so we'll see.
Comment 16 Kevin F. Quinn (RETIRED) gentoo-dev 2005-05-30 04:31:50 UTC
a little update.  I've run various things through this, and providing I set flag
'x' (the utility leaves them all '-') I don't get any kills.  In particular bdc
seems to work (so far this only seems happy with 'mxe', if the flags are set via
PT header rather than chpax).

I do get a segfault when running it on chpax'ed binaries - I'll have to track
that down.

I'll get around to writing a tidier version soonish.  Originally I rigged it to
generate a PT_NULL header; the idea being to have paxctl hijack it as a separate
operation - thoughts?

Comment 17 solar (RETIRED) gentoo-dev 2005-05-30 09:13:47 UTC
After you hacked out the initial support to work for ET_EXEC ET_DYN bins 
I wanted to import this tool or a variation there of into 
http://www.gentoo.org/cgi-bin/viewcvs.cgi/pax-utils/?root=gentoo-projects&hideattic=1
(assuming you GPL it)
Comment 18 PaX Team 2005-05-30 12:45:14 UTC
(In reply to comment #16)
> a little update.  I've run various things through this, and providing I set flag
> 'x' (the utility leaves them all '-') I don't get any kills.

FYI, the default value from ld is equivalent to paxctl -zex.

> I'll get around to writing a tidier version soonish.  Originally I rigged it to
> generate a PT_NULL header; the idea being to have paxctl hijack it as a
separate operation - thoughts?

i don't mind directly including it into paxctl as well but it has to go through
lots of testing before that. my main worry is that injecting something at the
beginning of the image changes all file offsets afterwards, so any such info in
structure fields must be all updated, this including not only mapped sections
but stuff like debug symbols, etc as well. did you systematically check all this
out already and make sure all file offset fields continue to refer to their
original places?
Comment 19 Kevin F. Quinn (RETIRED) gentoo-dev 2005-05-30 13:32:23 UTC
I was thinking of a separate widget for a while, to be applied on an "if you
dare" basis, to get confidence and maturity- pax-utils is an ideal repository
for the moment (it'll certainly be GPL).  On a related note we're putting
together a "wrapper" for the various pax widgets so that we can abstract what
ebuilds do into a simple call; this allows us to muck around with the set of
widgets as time goes on without disrupting ebuild maintainers - hopefully.

With regards file offset fields, I tried to cover everything, but I'll certainly
go through that again more thoroughly.  There are a few other things to tidy up
(e.g. making it 64bit & 32bit compliant, deciding more carefully what
assumptions need to be made and hence validated).  Also there's ET_DYN to think
about.  I've concentrated on ET_EXEC to keep things simple, and because that's
what most (if not all) vendor-built binaries are.

I was also keeping an eye on the elfsh thing; there's some talk about adding PT
entry injection on their website.  It's bit quiet there at the moment, but I
haven't made any noise yet.
Comment 20 PaX Team 2005-05-30 17:37:04 UTC
(In reply to comment #19)
> With regards file offset fields, I tried to cover everything, but I'll certainly
> go through that again more thoroughly.  There are a few other things to tidy up
> (e.g. making it 64bit & 32bit compliant, deciding more carefully what
> assumptions need to be made and hence validated).

one thing that may matter for gentoo is cross-compilation where you have to take
into account byte-endianess (something i blissfully ignore for paxctl ;-).

>  Also there's ET_DYN to think about.  I've concentrated on ET_EXEC to keep
things simple, and because that's what most (if not all) vendor-built binaries are.

i don't see a problem with ET_DYN. only executables matter for PaX so that means
you'd have care about PIEs only, not .so libraries. and any toolchain version
that can produce a PIE will already produce PT_GNU_STACK so we can always reuse
that.

> I was also keeping an eye on the elfsh thing; there's some talk about adding PT
> entry injection on their website.  It's bit quiet there at the moment, but I
> haven't made any noise yet.

elfsh should already be able to do it (etrel_inject if i'm not mistaken).
Comment 21 Kevin F. Quinn (RETIRED) gentoo-dev 2006-07-24 16:21:49 UTC
This can be closed now paxctl has the magic :)