Search code examples
cmemorymmapaslr

Using ASLR To Get Random Anonmous Mapping Address


Consider this code running on an up-to-date Ubuntu 16.04 x86_64 system:

void main(int argc, char *argv[])                                                                      
{                                                                                                      
    while(1) {                                                                                         
        char *x = (char *)mmap(0, 1000, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);   
        printf("%p\n", x);                                                                             
        munmap(x, 1000);                                                                               
    }                                                                                                  
}                                                                                                      

Whose output looks like this:

0x7f02ca14c000
0x7f02ca14c000
0x7f02ca14c000
0x7f02ca14c000
...

I would have expected, having provided an address hint of zero and ASLR being globally enabled to get random addresses here.

Is it possible to mmap() anonymous shared memory at random addresses?


Solution

  • Using this slightly modified version of my test code above :

    void main(int argc, char *argv[])                                                                      
    {                                                                                                      
        if (argc < 2) return;                                                                              
        int iter = strtol(argv[1], NULL, 10);                                                              
        for(int i = 0; i < iter; i++) {                                                                    
            char *x = (char *)mmap(0, 1000, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);   
            printf("stack=%p mmap=%p\n", main, x);                                                         
            munmap(x, 1000);                                                                               
        }                                                                                                  
    } 
    

    And running the test for 4 iterations I get the same address:

    $ ./rndmap 3  
    stack=0x5623b6ff3830 mmap=0x7fe8a29b7000                
    stack=0x5623b6ff3830 mmap=0x7fe8a29b7000                              
    stack=0x5623b6ff3830 mmap=0x7fe8a29b7000
    

    Which was my original question - Why are the mapping not at random addresses. I answered my own question by running the test several times with one iteration (./rndmap 1), here are the results:

    stack=0x559714ce7830 mmap=0x7f6956ac9000    
    stack=0x55b74b293830 mmap=0x7faafb7c0000
    stack=0x564665b22830 mmap=0x7f56baf12000
    

    One can thus conclude that ASLR in linux, in part, is responsible for randomizing the heap base address, not the individual memory maps. Which is why the address changes every time the binary is run, and for every mmap() we get the same randomized base address.