Position-independent Executable (PIE)

The protection mechanism ASLR was explained in the previous chapter. It introduces randomness to the memory layout of processes. Thus it is harder for attackers to correctly organize exploit execution. However, remember that even with ASLR fully enabled, the executable itself as well as the PLT are still not randomized. Position-independent Code (PIC) is a compiler feature which produces code that can be loaded at arbitrary addresses. Binaries consisting of only position-independent code are called Position-independent Executables (PIE).

Similar to ASLR, the below program illustrates the effect of PIE on process addresses.

pie/addresses.c
// gcc addresses.c -ldl
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
 
int main()
{
    int stack;
    int *heap = malloc(sizeof(int));
 
    printf("executable: %p\n", &main);
    printf("stack: %p\n", &stack);
    printf("heap: %p\n", heap);
    printf("system@plt: %p\n", &system);
 
    void *handle = dlopen("libc.so.6", RTLD_NOW | RTLD_GLOBAL);
    printf("libc: %p\n", handle);
    printf("system: %p\n", dlsym(handle, "system"));
 
    free(heap);
    return 0;
}

Having ASLR enabled results on the following output.

$ echo 2 | sudo tee /proc/sys/kernel/randomize_va_space
2
$ ./a.out 
executable: 0x55e8208157ca
stack: 0x7ffe5d194edc
heap: 0x55e821d11010
system@plt: 0x7f2904b01480
libc: 0x7f29052849b0
system: 0x7f2904b01480
$ ./a.out 
executable: 0x55716e0817ca
stack: 0x7ffd23f4e40c
heap: 0x55716ee0e010
system@plt: 0x7fe427397480
libc: 0x7fe427b1a9b0
system: 0x7fe427397480

It can be concluded that additionally to ASLR also the executable itself and the PLT are randomized.

ASLR value Executable Stack Heap PLT Shared libraries
2

Without leaking an address at runtime which can be used to calculate the address of further gadgets for a ROP chain, PIE heavily increases security1).

Note that PIE is a compiler option and needs to be applied to every executable separately. Following PIE-related flags are used by GCC2).

Flag Description
-fpie Enable PIE compilation
-fno-pie Disable PIE compilation
-pie Enable PIE for linking
-no-pie Disable PIE for linking

Depending on the used distribution, PIE might also be enabled by default.

$ gcc -v 2>&1 | grep -o -a -P "\S+default-pie"
--enable-default-pie

Although increasing security, PIE also impacts the performance of an executable3).



← Back to Address Space Layout Randomization (ASLR) Overview Continue with NX bit →

3)
Mathias Payer (2012). „Too much PIE is bad for performance.“.