On Sun, 7 Aug 2016, Philip Guenther wrote:

> On Sun, Aug 7, 2016 at 4:45 AM, Mark Kettenis <[email protected]> wrote:
> >> Date: Sat, 6 Aug 2016 22:17:47 -0700
> >> From: Philip Guenther <[email protected]>
> >>
> >> Parts of this were stolen from kettenis.
> >>
> >> Hey, wouldn't it be cool if static PIE executables took advantage of the
> >> RELRO information too?
> >
> > Hmm.  The PLT doesn't have to be executable for static PIE
> > executables.  So I think you could simply transition to PROT_READ like
> > the old code does.
> 
> Perhaps we should make it PROT_NONE.  :-)

...except that doesn't work for hppa, when I do relro with .plt and .got 
together in the same section.  PROT_READ it is!

Tested on hppa with the relro update in the next message...

Philip

Index: lib/csu/boot.h
===================================================================
RCS file: /data/src/openbsd/src/lib/csu/boot.h,v
retrieving revision 1.21
diff -u -p -r1.21 boot.h
--- lib/csu/boot.h      7 Aug 2016 02:44:00 -0000       1.21
+++ lib/csu/boot.h      8 Aug 2016 03:00:53 -0000
@@ -86,8 +86,6 @@ struct boot_dyn {
  */
 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[];
 
@@ -106,6 +104,7 @@ _dl_boot_bind(const long sp, long *dl_da
        long            loff;
        int             prot_exec = 0;
        RELOC_TYPE      *rp;
+       Elf_Phdr        *phdp;
        Elf_Addr        i;
 
        /*
@@ -220,12 +219,29 @@ _dl_boot_bind(const long sp, long *dl_da
        else
                pagesize = 4096;
 
+       /* 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(__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);
+    defined(__sparc64__) || defined(__hppa__)
+               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)

Reply via email to