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);

Reply via email to