Skip to content
Advertisement

Why aren’t glibc’s function addresses randomized when ASLR is enabled?

In trying to understand ASLR, I built this simple program:

#include <stdio.h>
#include <stdlib.h>

int main() {
    printf("%pn", &system);
    return 0;
}

ALSR seems to be enabled:

$ cat /proc/sys/kernel/randomize_va_space
2

and I used GCC to compile the program:

$ gcc aslrtest.c

Every time I run this program, it prints the same address (0x400450).

I would expect this program to print a different address each time if glibc is loaded at a random address. This is surprising to me, especially given that preventing return-to-libc attacks is supposed to be a primary motivation for ASLR (in particular the system() call).

Am I wrong in expecting that the address of system() should be randomized? Or is there likely something wrong with my configuration?

Advertisement

Answer

Any references to a function from a shared library that’s made from a non-position-independent object file in the main program requires a PLT entry through which the caller can make the call via a call instruction that’s resolved to a fixed address at link-time. This is because the object file was not built with special code (PIC) to enable it to support calling a function at a variable address.

Whenever such a PLT entry is used for a function in a library, the address of this PLT entry, not the original address of the function, becomes its “official” address (as in your example where you printed the address of system). This is necessary because the address of a function must be seen the same way from all parts of a C program; it’s not permitted by the language for the address of system to vary based on which part of the program is looking at it, as this would break the rule that two pointers to the same function compare as equal.

If you really want to get the benefits of ASLR against attacks that call a function using a known fixed address, you need to build the main program as PIE.

Advertisement