summaryrefslogtreecommitdiff
path: root/libexec
diff options
context:
space:
mode:
authorjoerg <joerg@NetBSD.org>2019-01-06 19:44:54 +0000
committerjoerg <joerg@NetBSD.org>2019-01-06 19:44:54 +0000
commitad970ad8929ea5c87b950a234da4d635518f3e00 (patch)
tree1cce0fc1d6285e635a702a34784e02028d59e033 /libexec
parent55da66c964856e95c2f042b73fc1a2bad06426c8 (diff)
When loading a non-PIE main binary, the virtual address must match.
Use MAP_TRYFIXED and verify that the result matches the expectation.
Diffstat (limited to 'libexec')
-rw-r--r--libexec/ld.elf_so/map_object.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/libexec/ld.elf_so/map_object.c b/libexec/ld.elf_so/map_object.c
index b878bfaa0fa..14afb4a6c92 100644
--- a/libexec/ld.elf_so/map_object.c
+++ b/libexec/ld.elf_so/map_object.c
@@ -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 fd, const struct stat *sb)
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 fd, const struct stat *sb)
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 fd, const struct stat *sb)
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);