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