PaX is a kernel security patch hosted at pax.grsecurity.net. This patch implements kernel level memory protections for user space applications. On i386, these protections incur a minor overhead; on other architectures, such as x86-64, PowerPC, and Sparc, these protections incur no overhead aside from the raw extra code added by PaX. The demonstration files for this exist in the pax/ demo directory.
PaX is a kernel patch. As such, the kernel must be merged with PaX, and certain settings must be adjusted. PaX also requires some modifications to the binaries on the system; the absolutely required changes can happen to a live system without recompilation or other major tasks if needed.
Data useful to demonstrate the installation of a skeletal PaX implementation using legacy EI_PAX for binary marking and not using PIC executables is available from the pax/ demo directory.
PaX utilizes an NX bit and mprotect() restrictions to implement memory protections which prevent direct shellcode injection. PaX also implements full Address Space Layout Randomization, which in the lack of an information leak will obfuscate the process of executing another class of exploits, return-to-libc attacks.
By utilizing the protections available with PaX, entire classes of exploits are made impossible or unlikely. Some exploits are simply not technically possible because certain factors are removed with PaX; while others rely on variables whose value cannot be reliably predicted, and thus cannot be guaranteed effective.
On i386, there is no NX bit in hardware; thus, one is emulated for a nominal cost. There are two emulation methods, PAGEEXEC and SEGMEXEC. Each method has its own faults and its own merits. It should be noted, however, that on k6-2, PAGEEXEC cannot properly function and SHOULD NOT be enabled. This is due to the k6-2 having a different TLB architecture which in most cases is compatible with other i386 processors; the advanced use that PAGEEXEC makes of the TLB is NOT compatible with the k6-2 TLB architecture.
SEGMEXEC gives guaranteed minimal overhead at the cost of a halved VM space. SEGMEXEC, in unofficial tests consisting of a kernel compile, incurred less than 1% performance overhead (0.7%). The halved VM space rarely makes a difference. This method is only available on i386.
On i386, PAGEEXEC gives guaranteed full VM address space at the cost of forcing off the vsyscall page. The method PAGEEXEC uses relies on having an upper code limit as a speed-up, which results in almost no overhead and no trade-off. The vsyscall page, as well as certain memory allocation patters, will cause this speed-up to fail, forcing PAGEEXEC to fall back to its original emulation method. This method causes the MMU to require kernel assistance, creating in some cases excessively high overhead.
On non-i386 architectures, PAGEEXEC relies on the NX bit in hardware, which incurs no overhead and has no extra caveats. Effectively, PAGEEXEC on non-i386 architectures is free.
ASLR randomly orders the individual segments of memory needed by a program in such a way that the process knows where they are, but an attacker does not. Basic information leaking, such as reading /proc/(pid)/maps counters ASLR; however, it is possible to obscure these leaks. Most remote attacks won't have shell access anyway, so such information leaks are immaterial.
Using ASLR, it is also recommended to use Position Independent Executables. These executables are compiled with -fPIE. A PIE will have less overhead when using ASLR in comparison to relocating position-dependent ET_EXEC executables. It also will not raise false alarms, an event which in rare cases happens in ET_EXEC executable relocation, causing PaX to mistakenly kill the process.
The overhead of PaX is very low. The greatest overhead it can produce is with PAGEEXEC falling back to the old method on i386 with certain memory access patterns. By using SEGMEXEC, however, overhead can be guaranteed to sustain at less than 1%.
PaX, like any security system, imposes restrictions on operations that can be performed by applications. These restrictions may cause certain applications to cease to function; restrictions must be removed for broken programs until they can be fixed, if possible.
Some programs generate code at runtime, such as Java and Mono. In theory, these could export the code to temporary files readable only by the user, and not writable (-r-x------). These files would exist in /tmp inside directories only accessable by the user (drwx------). The code could then be mmap()ed in as PROT_READ|PROT_EXEC, as noted in the PaX documentation:
attack method (1) is possible if the attacker can have the attacked task create, write to and mmap a file. This in turn requires attack method (2), so the analysis of that applies here as well (note that although not part of PaX per se, it is recommended among others, that production systems use an access control system that would prevent this venue of attack).
It will always be possible to mmap() a file as code; this is how shared libraries work. It will always be possible to write a file. It is still not predicted what the security implications of having some of the data from the virtual machine in /tmp, however; these solutions should be looked into carefully by anyone planning to implement them.
PaX can affect third party vendor packages adversely. Such software can be marked by the vendor or end user. If the end user does not wish to accept the extra responsibility in these cases, a non-PaX kernel can be used. PaX can be easily disabled by booting a Debian stock kernel without PaX.
PaX causes some programs to break. The actual executable binary files for these programs can be marked by altering a field in the ELF header, which means these markings are filesystem independent and can be done either before packaging the file in the .deb package or later by debconf.
Different tasks break depending on architecture. Typically, mono, java, and wine break. Many if not all of the i386 apps that break are already located, and markings are in pax.conf in the pax/ demonstration directory.
There are two different sets of flags used by PaX. One is a legacy EI_PAX field which can be used, but is not considered "stable;" certain programs such as strip may clear EI_PAX flags. The other is PT_PAX_FLAGS, which is generated by a specially patched binutils. The patch needed is available on the PaX homepage. The PT_PAX_FLAGS field does not interfere with normal operation on non-PaX systems, and is recommended over EI_PAX.
The chpax program alters EI_PAX, while paxctl alters PT_PAX_FLAGS.
An interesting method for marking binaries would be to make sure every program on the system has PT_PAX_FLAGS and set PaX in softmode. While in softmode, only binaries explicitly marked to have restrictions enabled will be affected by PaX. In this mode, all distributed binaries will be marked with paxctl -PSeMRx by default. Breaking binaries will have flags adjusted to fit properly. Third party software will of course not be marked, and PaX will not place restrictions on such binaries while in softmode.
It is important to give the user the option of allowing Debian to automatically manage PaX flags, or to be asked at installation time by debconf. Most users will want Debian to simply "work," and will just consider the extra security as a bonus. There are still cases where the administrator wants or needs to know what's going on on his system. Both situations must be handled.
A suggested method for easily handling this is in our list of things we need.