PT_GNU_STACK
You upgrade your linux distro and suddenly things are failing with error messages like "error while loading shared libraries: libfoobar.so.123: cannot enable executable stack as shared object requires: Permission denied"
what happened?
Well, you just have become yet another witness of the decay of the GNU toolchain. Besides that gcc and glibc becomes more and more bloated every day, gcc bugreports being randomly closed without fixing them and so on, we since some time have the beautifull PT_GNU_STACK feature in every GNU tool which tries very hard to make the stack of application executable, without grsec your system will be more vulnerable, with grsec stuff will fail hard as grsec will not give apps an executable stack if they dont need one and the redhead ehm i mean gnu libc/loader/… will then simply refuse to continue if the unneccesary executablity isnt provided
what exactly is PT_GNU_STACK?
PT_GNU_STACK is a entry in the elf file format which contains the access rights (read, write, execute) of the stack, so far so good, nothing bad here, the problem is how these access rights are choosen by the tools …
The idea behind PT_GNU_STACK / choosing the access rights
The stack is always read and writeable obviously thats needed, so we are left with the question about it being executable, when linking objects together into an library or libraries into an application, a single object requireing an executable stack will cause the final application and all libraries which contain that object to need an executable stack, if no object needs an executable stack the final application wont need one either
The design and implementation of PT_GNU_STACK
Every tool in the gnu toolchain will from source over assembly, objects and libraries to final application merge the PT_GNU_STACK access rights so that a single object needing a executable stack will cause the final application to need one, in case of doubt (no PT_GNU_STACK entry) the default is that the specific object needs an executable stack
The problem with this / the total failure of the PT_GNU_STACK idea
Undecideablility at the compilation and assembly level
Deciding if a piece of code needs an executable stack is proofably not possible, its indeed equivalent to solving the halting problem …
so gcc, gas and so on guess if a pice of code needs an executeable stack and if they are unsure, they claim that it does
Undecideablility at the global level
For example calling a function through a global pointer, the compiler compiling that file cant decide about the stack access rights as it doesnt know all code which changes the pointer, the linker later would have to dissassemble the object files again just to have the info needed to decide it …
several definitions of executability
If you execute code on the stack, does it need to be executable? if you use redheads execshield then AFAIK yes, if you use grsec it depends upon the code, as grsec can detect and emulate some common and harmless sequences of instrucions on the stack (trampolines)
Even if an application needs an executable stack for some feature
Theres no need to have an executable stack if that feature isnt used, actually applications might explicily try to enable / disable executability of a specific part of memory depening upon needs, gcc will in that case almost certainly claim that the app always needs an executable stack …
All these things cause applications to claim that they require an executable stack while they simply do not, which makes your system much more vulnerable to attacks
The alternative
Mark final applications which need an executable stack as such, make the default to not requireing an executable stack
whats the difference
Well, in practice more then 99% of all applications dont need an executable stack and if a application needs an executable stack but doesnt have one then that causes a clear failure which will be noticed immedeatly and can be fixed by marking that application as needing a executable stack
OTOH the current PT_GNU_STACK system with its pass the flags from source to final app ideally needs corretures to be done for each source file which the gnu tools cant deal with automatically, and there are many more source files then applications not to mention that the error rate at the application level seems to be far in excess of 1%
furthermore marking an app as requireing an executable stack while it actually doesnt, wont produce any warning, error or otherwise any hint that something is wrong while security is greatly impaired
The revolution will not be televised. Shoot, it won’t even compile.
Comment by Multimedia Mike — 2006-05-23 @ 17:21
Some worthwhile context here:
http://www.ussg.iu.edu/hypermail/linux/kernel/0406.0/0611.html
The discussion was Linus asking what non-executable stack settings would break, and the answer was that “on Fedora, almost nothing” because Fedora doesn’t use executable stacks. Nice to know.
Granted, its an old comment, but its a good attitude to start out with.
Comment by Michael T. Babcock — 2006-05-25 @ 02:54
yes, nearly everything works with non-exec stacks, the problem is that the current PT_GNU_STACK system makes it VERY hard to make stacks non-exec by default, this causes alot of uneeded work overriding many apps instead of 0.1% and it makes your system significantly less secure
if fedora really has non-exec stacks for all programs is something i doubt, aftar all they designed this mess, or does fedora have an option to ignore their own PT_GNU_STACK and make all programs use non-exec stacks? if so how do they deal with the 0.1% of programs which actually need a exec stack?
Comment by Michael — 2006-05-25 @ 11:42
People mostly disable SELinux and non-executable stack on Fedora anyway “everything works” is a big lie. Seems like they allow to turn off executable stack protection, more info at http://home.gagme.com/greg/linux/fc5-tips.php .
Comment by cartman — 2006-06-01 @ 08:32
That stack handling stuff was definitly a horrible, “support crap first” instead of “security first” decision.
E.g. MPlayer does not need executable stack, but there is no chance the compiler/linker can find out, since how should that know what e.g. the binary codecs do? So you need an extra linker flag to tell it to really use non-exec stack. But since that is not supported everywhere you need another configure check. And again you have > 10 lines of code just to fix a crappy decision.
Comment by Reimar — 2006-06-01 @ 09:20
Yay for more flaming of the ever-broken GNU toolchain!
Of course I doubt people will like my toolchain more since it’s entirely 80s technology but hey it’s simple and doesn’t do creepy stuff behind your back. :)
Comment by Rich — 2006-08-02 @ 08:08