From eee1f1f4f60eb1f1139ac311e787fac50accde30 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Fri, 6 Dec 2013 12:44:41 -0800 Subject: [PATCH] binfmt_elf: fix PIE load with randomization disabled Normally, a PIE executable has zero virtual address on the first PT_LOAD segment and kernel will load such executable at random address when randomization is enabled. If randomization is disabled, kernel will load it at a fixed address. But if a PIE executable has non-zero virtual address on the first PT_LOAD segment, kernel will load such executable at the non-zero virtual address when randomization is enabled. But when randomization is disabled, kernel ignores the non-zero virtual address on the first PT_LOAD segment and loads it at the fixed address. This patch makes kernel consistent by loading PIE executable with non-zero virtual address at the non-zero virtual address, regardless if randomization is enabled or disabled. Signed-off-by: H.J. Lu --- fs/binfmt_elf.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 4c94a79..a3fd4de 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -809,8 +809,13 @@ static int load_elf_binary(struct linux_binprm *bprm) * If that is the case, retain the original non-zero * load_bias value in order to establish proper * non-randomized mappings. + * If the first PT_LOAD segment has non-zero p_vaddr, + * use the zero load_bias so that a PIE binary will be + * loaded at the specific address even if memory + * randomization is off. */ - if (current->flags & PF_RANDOMIZE) + if ((current->flags & PF_RANDOMIZE) || + (!load_addr_set && vaddr)) load_bias = 0; else load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr); -- 1.8.3.1