The Grsecurity Project
The grsecurity project, hosted on http://www.grsecurity.org, provides various patches to the Linux kernel which enhance your system's overall security. The various features brought by grsecurity are discussed in the next chapter; a comprehensive list is maintained on the grsecurity features page itself.
As grsecurity's features are mostly kernel-based, the majority of this document explains the various kernel features and their respective sysctl operands (if applicable).
Throughout this document we will talk about kernel configuration using the kernel variables like CONFIG_GRKERNSEC_PAX_NO_ACL_FLAGS. These are the variables that the kernel build process uses to determine if a certain feature needs to be compiled.
When you configure your kernel through make menuconfig or similar, you receive a user interface through which you can select the various kernel options. If you select the Help button at a certain kernel feature you will see at the top that it lists such a kernel variable.
You can therefore still configure your kernel as you like - with a bit of thinking. And if you can't find a certain option, there's always the possibility to edit /usr/src/linux/.config by hand :)
Of course, to be able to select the various grsecurity kernel options, you must enable grsecurity in your kernel.
Fighting the Exploitation of Software Bugs
PaX introduces a couple of security mechanisms that make it harder for attackers to exploit software bugs that involve memory corruption (so don't treat PaX as if it protects against all possible software bugs). The PaX introduction document talks about three possible exploit techniques:
- introduce/execute arbitrary code
- execute existing code out of original program order
- execute existing code in original program order with arbitrary data
One prevention method disallows executable code to be stored in writable memory. When we look at a process, it requires five memory regions:
- a data section which contains the statically allocated and global data
- a BSS region (Block Started by Symbol) which contains information about the zero-initialized data of the process
- a code region, also called the text segment, which contains the executable instructions
- a heap which contains the dynamically allocated memory
- a stack which contains the local variables
The first PaX prevention method, called NOEXEC, is meant to give control over the runtime code generation. It marks memory pages that do not contain executable code as non-executable. This means that the heap and the stack, which only contain variable data and shouldn't contain executable code, are marked as non-executable. Exploits that place code in these areas with the intention of running it will fail.
NOEXEC does more than this actually, interested readers should focus their attention to the PaX NOEXEC documentation.
The second PaX prevention method, called ASLR (Address Space Layout Randomization), randomize the addresses given to memory requests. Where previously memory was assigned contiguously (which means exploits know where the tasks' memory regions are situated) ASLR randomizes this allocation, rendering techniques that rely on this information useless.
More information about ASLR can be found online.
The recommended kernel setting for PaX is:
# # Security options # # # PaX # CONFIG_PAX=y # # PaX Control # # CONFIG_PAX_SOFTMODE is not set CONFIG_PAX_EI_PAX=y CONFIG_PAX_PT_PAX_FLAGS=y CONFIG_PAX_NO_ACL_FLAGS=y # CONFIG_PAX_HAVE_ACL_FLAGS is not set # CONFIG_PAX_HOOK_ACL_FLAGS is not set # # Non-executable pages # CONFIG_PAX_NOEXEC=y CONFIG_PAX_PAGEEXEC=y CONFIG_PAX_SEGMEXEC=y # CONFIG_PAX_DEFAULT_PAGEEXEC is not set CONFIG_PAX_DEFAULT_SEGMEXEC=y CONFIG_PAX_EMUTRAMP=y CONFIG_PAX_MPROTECT=y # CONFIG_PAX_NOELFRELOCS is not set # # Address Space Layout Randomization # CONFIG_PAX_ASLR=y CONFIG_PAX_RANDKSTACK=y CONFIG_PAX_RANDUSTACK=y CONFIG_PAX_RANDMMAP=y # # Miscellaneous hardening features # CONFIG_PAX_MEMORY_SANITIZE=y CONFIG_PAX_MEMORY_UDEREF=y CONFIG_KEYS=y # CONFIG_KEYS_DEBUG_PROC_KEYS is not set CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_SECURITY_NETWORK_XFRM=y CONFIG_SECURITY_CAPABILITIES=m CONFIG_SECURITY_ROOTPLUG=m
If you are running a non-x86 system you will observe that there is no CONFIG_GRKERNSEC_PAX_NOEXEC. You should select CONFIG_GRKERNSEC_PAX_PAGEEXEC instead as it is the only non-exec implementation around.
Not all Linux applications are happy with the PaX security restrictions. These tools include xorg-x11, java, mplayer, xmms and others. If you plan on using them you can elevate the protections for these applications using and paxctl. You can find it on AUR.
You can also use pax-utils, which is a small toolbox which contains useful applications to administrate a PaX aware server. Find it on AUR.
Interesting tools include scanelf and pspax:
- With scanelf you can scan over library and binary directories and list the various permissions and ELF types that pertain to running an ideal pax/grsec setup
- With pspax you can display PaX flags/capabilities/xattr from the kernel's perspective
Verifying the PaX Settings
Peter Busser has written a regression test suite called paxtest. This tool will check various cases of possible attack vectors and inform you of the result. When you run it, it will leave a logfile called paxtest.log in the current working directory.
# paxtest Executable anonymous mapping : Killed Executable bss : Killed Executable data : Killed Executable heap : Killed Executable stack : Killed Executable anonymous mapping (mprotect) : Killed Executable bss (mprotect) : Killed Executable data (mprotect) : Killed Executable heap (mprotect) : Killed Executable stack (mprotect) : Killed Executable shared library bss (mprotect) : Killed Executable shared library data (mprotect): Killed Writable text segments : Killed Anonymous mapping randomisation test : 16 bits (guessed) Heap randomisation test (ET_EXEC) : 13 bits (guessed) Heap randomisation test (ET_DYN) : 25 bits (guessed) Main executable randomisation (ET_EXEC) : 16 bits (guessed) Main executable randomisation (ET_DYN) : 17 bits (guessed) Shared library randomisation test : 16 bits (guessed) Stack randomisation test (SEGMEXEC) : 23 bits (guessed) Stack randomisation test (PAGEEXEC) : No randomisation Return to function (strcpy) : Vulnerable Return to function (memcpy) : Vulnerable Return to function (strcpy, RANDEXEC) : Killed Return to function (memcpy, RANDEXEC) : Killed Executable shared library bss : Killed Executable shared library data : Killed
In the above example run you notice that:
- strcpy and memcpy are listed as Vulnerable. This is expected and normal - it is simply showing the need for a technology such as ProPolice/SSP
- there is no randomization for PAGEEXEC. This is normal since our recommended x86 kernel configuration didn't activate the PAGEEXEC setting. However, on arches that support a true NX (non-executable) bit (most of them do, including x86_64), PAGEEXEC is the only method available for NOEXEC and has no performance hit.