W^X and !W
W^X works. Are there other smart permission changes? Introducing !W
void
exit(int status)
{
register struct atexit *p;
register int n;
for (p = __atexit; p; p = p->next)
for (n = p->ind; --n >= 0;)
(*p->fns[n])();
if (__cleanup)
(*__cleanup)();
_exit(status);
}
__atexit is a *writeable* linked list of function pointers
If attacker can overwrite any location in memory -> can run his code when program exits
atexit(3) Modification:
maintain lists of pages (to function pointers) cleverly made non-writeable
__cleanup is a *writeable* pointer used by stdio (if stdio is not used, avoid linking)
Changed stdio to use the atexit(3) change described above
We call this policy change by the name !W or "non-writeable"
Other library components can use such tricks
Basically free