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;