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/588e9a6e913d
branches:  trunk
changeset: 816038:588e9a6e913d
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 ca38396bbdfa -r 588e9a6e913d 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 ca38396bbdfa -r 588e9a6e913d 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 ca38396bbdfa -r 588e9a6e913d 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 ca38396bbdfa -r 588e9a6e913d 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 ca38396bbdfa -r 588e9a6e913d 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