3

I checked if ASLR is enabled as follows and I think it is:

[user@localhost test]$ cat /proc/sys/kernel/randomize_va_space
2

I tried testing it with the following program:

test.c:

#include <stdio.h>
int main(void)
{
    printf("%p\n", main);
    return 1;
}

I expected, if ASLR is active, to a different address for each run, right? But I got the same each time. I tested both for 64bit and 32bit executables. I am using a 64bit Arch Linux system to test this:

[user@localhost test]$ gcc test.c -o test
[user@localhost test]$ ./test
0x4004c6
[user@localhost test]$ ./test
0x4004c6
[user@localhost test]$ ./test
0x4004c6
[user@localhost test]$ ./test
0x4004c6
[user@localhost test]$ gcc -m32 test.c -o test
[user@localhost test]$ ./test
0x80483eb
[user@localhost test]$ ./test
0x80483eb
[user@localhost test]$ ./test
0x80483eb
[user@localhost test]$ ./test
0x80483eb

As you can see, the address is the same for every run. Doesn't this mean that ASLR is off?

Baruch
  • 20,590
  • 28
  • 126
  • 201

1 Answers1

10

Your executable must be position-independent to allow that.

gcc -pie -fPIE -o test test.c

Try running it this way, the address should visibly change on each run.

Non-PI executables are meant to be loaded at a fixed, explicitly non-random address stored in their ELF header. This assumption allows compiler and linker to hard-code absolute addresses into the output, making it smaller and faster on some targets.

Loading non-PI executables at any other address invalidates all those absolute references, resulting in SIGSEGV at best and some random code running at worst. The address of main can't be randomized safely because the compiler was allowed to assume that it won't be, so it's never done even if ASLR is enabled.

To allow randomization, the compiler must be told to generate position-independent code (-fPIE), and the resulting executable must be marked as position-independent (-pie) so that the kernel would know it's safe to load at any address.

Which options are necessary to achieve that depends a lot on toolchain configuration, -fpie, -fPIE, -fpic, -fPIC, some may generate PI code by default. The safe bet is to compile with -fPIE and link with -pie -fPIE.

arsv
  • 1,176
  • 9
  • 11
  • Thank you. I took some time to research -pie and -fpie before accepting, but it would probably help others if you explained briefly what these do or why this has to do with ASLR. – Baruch Aug 09 '16 at 20:21
  • Updated the post, hopefully it's self-contained enough now to be readable without much googling. – arsv Aug 10 '16 at 12:32
  • Related: [32-bit absolute addresses no longer allowed in x86-64 Linux?](https://stackoverflow.com/q/43367427) has more about PIE executables. – Peter Cordes Oct 04 '20 at 15:23