Использование ASLR для получения случайного анонимного адреса сопоставления

Рассмотрим этот код, работающий в современной системе Ubuntu 16.04 x86_64:

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);                                                                               
    }                                                                                                  
}                                                                                                      

Чей вывод выглядит так:

0x7f02ca14c000
0x7f02ca14c000
0x7f02ca14c000
0x7f02ca14c000
...

Я бы ожидал, предоставив адресную подсказку с нулевым значением, а ASLR глобально включен для получения здесь случайных адресов.

Можно ли mmap() анонимно использовать общую память по случайным адресам?


person Whome    schedule 23.04.2018    source источник
comment
Связанный: stackoverflow.com/questions /9485244/   -  person Hasturkun    schedule 24.04.2018


Ответы (1)


Используя эту слегка измененную версию моего тестового кода выше:

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);                                                                               
    }                                                                                                  
} 

И запустив тест на 4 итерации получаю один и тот же адрес:

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

Каков был мой первоначальный вопрос: почему сопоставление происходит не по случайным адресам. Я ответил на свой вопрос, запустив тест несколько раз с одной итерацией (./rndmap 1), вот результаты:

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

Таким образом, можно сделать вывод, что ASLR в Linux частично отвечает за рандомизацию базового адреса кучи, а не отдельных карт памяти. Вот почему адрес меняется каждый раз, когда запускается двоичный файл, и для каждого mmap() мы получаем один и тот же рандомизированный базовый адрес.

person Whome    schedule 24.04.2018