--- linux-3.2.12-hardened/fs/binfmt_elf.c +++ linux-3.3.1-hardened-r1/fs/binfmt_elf.c @@ -1328,11 +1328,6 @@ static int load_elf_binary(struct linux_ start_data += load_bias; end_data += load_bias; -#ifdef CONFIG_PAX_RANDMMAP - if (current->mm->pax_flags & MF_PAX_RANDMMAP) - elf_brk += PAGE_SIZE + ((pax_get_random_long() & ((1UL << 22) - 1UL)) << 4); -#endif - /* Calling set_brk effectively mmaps the pages that we need * for the bss and break sections. We must do this before * mapping in the interpreter, to make sure it doesn't wind @@ -1351,6 +1346,30 @@ static int load_elf_binary(struct linux_ */ } +#ifdef CONFIG_PAX_RANDMMAP + if (current->mm->pax_flags & MF_PAX_RANDMMAP) { + unsigned long start, size; + + current->mm->end_data = end_data = elf_brk; + start = ELF_PAGEALIGN(elf_brk); + size = PAGE_SIZE + ((pax_get_random_long() & ((1UL << 22) - 1UL)) << 4); + current->mm->start_brk = start + size; + down_write(¤t->mm->mmap_sem); + retval = -ENOMEM; + if (!find_vma_intersection(current->mm, start, start + size + PAGE_SIZE)) { + start = do_mmap(NULL, start, size, PROT_NONE, MAP_ANONYMOUS | MAP_FIXED | MAP_PRIVATE, 0); + retval = IS_ERR_VALUE(start) ? start : 0; + } + up_write(¤t->mm->mmap_sem); + if (retval == 0) + retval = set_brk(start + size, start + size + PAGE_SIZE); + if (retval < 0) { + send_sig(SIGKILL, current, 0); + goto out_free_dentry; + } + } +#endif + if (elf_interpreter) { unsigned long uninitialized_var(interp_map_addr);