Module Name: src
Committed By: joerg
Date: Sun Jan 6 19:44:54 UTC 2019
Modified Files:
src/libexec/ld.elf_so: map_object.c
Log Message:
When loading a non-PIE main binary, the virtual address must match.
Use MAP_TRYFIXED and verify that the result matches the expectation.
To generate a diff of this commit:
cvs rdiff -u -r1.59 -r1.60 src/libexec/ld.elf_so/map_object.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/libexec/ld.elf_so/map_object.c
diff -u src/libexec/ld.elf_so/map_object.c:1.59 src/libexec/ld.elf_so/map_object.c:1.60
--- src/libexec/ld.elf_so/map_object.c:1.59 Fri Jan 4 19:54:56 2019
+++ src/libexec/ld.elf_so/map_object.c Sun Jan 6 19:44:54 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: map_object.c,v 1.59 2019/01/04 19:54:56 joerg Exp $ */
+/* $NetBSD: map_object.c,v 1.60 2019/01/06 19:44:54 joerg Exp $ */
/*
* Copyright 1996 John D. Polstra.
@@ -34,7 +34,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: map_object.c,v 1.59 2019/01/04 19:54:56 joerg Exp $");
+__RCSID("$NetBSD: map_object.c,v 1.60 2019/01/06 19:44:54 joerg Exp $");
#endif /* not lint */
#include <errno.h>
@@ -82,7 +82,7 @@ _rtld_map_object(const char *path, int f
Elf_Addr base_vlimit;
Elf_Addr text_vlimit;
int text_flags;
- caddr_t base_addr;
+ void *base_addr;
Elf_Off data_offset;
Elf_Addr data_vaddr;
Elf_Addr data_vlimit;
@@ -339,10 +339,12 @@ _rtld_map_object(const char *path, int f
mapflags = MAP_ALIGNED(log2);
}
-#ifdef RTLD_LOADER
- base_addr = obj->isdynamic ? NULL : (caddr_t)base_vaddr;
-#else
base_addr = NULL;
+#ifdef RTLD_LOADER
+ if (!obj->isdynamic) {
+ mapflags |= MAP_TRYFIXED;
+ base_addr = (void *)(uintptr_t)base_vaddr;
+ }
#endif
mapsize = base_vlimit - base_vaddr;
mapbase = mmap(base_addr, mapsize, text_flags,
@@ -352,6 +354,12 @@ _rtld_map_object(const char *path, int f
xstrerror(errno));
goto bad;
}
+#ifdef RTLD_LOADER
+ if (!obj->isdynamic && mapbase != base_addr) {
+ _rtld_error("mmap of executable at correct address failed");
+ goto bad;
+ }
+#endif
/* Overlay the data segment onto the proper region. */
data_addr = mapbase + (data_vaddr - base_vaddr);