Patchwork [RFC] elfload: load PIE executables to right address

login
register
mail settings
Submitter Timo Teräs
Date July 4, 2013, 1:01 p.m.
Message ID <1372942883-26110-1-git-send-email-timo.teras@iki.fi>
Download mbox | patch
Permalink /patch/256891/
State New
Headers show

Comments

Timo Teräs - July 4, 2013, 1:01 p.m.
PIE images are ET_DYN images. Check first for pinterp_name to make
sure the main executable always is loaded to correct place.

See below for current behaviour of PIE executables:

Reserved 0x7f000000 bytes of guest address space
host mmap_min_addr=0x1000
guest_base  0x7f7cb41d5000
start    end      size     prot
0037f400-003fe400 0007f000 r-x
003fe400-003ff400 00001000 ---
003ff400-003fe400 fffff000 rw-
003fe400-003ff400 00001000 ---
003ff400-003ffc00 00000800 rw-
003ffc00-003fec00 fffff000 r-x
003fec00-003ffc00 00001000 ---
003ffc00-0007f000 ffc7f400 rw-
start_brk   0x00000000
end_code    0x7eff7ac0
start_code  0x7eff7000
start_data  0x7efffac0
end_data    0x7efffc18
start_stack 0x7eff6dc8
brk         0x7efffc34
entry       0x7e799b30
00000000-00005000 ---p 00000000 00:00 0
00005000-00015000 rw-p 00000000 00:00 0
00015000-7e77d000 ---p 00000000 00:00 0
7e77d000-7e7ec000 r-xp 00000000 68:03 14326298          /lib/libc.so
7e7ec000-7e7f3000 ---p 00000000 00:00 0
7e7f3000-7e7f4000 rw-p 0006e000 68:03 14326298          /lib/libc.so
7e7f4000-7e7f6000 rw-p 00000000 00:00 0
7e7f6000-7e7f7000 ---p 00000000 00:00 0
7e7f7000-7eff7000 rw-p 00000000 00:00 0
7eff7000-7eff8000 r-xp 00000000 68:03 9731305          /usr/bin/brk
7eff8000-7efff000 ---p 00000000 00:00 0
7e7f7000-7eff7000 rw-p 00000000 00:00 0          [stack]

Showing how the main binary got loaded to wrong place.

Signed-off-by: Timo Teräs <timo.teras@iki.fi>
---
I assume pinterp_name is only ever set for the main executable.
Quick grep would indicate that this is indeed the case.

 linux-user/elfload.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)
Timo Teräs - July 4, 2013, 6:40 p.m.
On Thu,  4 Jul 2013 16:01:23 +0300
Timo Teräs <timo.teras@iki.fi> wrote:

> PIE images are ET_DYN images. Check first for pinterp_name to make
> sure the main executable always is loaded to correct place.
> 
> See below for current behaviour of PIE executables:
> 
> Reserved 0x7f000000 bytes of guest address space
> host mmap_min_addr=0x1000
> guest_base  0x7f7cb41d5000
> start    end      size     prot
> 0037f400-003fe400 0007f000 r-x
> 003fe400-003ff400 00001000 ---
> 003ff400-003fe400 fffff000 rw-
> 003fe400-003ff400 00001000 ---
> 003ff400-003ffc00 00000800 rw-
> 003ffc00-003fec00 fffff000 r-x
> 003fec00-003ffc00 00001000 ---
> 003ffc00-0007f000 ffc7f400 rw-
> start_brk   0x00000000
> end_code    0x7eff7ac0
> start_code  0x7eff7000
> start_data  0x7efffac0
> end_data    0x7efffc18
> start_stack 0x7eff6dc8
> brk         0x7efffc34
> entry       0x7e799b30
> 00000000-00005000 ---p 00000000 00:00 0
> 00005000-00015000 rw-p 00000000 00:00 0
> 00015000-7e77d000 ---p 00000000 00:00 0
> 7e77d000-7e7ec000 r-xp 00000000 68:03 14326298          /lib/libc.so
> 7e7ec000-7e7f3000 ---p 00000000 00:00 0
> 7e7f3000-7e7f4000 rw-p 0006e000 68:03 14326298          /lib/libc.so
> 7e7f4000-7e7f6000 rw-p 00000000 00:00 0
> 7e7f6000-7e7f7000 ---p 00000000 00:00 0
> 7e7f7000-7eff7000 rw-p 00000000 00:00 0
> 7eff7000-7eff8000 r-xp 00000000 68:03 9731305          /usr/bin/brk
> 7eff8000-7efff000 ---p 00000000 00:00 0
> 7e7f7000-7eff7000 rw-p 00000000 00:00 0          [stack]
> 
> Showing how the main binary got loaded to wrong place.

Forgot to mention. Due to the above, the brk is set wrong, and the
application will be unable to allocate any memory. Making them
practically unusable.

I've done quick testing that with this patch applied, the
PIE executables will have working brk().

- Timo

Patch

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index ddef23e..d6e00cd 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -1660,7 +1660,12 @@  static void load_elf_image(const char *image_name, int image_fd,
     }
 
     load_addr = loaddr;
-    if (ehdr->e_type == ET_DYN) {
+    if (pinterp_name != NULL) {
+        /* This is the main executable.  Make sure that the low
+           address does not conflict with MMAP_MIN_ADDR or the
+           QEMU application itself.  */
+        probe_guest_base(image_name, loaddr, hiaddr);
+    } else if (ehdr->e_type == ET_DYN) {
         /* The image indicates that it can be loaded anywhere.  Find a
            location that can hold the memory space required.  If the
            image is pre-linked, LOADDR will be non-zero.  Since we do
@@ -1672,11 +1677,6 @@  static void load_elf_image(const char *image_name, int image_fd,
         if (load_addr == -1) {
             goto exit_perror;
         }
-    } else if (pinterp_name != NULL) {
-        /* This is the main executable.  Make sure that the low
-           address does not conflict with MMAP_MIN_ADDR or the
-           QEMU application itself.  */
-        probe_guest_base(image_name, loaddr, hiaddr);
     }
     load_bias = load_addr - loaddr;