Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/libexec/ld.elf_so Add support for GNU RELRO headers from Mat...
details: https://anonhg.NetBSD.org/src/rev/1c8bda07f779
branches: trunk
changeset: 345896:1c8bda07f779
user: christos <christos%NetBSD.org@localhost>
date: Tue Jun 14 13:06:41 2016 +0000
description:
Add support for GNU RELRO headers from Matthias Weckbecker.
diffstat:
libexec/ld.elf_so/Makefile | 3 ++-
libexec/ld.elf_so/headers.c | 15 +++++++++++++--
libexec/ld.elf_so/map_object.c | 24 ++++++++++++++++++++++--
libexec/ld.elf_so/reloc.c | 15 +++++++++++++--
libexec/ld.elf_so/rtld.h | 8 +++++++-
5 files changed, 57 insertions(+), 8 deletions(-)
diffs (177 lines):
diff -r 9e3ab2bad130 -r 1c8bda07f779 libexec/ld.elf_so/Makefile
--- a/libexec/ld.elf_so/Makefile Tue Jun 14 09:07:22 2016 +0000
+++ b/libexec/ld.elf_so/Makefile Tue Jun 14 13:06:41 2016 +0000
@@ -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 @@
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
diff -r 9e3ab2bad130 -r 1c8bda07f779 libexec/ld.elf_so/headers.c
--- a/libexec/ld.elf_so/headers.c Tue Jun 14 09:07:22 2016 +0000
+++ b/libexec/ld.elf_so/headers.c Tue Jun 14 13:06:41 2016 +0000
@@ -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 @@
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;
diff -r 9e3ab2bad130 -r 1c8bda07f779 libexec/ld.elf_so/map_object.c
--- a/libexec/ld.elf_so/map_object.c Tue Jun 14 09:07:22 2016 +0000
+++ b/libexec/ld.elf_so/map_object.c Tue Jun 14 13:06:41 2016 +0000
@@ -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 @@
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 @@
#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 @@
(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 @@
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;
diff -r 9e3ab2bad130 -r 1c8bda07f779 libexec/ld.elf_so/reloc.c
--- a/libexec/ld.elf_so/reloc.c Tue Jun 14 09:07:22 2016 +0000
+++ b/libexec/ld.elf_so/reloc.c Tue Jun 14 13:06:41 2016 +0000
@@ -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 @@
/* 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;
diff -r 9e3ab2bad130 -r 1c8bda07f779 libexec/ld.elf_so/rtld.h
--- a/libexec/ld.elf_so/rtld.h Tue Jun 14 09:07:22 2016 +0000
+++ b/libexec/ld.elf_so/rtld.h Tue Jun 14 13:06:41 2016 +0000
@@ -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 @@
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 */
Home |
Main Index |
Thread Index |
Old Index