Module Name:    src
Committed By:   christos
Date:           Tue Jun 14 13:06:41 UTC 2016

Modified Files:
        src/libexec/ld.elf_so: Makefile headers.c map_object.c reloc.c rtld.h

Log Message:
Add support for GNU RELRO headers from Matthias Weckbecker.


To generate a diff of this commit:
cvs rdiff -u -r1.130 -r1.131 src/libexec/ld.elf_so/Makefile
cvs rdiff -u -r1.60 -r1.61 src/libexec/ld.elf_so/headers.c
cvs rdiff -u -r1.53 -r1.54 src/libexec/ld.elf_so/map_object.c
cvs rdiff -u -r1.108 -r1.109 src/libexec/ld.elf_so/reloc.c
cvs rdiff -u -r1.124 -r1.125 src/libexec/ld.elf_so/rtld.h

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/Makefile
diff -u src/libexec/ld.elf_so/Makefile:1.130 src/libexec/ld.elf_so/Makefile:1.131
--- src/libexec/ld.elf_so/Makefile:1.130	Sat Jan 23 16:22:47 2016
+++ src/libexec/ld.elf_so/Makefile	Tue Jun 14 09:06:41 2016
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile,v 1.130 2016/01/23 21:22:47 christos Exp $
+#	$NetBSD: Makefile,v 1.131 2016/06/14 13:06:41 christos Exp $
 #
 # NOTE: when changing ld.so, ensure that ldd still compiles.
 #
@@ -93,6 +93,7 @@ BINDIR=		${SHLINKINSTALLDIR}
 CPPFLAGS+=	-DLIBDIR=\"${LIBDIR}\" -D_PATH_RTLD=\"${BINDIR}/${PROG}\"
 CPPFLAGS+=	-I${.CURDIR} -I. -D_KERNTYPES
 CPPFLAGS+=	-DRTLD_LOADER
+CPPFLAGS+=	-DGNU_RELRO
 CPPFLAGS+=	-D_RTLD_SOURCE
 CPPFLAGS+=	-DCOMBRELOC
 #CPPFLAGS+=	-DDEBUG

Index: src/libexec/ld.elf_so/headers.c
diff -u src/libexec/ld.elf_so/headers.c:1.60 src/libexec/ld.elf_so/headers.c:1.61
--- src/libexec/ld.elf_so/headers.c:1.60	Sun May 22 15:28:39 2016
+++ src/libexec/ld.elf_so/headers.c	Tue Jun 14 09:06:41 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: headers.c,v 1.60 2016/05/22 19:28:39 joerg Exp $	 */
+/*	$NetBSD: headers.c,v 1.61 2016/06/14 13:06:41 christos Exp $	 */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -40,7 +40,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: headers.c,v 1.60 2016/05/22 19:28:39 joerg Exp $");
+__RCSID("$NetBSD: headers.c,v 1.61 2016/06/14 13:06:41 christos Exp $");
 #endif /* not lint */
 
 #include <err.h>
@@ -432,6 +432,17 @@ _rtld_digest_phdr(const Elf_Phdr *phdr, 
 			     ph->p_memsz));
 			break;
 
+#ifdef GNU_RELRO
+		case PT_GNU_RELRO:
+			obj->relro_page = obj->relocbase
+			    + round_down(ph->p_vaddr);
+			obj->relro_size = round_up(ph->p_memsz);
+			dbg(("headers: %s %p phsize %" PRImemsz,
+			    "PT_GNU_RELRO", (void *)(uintptr_t)vaddr,
+			     ph->p_memsz));
+			break;
+#endif
+
 #if defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II)
 		case PT_TLS:
 			obj->tlsindex = 1;

Index: src/libexec/ld.elf_so/map_object.c
diff -u src/libexec/ld.elf_so/map_object.c:1.53 src/libexec/ld.elf_so/map_object.c:1.54
--- src/libexec/ld.elf_so/map_object.c:1.53	Thu Oct 30 03:53:41 2014
+++ src/libexec/ld.elf_so/map_object.c	Tue Jun 14 09:06:41 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: map_object.c,v 1.53 2014/10/30 07:53:41 martin Exp $	 */
+/*	$NetBSD: map_object.c,v 1.54 2016/06/14 13:06:41 christos Exp $	 */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -34,7 +34,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: map_object.c,v 1.53 2014/10/30 07:53:41 martin Exp $");
+__RCSID("$NetBSD: map_object.c,v 1.54 2016/06/14 13:06:41 christos Exp $");
 #endif /* not lint */
 
 #include <errno.h>
@@ -103,6 +103,10 @@ _rtld_map_object(const char *path, int f
 	caddr_t		 clear_addr;
 	size_t		 nclear;
 #endif
+#ifdef GNU_RELRO
+	Elf_Addr 	 relro_page;
+	size_t		 relro_size;
+#endif
 
 	if (sb != NULL && sb->st_size < (off_t)sizeof (Elf_Ehdr)) {
 		_rtld_error("%s: not ELF file (too short)", path);
@@ -173,6 +177,10 @@ _rtld_map_object(const char *path, int f
 #endif
 	phsize = ehdr->e_phnum * sizeof(phdr[0]);
 	obj->phdr = NULL;
+#ifdef GNU_RELRO
+	relro_page = 0;
+	relro_size = 0;
+#endif
 	phdr_vaddr = EA_UNDEF;
 	phdr_memsz = 0;
 	phlimit = phdr + ehdr->e_phnum;
@@ -200,6 +208,13 @@ _rtld_map_object(const char *path, int f
 			    (void *)(uintptr_t)phdr->p_vaddr, phdr->p_memsz));
 			break;
 
+#ifdef GNU_RELRO
+		case PT_GNU_RELRO:
+			relro_page = phdr->p_vaddr;
+			relro_size = phdr->p_memsz;
+			break;
+#endif
+
 		case PT_DYNAMIC:
 			obj->dynamic = (void *)(uintptr_t)phdr->p_vaddr;
 			dbg(("%s: %s %p phsize %" PRImemsz, obj->path, "PT_DYNAMIC",
@@ -267,6 +282,11 @@ _rtld_map_object(const char *path, int f
 	obj->vaddrbase = base_vaddr;
 	obj->isdynamic = ehdr->e_type == ET_DYN;
 
+#ifdef GNU_RELRO
+	obj->relro_page = obj->relocbase + round_down(relro_page);
+	obj->relro_size = round_up(relro_size);
+#endif
+
 #if defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II)
 	if (phtls != NULL) {
 		++_rtld_tls_dtv_generation;

Index: src/libexec/ld.elf_so/reloc.c
diff -u src/libexec/ld.elf_so/reloc.c:1.108 src/libexec/ld.elf_so/reloc.c:1.109
--- src/libexec/ld.elf_so/reloc.c:1.108	Tue Apr 12 15:10:48 2016
+++ src/libexec/ld.elf_so/reloc.c	Tue Jun 14 09:06:41 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: reloc.c,v 1.108 2016/04/12 19:10:48 christos Exp $	 */
+/*	$NetBSD: reloc.c,v 1.109 2016/06/14 13:06:41 christos Exp $	 */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -39,7 +39,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: reloc.c,v 1.108 2016/04/12 19:10:48 christos Exp $");
+__RCSID("$NetBSD: reloc.c,v 1.109 2016/06/14 13:06:41 christos Exp $");
 #endif /* not lint */
 
 #include <err.h>
@@ -223,6 +223,17 @@ _rtld_relocate_objects(Obj_Entry *first,
 		/* Set the special PLTGOT entries. */
 		if (obj->pltgot != NULL)
 			_rtld_setup_pltgot(obj);
+#ifdef GNU_RELRO
+		if (obj->relro_size > 0) {
+			if (mprotect(obj->relro_page, obj->relro_size,
+			    PROT_READ) == -1) {
+				_rtld_error("%s: Cannot enforce relro "
+				    "protection: %s", obj->path,
+				    xstrerror(errno));
+				return -1;
+			}
+		}
+#endif
 	}
 
 	return 0;

Index: src/libexec/ld.elf_so/rtld.h
diff -u src/libexec/ld.elf_so/rtld.h:1.124 src/libexec/ld.elf_so/rtld.h:1.125
--- src/libexec/ld.elf_so/rtld.h:1.124	Fri Sep 19 13:43:33 2014
+++ src/libexec/ld.elf_so/rtld.h	Tue Jun 14 09:06:41 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: rtld.h,v 1.124 2014/09/19 17:43:33 matt Exp $	 */
+/*	$NetBSD: rtld.h,v 1.125 2016/06/14 13:06:41 christos Exp $	 */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -276,6 +276,12 @@ typedef struct Struct_Obj_Entry {
 	size_t		tlsalign;	/* Needed alignment for static TLS */
 #endif
 
+#ifdef GNU_RELRO
+	/* relocation readonly */
+	void		*relro_page;
+	size_t		relro_size;
+#endif
+
 	/* symbol versioning */
 	const Elf_Verneed *verneed;	/* Required versions. */
 	Elf_Word	verneednum;	/* Number of entries in verneed table */

Reply via email to