diff options
| author | joerg <joerg@NetBSD.org> | 2019-01-06 19:44:54 +0000 |
|---|---|---|
| committer | joerg <joerg@NetBSD.org> | 2019-01-06 19:44:54 +0000 |
| commit | ad970ad8929ea5c87b950a234da4d635518f3e00 (patch) | |
| tree | 1cce0fc1d6285e635a702a34784e02028d59e033 /libexec | |
| parent | 55da66c964856e95c2f042b73fc1a2bad06426c8 (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.c | 20 |
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); |
