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_ */