9

From what I understand, ASLR has 3 Modes:

  • 0 - turned off
  • 1 - randomizes stack, heap, shared libraries, vDSO, mmap memory area and text area (if built with -fPIE -pie)
  • 2 - additionally randomizes brk()-allocated memory, which comes, to my understanding, mostly from small malloc()-calls.

Why is there an extra mode especially for brk()-allocated memory (if this is really all it does) and how important is it or rather when is it important to use Mode 2 of ASLR instead of Mode 1?

cactus4
  • 13
  • 3
Mr_Mango
  • 93
  • 6
  • 1
    Linux man page http://man7.org/linux/man-pages/man2/brk.2.html has a warning to not use brk(). Therefore, brk() not being a default would justify having a separate mode for ASLR. – postoronnim Apr 08 '20 at 19:38
  • It does indeed say brk() should be avoided. Yet the [man page of malloc](http://man7.org/linux/man-pages/man3/malloc.3.html) states that it uses sbrk(), so i'd guess that it is used a lot, maybe without everybody being aware of it. – Mr_Mango Apr 09 '20 at 19:03

1 Answers1

1

There has to be a specific way of randomizing brk() as well, as there are some heap implementations other than glibc's default (ptmalloc) that might not rely on brk(), leaving direct use of brk() unprotected to predictable address space if only va_randomize_space = 1 is used.

This is also important because attackers could craft shellcodes using direct SYS_brk system calls to map memory with a predicted address space to work on.

A quick look into the Linux kernel source code suggests setting ASLR to mode 2 does only just that: randomizes the start of the dynamic memory mapping address space:

https://github.com/torvalds/linux/blob/master/fs/binfmt_elf.c#L1110-L1123

<!-- language: lang-c -->

    if ((current->flags & PF_RANDOMIZE) && (randomize_va_space > 1)) {
        /*
         * For architectures with ELF randomization, when executing
         * a loader directly (i.e. no interpreter listed in ELF
         * headers), move the brk area out of the mmap region
         * (since it grows up, and may collide early with the stack
         * growing down), and into the unused ELF_ET_DYN_BASE region.
         */
        if (IS_ENABLED(CONFIG_ARCH_HAS_ELF_RANDOMIZE) &&
            elf_ex->e_type == ET_DYN && !interpreter) {
            mm->brk = mm->start_brk = ELF_ET_DYN_BASE;
        }

        mm->brk = mm->start_brk = arch_randomize_brk(mm);
#ifdef compat_brk_randomized
        current->brk_randomized = 1;
#endif
    }

https://github.com/torvalds/linux/blob/master/mm/mmap.c#L212-L213

<!-- language: lang-c -->

    if (current->brk_randomized)
        min_brk = mm->start_brk;