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
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.


-- 
H.J
From eee1f1f4f60eb1f1139ac311e787fac50accde30 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.to...@gmail.com>
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 <hjl.to...@gmail.com>
---
 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

Reply via email to