Module Name:    src
Committed By:   christos
Date:           Sun Dec 30 01:48:37 UTC 2018

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

Log Message:
binutils 2.31.1 can put copy relocations in the relro segment. Delay
protecting the relro segment for the main object until copy relocations
are done.


To generate a diff of this commit:
cvs rdiff -u -r1.113 -r1.114 src/libexec/ld.elf_so/reloc.c
cvs rdiff -u -r1.194 -r1.195 src/libexec/ld.elf_so/rtld.c
cvs rdiff -u -r1.135 -r1.136 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/reloc.c
diff -u src/libexec/ld.elf_so/reloc.c:1.113 src/libexec/ld.elf_so/reloc.c:1.114
--- src/libexec/ld.elf_so/reloc.c:1.113	Wed Oct 17 19:36:58 2018
+++ src/libexec/ld.elf_so/reloc.c	Sat Dec 29 20:48:37 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: reloc.c,v 1.113 2018/10/17 23:36:58 joerg Exp $	 */
+/*	$NetBSD: reloc.c,v 1.114 2018/12/30 01:48:37 christos Exp $	 */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -39,7 +39,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: reloc.c,v 1.113 2018/10/17 23:36:58 joerg Exp $");
+__RCSID("$NetBSD: reloc.c,v 1.114 2018/12/30 01:48:37 christos Exp $");
 #endif /* not lint */
 
 #include <err.h>
@@ -102,10 +102,10 @@ _rtld_do_copy_relocation(const Obj_Entry
 		return (-1);
 	}
 	srcaddr = (const void *)(srcobj->relocbase + srcsym->st_value);
-	(void)memcpy(dstaddr, srcaddr, size);
 	rdbg(("COPY %s %s %s --> src=%p dst=%p size %ld",
 	    dstobj->path, srcobj->path, name, srcaddr,
 	    (void *)dstaddr, (long)size));
+	(void)memcpy(dstaddr, srcaddr, size);
 	return (0);
 }
 #endif /* RTLD_INHIBIT_COPY_RELOCS */
@@ -149,6 +149,10 @@ _rtld_do_copy_relocations(const Obj_Entr
 			}
 		}
 	}
+#ifdef GNU_RELRO
+	if (_rtld_relro(dstobj, true) == -1)
+		return -1;
+#endif
 #endif /* RTLD_INHIBIT_COPY_RELOCS */
 
 	return (0);
@@ -225,18 +229,10 @@ _rtld_relocate_objects(Obj_Entry *first,
 		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;
-			}
-		}
+		if (_rtld_relro(obj, false) == -1)
+			return -1;
 #endif
 	}
-
 	return 0;
 }
 

Index: src/libexec/ld.elf_so/rtld.c
diff -u src/libexec/ld.elf_so/rtld.c:1.194 src/libexec/ld.elf_so/rtld.c:1.195
--- src/libexec/ld.elf_so/rtld.c:1.194	Thu Dec 27 13:57:43 2018
+++ src/libexec/ld.elf_so/rtld.c	Sat Dec 29 20:48:37 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: rtld.c,v 1.194 2018/12/27 18:57:43 christos Exp $	 */
+/*	$NetBSD: rtld.c,v 1.195 2018/12/30 01:48:37 christos Exp $	 */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -40,7 +40,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: rtld.c,v 1.194 2018/12/27 18:57:43 christos Exp $");
+__RCSID("$NetBSD: rtld.c,v 1.195 2018/12/30 01:48:37 christos Exp $");
 #endif /* not lint */
 
 #include <sys/param.h>
@@ -1746,3 +1746,22 @@ _rtld_exclusive_exit(sigset_t *mask)
 
 	sigprocmask(SIG_SETMASK, mask, NULL);
 }
+
+int
+_rtld_relro(const Obj_Entry *obj, bool wantmain)
+{
+#ifdef GNU_RELRO
+	if (obj->relro_size == 0)
+		return 0;
+	if (wantmain != (obj ==_rtld_objmain))
+		return 0;
+
+	dbg(("RELRO %s %p %lx\n", obj->path, obj->relro_page, obj->relro_size));
+	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.135 src/libexec/ld.elf_so/rtld.h:1.136
--- src/libexec/ld.elf_so/rtld.h:1.135	Mon Nov 26 12:40:26 2018
+++ src/libexec/ld.elf_so/rtld.h	Sat Dec 29 20:48:37 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: rtld.h,v 1.135 2018/11/26 17:40:26 joerg Exp $	 */
+/*	$NetBSD: rtld.h,v 1.136 2018/12/30 01:48:37 christos Exp $	 */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -372,6 +372,8 @@ void _rtld_shared_exit(void);
 void _rtld_exclusive_enter(sigset_t *);
 void _rtld_exclusive_exit(sigset_t *);
 
+int _rtld_relro(const Obj_Entry *, bool);
+
 /* expand.c */
 size_t _rtld_expand_path(char *, size_t, const char *, const char *,\
     const char *);

Reply via email to