In April 1997, Solar Designer sent his famous “Linux kernel patch to remove stack exec permission” for Linux 2.30.0 x86 on bugtraq. Four months later, he published a followup, formalising ret2libc, along with a suggested “fix”.
This lead to an other famous email in January 1998, by Rafal Wojtczuk: “Defeating Solar Designer’s Non-executable Stack Patch”.
Solardiz’ patch was the foundation of Openwall, an hardened Linux distribution.
PaX (PAge eXecute) designed PAGEEXEC in August 2000, and it was implemented and released in October 2000, based on ideas from the plex86 project. It provided non-executable pages for IA-32 (i386) processors, using pagination.
In January 2001, Securewave released a non-executable stack implementation for Windows NT/2000 called SecureStack.
- creating executable anonymous mappings
- creating executable/writable file mappings
- making an executable/read-only file mapping writable except for performing relocations on an
ET_DYNELF file (non-PIC shared library)
- making a non-executable mapping executable
In July 2002, Artur Grabowski started to implement support for a non-executable stack in OpenBSD, and Theo de Raadt committed a non-executable BSS. One month after, the heap was marked non-executable, by Artur Grabowski.
SEGMEXEC is released by the PaX
Team, to replace
of pagination, as well as VMA (virtual memory area)
mirroring to detect
and prevent code injection.
In November 2002, OpenBSD 3.2 was released with a non-executable stack and heap on i386, sparc, sparc64, alpha, powerpc, as well a no-exec data and bss on sparc, sparc64, and alpha.
In January 2003, Dale Rahn
.rodata in a separate segment on OpenBSD, to make it read-only.
was add to PaX in April
While not being exactly a “PAGEEXEC for kernel-land”, it’s based on the same
idea as SEGMEXEC: non-executable pages and read-only things (syscall table,
GDT), as much as
In May 2003, OpenBSD 3.3, came with
W^X for userland on sparc, sparc64, alpha and hppa, preventing memory from
being mapped as writeable and executable at the same time.
In November 2003, spender did a talk about PaX: The Guaranteed End of Arbitrary
featuring an interesting comparison between PaX’
PAGEXEC and OpenBSD’s W^X.
W^X on i386 for userland has been added on OpenBSD
3.4, released in November 2003.
In May 2004, Theo de Raadt spoke about Exploit mitigation on
BSDCan04, explaining that it isn’t possible to
have per-page W^X granularity on architectures without the per-page X-bit,
which is exactly what PaX’
SEGMEXEC is doing.
In January 2015, 12 years later, Theo de Raadt announced that thanks to the work of Mike Larkin, no part of the OpenBSD kernel is writeable and executable any more, on amd64. Seven months later, in August 2015, i386 was covered too.
In 2019, OpenBSD made ELF headers non-executable for i386, but only for machines with the NX bit: It doesn’t add anything security-wise, since the odds of finding valid and useful code there is non-existent, but why not.
Having no memory both writeable and executable is an excellent mitigation against the introduction of new code by an attacker, both in kernel-land and in user-land, forcing attackers to use more convoluted ways to achieve arbitrary code execution.