From 21f973f87f480e3d24f1cb6c22b71253d25a3ea1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Tue, 1 Oct 2013 13:46:04 +0300 Subject: [PATCH 3.10-grsec] fs/binfmt_elf: fix memory map for PIE applications MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit arch/*/include/asm/elf.h comments say: ELF_ET_DYN_BASE is the location that an ET_DYN program is loaded if exec'ed. Typical use of this is to invoke "./ld.so someprog" to test out a new version of the loader. We need to make sure that it is out of the way of the program that it will "exec", and that there is sufficient room for the brk. In case we have main application linked as PIE, this can cause problems as the main program itself is being loaded to this alternate address. And this allows limited heap size. While this is inevitable when exec'ing the interpreter directly, we should do better for PIE applications. This fixes the loader to detect PIE application by checking if elf_interpreter is requested. This images are loaded to beginning of the address space instead of the specially crafted place for elf interpreter. This allows full heap address space for PIE applications and fixes random "out of memory" errors. Signed-off-by: Timo Teräs --- fs/binfmt_elf.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 6f036ed..06419af 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -1217,21 +1217,19 @@ static int load_elf_binary(struct linux_binprm *bprm) * default mmap base, as well as whatever program they * might try to exec. This is because the brk will * follow the loader, and is not movable. */ + if (elf_interpreter) + load_bias = 0x00400000UL; + else + load_bias = ELF_ET_DYN_BASE; #ifdef CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE /* Memory randomization might have been switched off * in runtime via sysctl or explicit setting of * personality flags. - * If that is the case, retain the original non-zero - * load_bias value in order to establish proper - * non-randomized mappings. */ if (current->flags & PF_RANDOMIZE) - load_bias = 0; - else - load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr); -#else - load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr); + load_bias = (get_random_int() & STACK_RND_MASK) << PAGE_SHIFT; #endif + load_bias = ELF_PAGESTART(load_bias - vaddr); #ifdef CONFIG_PAX_RANDMMAP /* PaX: randomize base address at the default exe base if requested */ -- 1.8.4