The diff below (partly by guenther@) removes ld.so's dependency on the
__got_{start,end} symbols by looking at PT_GNU_RELRO instead.  On some
platforms (hppa and perhaps a few others) this leads to even less
writable pages.  However, we're not sure if this will work correctly
on landisk.  So if somebody with a fairly up-to-date landisk could
give this a spin for us, it would be highly appreciated.


Index: libexec/ld.so/boot.c
===================================================================
RCS file: /cvs/src/libexec/ld.so/boot.c,v
retrieving revision 1.14
diff -u -p -r1.14 boot.c
--- libexec/ld.so/boot.c        13 Aug 2016 20:57:04 -0000      1.14
+++ libexec/ld.so/boot.c        2 Jan 2017 15:55:52 -0000
@@ -87,6 +87,8 @@ _dl_boot_bind(const long sp, long *dl_da
        long            loff;
        Elf_Addr        i;
        RELOC_TYPE      *rp;
+       Elf_Ehdr        *ehdp;
+       Elf_Phdr        *phdp;
 
        /*
         * Scan argument and environment vectors. Find dynamic
@@ -189,4 +191,30 @@ _dl_boot_bind(const long sp, long *dl_da
         * we have been fully relocated here, so most things no longer
         * need the loff adjustment
         */
+
+       /*
+        * No further changes to the PLT and/or GOT are needed so make
+        * them read-only.
+        */
+
+       /* do any RWX -> RX fixups for executable PLTs and apply GNU_RELRO */
+       ehdp = (Elf_Ehdr *)loff;
+       phdp = (Elf_Phdr *)(loff + ehdp->e_phoff);
+       for (i = 0; i < dl_data[AUX_phnum]; i++, phdp++) {
+               switch (phdp->p_type) {
+#if defined(__alpha__) || defined(__hppa__) || defined(__powerpc__) || \
+    defined(__sparc64__)
+               case PT_LOAD:
+                       if ((phdp->p_flags & (PF_X | PF_W)) != (PF_X | PF_W))
+                               break;
+                       _dl_mprotect((void *)(phdp->p_vaddr + loff),
+                           phdp->p_memsz, PROT_READ);
+                       break;
+#endif
+               case PT_GNU_RELRO:
+                       _dl_mprotect((void *)(phdp->p_vaddr + loff),
+                           phdp->p_memsz, PROT_READ);
+                       break;
+               }
+       }
 }
Index: libexec/ld.so/loader.c
===================================================================
RCS file: /cvs/src/libexec/ld.so/loader.c,v
retrieving revision 1.167
diff -u -p -r1.167 loader.c
--- libexec/ld.so/loader.c      28 Aug 2016 04:33:17 -0000      1.167
+++ libexec/ld.so/loader.c      2 Jan 2017 15:55:52 -0000
@@ -413,25 +413,6 @@ _dl_boot(const char **argv, char **envp,
 #define ROUND_PG(x) (((x) + align) & ~(align))
 #define TRUNC_PG(x) ((x) & ~(align))
 
-       /*
-        * now that GOT and PLT have been relocated, and we know
-        * page size, protect them from modification
-        */
-#ifndef  RTLD_NO_WXORX
-       {
-               extern char *__got_start;
-               extern char *__got_end;
-
-               if (&__got_start != &__got_end) {
-                       _dl_mprotect((void *)ELF_TRUNC((long)&__got_start,
-                           _dl_pagesz),
-                           ELF_ROUND((long)&__got_end,_dl_pagesz) -
-                           ELF_TRUNC((long)&__got_start, _dl_pagesz),
-                           GOT_PERMS);
-               }
-       }
-#endif
-
        _dl_setup_env(argv[0], envp);
 
        DL_DEB(("rtld loading: '%s'\n", __progname));
Index: libexec/ld.so/alpha/archdep.h
===================================================================
RCS file: /cvs/src/libexec/ld.so/alpha/archdep.h,v
retrieving revision 1.17
diff -u -p -r1.17 archdep.h
--- libexec/ld.so/alpha/archdep.h       6 Dec 2015 23:36:12 -0000       1.17
+++ libexec/ld.so/alpha/archdep.h       2 Jan 2017 15:55:52 -0000
@@ -65,6 +65,4 @@ RELOC_DYN(Elf64_Rela *r, const Elf64_Sym
 
 #define RELOC_GOT(obj, offs)
 
-#define GOT_PERMS PROT_READ
-
 #endif /* _ALPHA_ARCHDEP_H_ */
Index: libexec/ld.so/amd64/archdep.h
===================================================================
RCS file: /cvs/src/libexec/ld.so/amd64/archdep.h,v
retrieving revision 1.8
diff -u -p -r1.8 archdep.h
--- libexec/ld.so/amd64/archdep.h       18 May 2016 20:40:20 -0000      1.8
+++ libexec/ld.so/amd64/archdep.h       2 Jan 2017 15:55:52 -0000
@@ -68,6 +68,4 @@ RELOC_DYN(Elf64_Rela *r, const Elf64_Sym
 
 #define RELOC_GOT(obj, offs)
 
-#define GOT_PERMS PROT_READ
-
 #endif /* _X86_64_ARCHDEP_H_ */
Index: libexec/ld.so/arm/archdep.h
===================================================================
RCS file: /cvs/src/libexec/ld.so/arm/archdep.h,v
retrieving revision 1.8
diff -u -p -r1.8 archdep.h
--- libexec/ld.so/arm/archdep.h 8 Sep 2016 18:56:58 -0000       1.8
+++ libexec/ld.so/arm/archdep.h 2 Jan 2017 15:55:52 -0000
@@ -73,6 +73,4 @@ RELOC_DYN(Elf_Rel *r, const Elf_Sym *s, 
 
 #define RELOC_GOT(obj, offs)
 
-#define GOT_PERMS (PROT_READ|PROT_EXEC)
-
 #endif /* _ARM_ARCHDEP_H_ */
Index: libexec/ld.so/hppa/archdep.h
===================================================================
RCS file: /cvs/src/libexec/ld.so/hppa/archdep.h,v
retrieving revision 1.11
diff -u -p -r1.11 archdep.h
--- libexec/ld.so/hppa/archdep.h        18 May 2016 20:40:20 -0000      1.11
+++ libexec/ld.so/hppa/archdep.h        2 Jan 2017 15:55:52 -0000
@@ -85,8 +85,6 @@ RELOC_DYN(Elf_RelA *r, const Elf_Sym *s,
 
 #define RELOC_GOT(obj, offs)
 
-#define GOT_PERMS PROT_READ
-
 void _hppa_dl_dtors(void);
 Elf_Addr _dl_md_plabel(Elf_Addr, Elf_Addr *);
 
Index: libexec/ld.so/hppa/rtld_machine.c
===================================================================
RCS file: /cvs/src/libexec/ld.so/hppa/rtld_machine.c,v
retrieving revision 1.34
diff -u -p -r1.34 rtld_machine.c
--- libexec/ld.so/hppa/rtld_machine.c   27 Aug 2016 22:52:21 -0000      1.34
+++ libexec/ld.so/hppa/rtld_machine.c   2 Jan 2017 15:55:52 -0000
@@ -430,7 +430,7 @@ _dl_md_reloc_got(elf_object_t *object, i
 
        /* mprotect the GOT */
        _dl_protect_segment(object, 0, "__got_start", "__got_end",
-           GOT_PERMS|PROT_EXEC);
+           PROT_READ|PROT_EXEC);
 
        return (fails);
 }
Index: libexec/ld.so/i386/archdep.h
===================================================================
RCS file: /cvs/src/libexec/ld.so/i386/archdep.h,v
retrieving revision 1.15
diff -u -p -r1.15 archdep.h
--- libexec/ld.so/i386/archdep.h        18 May 2016 20:40:20 -0000      1.15
+++ libexec/ld.so/i386/archdep.h        2 Jan 2017 15:55:52 -0000
@@ -77,6 +77,4 @@ RELOC_DYN(Elf32_Rel *r, const Elf32_Sym 
 
 #define RELOC_GOT(obj, offs)
 
-#define GOT_PERMS PROT_READ
-
 #endif /* _I386_ARCHDEP_H_ */
Index: libexec/ld.so/m88k/archdep.h
===================================================================
RCS file: /cvs/src/libexec/ld.so/m88k/archdep.h,v
retrieving revision 1.2
diff -u -p -r1.2 archdep.h
--- libexec/ld.so/m88k/archdep.h        6 Dec 2015 23:36:12 -0000       1.2
+++ libexec/ld.so/m88k/archdep.h        2 Jan 2017 15:55:52 -0000
@@ -62,6 +62,4 @@ RELOC_DYN(Elf32_Rela *r, const Elf32_Sym
 
 #define RELOC_GOT(obj, offs)   do { } while (0)
 
-#define GOT_PERMS              PROT_READ
-
 #endif /* _M88K_ARCHDEP_H_ */
Index: libexec/ld.so/mips64/archdep.h
===================================================================
RCS file: /cvs/src/libexec/ld.so/mips64/archdep.h,v
retrieving revision 1.10
diff -u -p -r1.10 archdep.h
--- libexec/ld.so/mips64/archdep.h      6 Dec 2015 23:36:12 -0000       1.10
+++ libexec/ld.so/mips64/archdep.h      2 Jan 2017 15:55:52 -0000
@@ -90,6 +90,4 @@ do {                                                          
        \
        }                                                               \
 } while (0)
 
-#define GOT_PERMS PROT_READ
-
 #endif /* _MIPS_ARCHDEP_H_ */
Index: libexec/ld.so/powerpc/archdep.h
===================================================================
RCS file: /cvs/src/libexec/ld.so/powerpc/archdep.h,v
retrieving revision 1.18
diff -u -p -r1.18 archdep.h
--- libexec/ld.so/powerpc/archdep.h     6 Dec 2015 23:36:12 -0000       1.18
+++ libexec/ld.so/powerpc/archdep.h     2 Jan 2017 15:55:52 -0000
@@ -87,6 +87,4 @@ RELOC_DYN(Elf32_Rela *r, const Elf32_Sym
 
 #define RELOC_GOT(obj, offs)
 
-#define GOT_PERMS PROT_READ
-
 #endif /* _POWERPC_ARCHDEP_H_ */
Index: libexec/ld.so/sh/archdep.h
===================================================================
RCS file: /cvs/src/libexec/ld.so/sh/archdep.h,v
retrieving revision 1.6
diff -u -p -r1.6 archdep.h
--- libexec/ld.so/sh/archdep.h  18 May 2016 20:40:20 -0000      1.6
+++ libexec/ld.so/sh/archdep.h  2 Jan 2017 15:55:52 -0000
@@ -43,8 +43,6 @@
 #include "syscall.h"
 #include "util.h"
 
-#define  RTLD_NO_WXORX
-
 /*
  *     The following functions are declared inline so they can
  *     be used before bootstrap linking has been finished.
@@ -72,7 +70,5 @@ RELOC_DYN(Elf32_Rela *r, const Elf32_Sym
 }
 
 #define RELOC_GOT(obj, offs)
-
-#define GOT_PERMS (PROT_READ|PROT_EXEC)
 
 #endif /* _SH_ARCHDEP_H_ */
Index: libexec/ld.so/sparc64/archdep.h
===================================================================
RCS file: /cvs/src/libexec/ld.so/sparc64/archdep.h,v
retrieving revision 1.21
diff -u -p -r1.21 archdep.h
--- libexec/ld.so/sparc64/archdep.h     18 May 2016 20:40:20 -0000      1.21
+++ libexec/ld.so/sparc64/archdep.h     2 Jan 2017 15:55:52 -0000
@@ -66,6 +66,4 @@ RELOC_DYN(Elf_RelA *r, const Elf_Sym *s,
 
 #define RELOC_GOT(obj, offs)
 
-#define GOT_PERMS PROT_READ
-
 #endif /* _SPARC64_ARCHDEP_H_ */

Reply via email to