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