-/* $OpenBSD: boot.h,v 1.21 2016/08/07 02:44:00 guenther Exp $ */
+/* $OpenBSD: boot.h,v 1.22 2016/08/08 22:05:26 guenther Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
*/
void _dl_boot_bind(const long, long *, Elf_Dyn *);
-extern char __plt_start[];
-extern char __plt_end[];
extern char __got_start[];
extern char __got_end[];
long loff;
int prot_exec = 0;
RELOC_TYPE *rp;
+ Elf_Phdr *phdp;
Elf_Addr i;
/*
else
pagesize = 4096;
-#if defined(__alpha__) || defined(__powerpc__) || defined(__sparc__) || \
- defined(__sparc64__)
- start = ELF_TRUNC((Elf_Addr)__plt_start, pagesize);
- size = ELF_ROUND((Elf_Addr)__plt_end - start, pagesize);
- mprotect((void *)start, size, PROT_READ);
+ /* do any RWX -> RX fixups for executable PLTs and apply GNU_RELRO */
+ phdp = (Elf_Phdr *)dl_data[AUX_phdr];
+ for (i = 0; i < dl_data[AUX_phnum]; i++, phdp++) {
+ switch (phdp->p_type) {
+#if defined(__alpha__) || defined(__hppa__) || defined(__powerpc__) || \
+ defined(__sparc__) || defined(__sparc64__)
+ case PT_LOAD:
+ if ((phdp->p_flags & (PF_X | PF_W)) != (PF_X | PF_W))
+ break;
+ mprotect((void *)(phdp->p_vaddr + loff), phdp->p_memsz,
+ PROT_READ);
+ break;
#endif
+ case PT_GNU_RELRO:
+ mprotect((void *)(phdp->p_vaddr + loff), phdp->p_memsz,
+ PROT_READ);
+ /*
+ * GNU_RELRO (a) covers the GOT, and (b) comes after
+ * all LOAD sections, so if we found it then we're done
+ */
+ return;
+ }
+ }
#if defined(__powerpc__)
if (dynld.dt_proc[DT_PROC(DT_PPC_GOT)] == 0)