Address Space Layout Randomization( ALSR ) and mmap

社会主义新天地 提交于 2020-01-02 04:10:10

问题


I expect that due to Address Space Layout Randomization (ALSR) a process forked from another process will have different addresses returned when calling mmap. But as I found out, that was not the case. I made the following test program for that purpose. All the addresses returned by malloc are exactly the same for the parent and the child. Note that the malloc for cl1, cl2, pl1, pl2 internally uses mmap because they are large blocks.

So, my question is, why mmap is not returning different addresses even in the presence of ALSR. Maybe its because the seed for randomization here is the same for the original and forked process. Or is there any other reason?

int main()
{
  pid = fork();

  if (pid == 0)                // child
  {
    void * c1 = malloc( 4096 );
    void * c2 = malloc( 4096 );

    void * cl1 = malloc( (long)512e3 ); // internally uses mmap
    void * cl2 = malloc( (long)512e3 ); // internally uses mmap

    printf( "c1 = %p, c2 = %p, cl1 = %p, cl2 = %p!\n", c1, c2, cl1, cl2 );
  }
  else
  {
    void * p1 = malloc( 4096 );
    void * p2 = malloc( 4096 );

    void * pl1 = malloc( (long)512e3 ); // internally uses mmap
    void * pl2 = malloc( (long)512e3 ); // internally uses mmap

    printf( "p1 = %p, p2 = %p, pl1 = %p, pl2 = %p!\n", p1, p2, pl1, pl2 );
  }

  return 0;
}

回答1:


ASLR mainly randomizes the distance from the top of user-space address space down to the stack, and the distance from the bottom of stack-reserved space to the first mmap (which is probably the mapping of the dynamic linker). Any further randomization would have serious fragmenting effects on the virtual memory space, and thus would break programs that need to make large mmaps (e.g. a 1-2 GB mapping on a 32-bit machine).

I have seen some Linux distros ship patched kernels that perform much more randomization on the addresses returned by mmap. Some of them even give you mappings overlapping with the space reserved for the stack to expand into, and then when the stack grows it clobbers your mapping (resulting a huge gaping security hole, much bigger than anything non-random address assignments could have caused). Stay away from these hacks.




回答2:


You can't re-randomize the child's address space - all pointers would have to be touched up, and that's technically impossible (the runtime environment doesn't even know what part of your data is pointers).

So the result you are seeing is expected, the child from the fork has an exact copy of its parent address space at the time of forking, including its virtual address layout.

You'll need an exec* call to get a new address-space layout.

$ cat t.c
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char **argv)
{
    printf("%p\n", malloc((long)512e3));
    if ((argc > 1) && fork()) {
        execl("./a.out", "./a.out", NULL);
    }
    return 0;
}
$ gcc -Wall t.c
$ ./a.out 1
0x7f5bf6962010
0x7f3483044010
$ ./a.out 1
0x7f1ce7462010
0x7feb2adc2010

(And make sure /proc/sys/kernel/randomize_va_space is not zero too.)



来源:https://stackoverflow.com/questions/9485244/address-space-layout-randomization-alsr-and-mmap

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!