# PaX

PaX is included in the grsecurity kernel package in the official repositories. This page also applies to the standalone linux-pax package in the AUR.

## PaX exceptions

Some of the PaX exploit mitigations prevent certain applications from running and require the executables to be marked with exceptions. Extended attributes can be used to exclude executables from one or more of the features. For example, to disable the MPROTECT and RANDMMAP features:

    $ setfattr -n user.pax.flags -v "mr" /usr/bin/problematic_binary

Note: The linux-grsec package only supports the extended attributes, and does not include support for the ELF exception markers. The extended attributes do not require special tooling and leave the binaries unaltered, making them a far better option.

The MPROTECT feature is by far the most common source of issues, and linux-grsec defaults to logging messages to the kernel log when this results in a process being killed.

The pax-utils package includes some useful tools. For example, the `pspax` utility can display PaX permissions from the kernel's perspective along with capabilities. The `scanelf` tool can be used to query attributes of binaries.

One might also use getfattr to retrieve extended attributes set above (or set by paxd described below) if they choose not to run pax-utils or if they want to check the attributes of a process not running:

    $ getfattr -n user.pax.flags /usr/bin/problematic_binary

### Using the paxd package

The paxd package provided in the official repositories uses a daemon to automatically apply PaX exceptions from `/etc/paxd.conf` whenever a Pacman transaction occurs or the configuration file is modified. This is the officially supported way of applying these exceptions for binaries provided by packages. When Pacman gains support for hooks, the daemon can be dropped in favour of a post-install/upgrade hook.

### Using linux-pax-flags AUR package

Note: linux-pax-flags defaults to using ELF markers rather than extended attributes, so it will not work with linux-grsec by default.

The linux-pax-flags program takes care of marking exceptions on executables in user home directories in addition to global ones, which is not covered by paxd. When you run this program it will set the PaX flags for most problematic programs for you. After you find what PaX flags need to be set post a comment on the linux-pax-flags AUR package so it can be added.

More extensive documentation of the linux-pax-flags utility is to be found on its man page.

### Soft mode

Setting `kernel.pax.softmode=1` with sysctl will result in the mitigations being opt-in rather than opt-out. This could be used to apply the mitigations only to certain high-risk binaries such as web services on a server without causing any issues. However, opting out of the mitigations results in a significantly more secure system and paxd takes care of nearly all the work automatically.

## 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.

    PaX disabled

    Executable anonymous mapping             : Killed
    Executable bss                           : Killed
    Executable data                          : Killed
    Executable heap                          : Killed
    Executable stack                         : Killed
    Executable shared library bss            : Killed
    Executable shared library data           : Killed
    Executable anonymous mapping (mprotect)  : Vulnerable
    Executable bss (mprotect)                : Vulnerable
    Executable data (mprotect)               : Vulnerable
    Executable heap (mprotect)               : Vulnerable
    Executable stack (mprotect)              : Vulnerable
    Executable shared library bss (mprotect) : Vulnerable
    Executable shared library data (mprotect): Vulnerable
    Writable text segments                   : Vulnerable
    Anonymous mapping randomisation test     : 28 bits (guessed)
    Heap randomisation test (ET_EXEC)        : No randomisation
    Heap randomisation test (PIE)            : 28 bits (guessed)
    Main executable randomisation (ET_EXEC)  : 28 bits (guessed)
    Main executable randomisation (PIE)      : 28 bits (guessed)
    Shared library randomisation test        : 28 bits (guessed)
    Stack randomisation test (SEGMEXEC)      : 28 bits (guessed)
    Stack randomisation test (PAGEEXEC)      : 28 bits (guessed)
    Arg/env randomisation test (SEGMEXEC)    : 32 bits (guessed)
    Arg/env randomisation test (PAGEEXEC)    : 32 bits (guessed)
    Randomization under memory exhaustion @~0: 28 bits (guessed)
    Randomization under memory exhaustion @0 : 28 bits (guessed)
    Return to function (strcpy)              : paxtest: return address contains a NULL byte.
    Return to function (memcpy)              : Killed
    Return to function (strcpy, PIE)         : paxtest: return address contains a NULL byte.
    Return to function (memcpy, PIE)         : Killed

    PaX enabled

    Executable anonymous mapping             : Killed
    Executable bss                           : Killed
    Executable data                          : Killed
    Executable heap                          : Killed
    Executable stack                         : Killed
    Executable shared library bss            : Killed
    Executable shared library data           : 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     : 33 bits (guessed)
    Heap randomisation test (ET_EXEC)        : 22 bits (guessed)
    Heap randomisation test (PIE)            : 40 bits (guessed)
    Main executable randomisation (ET_EXEC)  : 33 bits (guessed)
    Main executable randomisation (PIE)      : 33 bits (guessed)
    Shared library randomisation test        : 33 bits (guessed)
    Stack randomisation test (SEGMEXEC)      : 40 bits (guessed)
    Stack randomisation test (PAGEEXEC)      : 40 bits (guessed)
    Arg/env randomisation test (SEGMEXEC)    : 44 bits (guessed)
    Arg/env randomisation test (PAGEEXEC)    : 44 bits (guessed)
    Randomization under memory exhaustion @~0: 33 bits (guessed)
    Randomization under memory exhaustion @0 : 33 bits (guessed)
    Return to function (strcpy)              : paxtest: return address contains a NULL byte.
    Return to function (memcpy)              : Killed
    Return to function (strcpy, PIE)         : paxtest: return address contains a NULL byte.
    Return to function (memcpy, PIE)         : Killed

## 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 do not treat PaX as if it protects against all possible software bugs). The PaX introduction document talks about three possible exploit techniques:

1. introduce/execute arbitrary code
2. execute existing code out of original program order
3. 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:

1. a data section which contains the statically allocated and global data
2. a BSS region (Block Started by Symbol) which contains information about the zero-initialized data of the process
3. a code region, also called the text segment, which contains the executable instructions
4. a heap which contains the dynamically allocated memory
5. 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 should not 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.

Categories:

- Kernel
- Security