Ahem.

What I mean is that with some patching, RELRO can be enabled by default on 
several archs.  The first chunk below enables it on x86, arm, and sparc64.  
I'm 95% positive that it would Just Work on alpha and sh (TEXT_PLT archs 
like amd64, arm, and i386) and sparc (looks like sparc64, shock!), but 
this is untested there.


So what is RELRO anyway?  RELRO is basically a hook for marking sections 
of memory of an object as being "Read-Only after RELocation".

We've been doing a version of this for years on OpenBSD via the 
__{got,plt}_{start,end} symbols: ld.so would mprotect the regions between 
those symbols after relocation, and then when relocating lazy binding it 
would mark the necessary bits temporarily writable.  Last year we added 
kbind() so that lazy relocations could be done securely and efficiently 
through the kernel.

Since then, we've practically eliminated the need for the 
__plt_{start,end} handling by treating all RWX sections as RW-until- 
-relocation-and-RX-after-relocation.

While our design works, the GNU_RELRO design by the GNU people offers some 
advantages:
 - no need for symbol lookup.  The start address and length are coded
   directly into the section instead of needing two symbol lookups
 - covers even more than we did.  Theo and Dale had to do serious hacking
   to get our support to cover not just the GOT but also the .ctors and 
   .dtors segments.  Well, the GNU people hacked more and managed to make 
   the .eh_frame, .tdata, .tbss, dynamic, .{init,preinit,fini}_array, and 
   .jcr segments also RELRO.
 - fewer mappings.  There are two areas, both of which need to start out
   read-write but the first needs to switch to read-only.  The GNU people 
   realized that if you align the data correctly in the file, you can do 
   *one* mmap() that covers both but place the division between them on a 
   page boundary so it can be the start of a later mprotect(), thus saving 
   the cost of a separate mmap() call.


So what's going on in this diff?

The armelf_obsd.sh chunk makes that arch order things like the others, 
setting things up before sourcing the common elf_obsd bits that depend on 
them, with 4KB as the normal pagesize.  If there's nothing special about 
16KB in our uvm/pmap layer then lowering MAXPAGESIZE may save space.

While I don't have RELRO 100% working on powerpc (damn bss-plt compat) or 
mips64 yet, these are a start...and I've been testing with them so long 
I'm not sure things work without them.  I really don't know what *PAGESIZE 
values are appropriate for mips BE & LE: loongson has 16KB pages, are 
there mips64le with smaller?

As for elf.sc: "Cthulhu touches you with his tentacle: you lose 5 sanity" 
The diff here does this:
 - move some not-really-executable bits from the start of the inital RX
   section to start of the first RO section
 - move the PLT in the "executable, but initially mutable and not required
   to be before the GOT" case from immediately before the .data segment to 
   between the RO and RW sections.  This is used, for example, on sparc64 
   where the sections end up in the order
        RX      .init .text .fini
        R       .interp .note* .hash .dyn* .rel* .rodata .eh_frame
        RWX     .plt
        RW      .openbsd.randomdata .jcr .dynamic .got .cdtors .data .bss
 - move up the __got_start symbols to the start of the RW section
 - *don't* pad before the PLT when it's a DATA_PLT in the relro area
 - when doing RELRO, put the .ctor and .dtor sections right after
   the .got and *right before* the RELRO RO-vs-RW boundary

Have I lost everyone?  Beuhler?  Beuhler?  oks?


Philip Guenther

Index: gnu/usr.bin/binutils-2.17/ld/ldmain.c
===================================================================
RCS file: /cvs/src/gnu/usr.bin/binutils-2.17/ld/ldmain.c,v
retrieving revision 1.9
diff -u -p -r1.9 ldmain.c
--- gnu/usr.bin/binutils-2.17/ld/ldmain.c       21 Jun 2016 02:55:57 -0000      
1.9
+++ gnu/usr.bin/binutils-2.17/ld/ldmain.c       7 Aug 2016 03:18:37 -0000
@@ -299,7 +299,12 @@ main (int argc, char **argv)
   link_info.new_dtags = FALSE;
   link_info.combreloc = TRUE;
   link_info.eh_frame_hdr = FALSE;
+#if defined(__amd64__) || defined(__arm__) || defined(__i386__) || \
+    defined(__sparc64__)
+  link_info.relro = TRUE;
+#else
   link_info.relro = FALSE;
+#endif
   link_info.strip_discarded = TRUE;
   link_info.strip = strip_none;
   link_info.discard = discard_sec_merge;
Index: gnu/usr.bin/binutils-2.17/ld/emulparams/armelf_obsd.sh
===================================================================
RCS file: /cvs/src/gnu/usr.bin/binutils-2.17/ld/emulparams/armelf_obsd.sh,v
retrieving revision 1.1
diff -u -p -r1.1 armelf_obsd.sh
--- gnu/usr.bin/binutils-2.17/ld/emulparams/armelf_obsd.sh      24 Apr 2011 
20:19:25 -0000      1.1
+++ gnu/usr.bin/binutils-2.17/ld/emulparams/armelf_obsd.sh      7 Aug 2016 
03:18:37 -0000
@@ -1,8 +1,10 @@
 . ${srcdir}/emulparams/armelf.sh
-. ${srcdir}/emulparams/elf_obsd.sh
 
 MAXPAGESIZE=0x8000
+COMMONPAGESIZE=0x1000
 TEXT_START_ADDR=0x00008000
 TARGET2_TYPE=got-rel
 
 unset EMBEDDED
+
+. ${srcdir}/emulparams/elf_obsd.sh
Index: gnu/usr.bin/binutils-2.17/ld/emulparams/elf32ppc_obsd.sh
===================================================================
RCS file: /cvs/src/gnu/usr.bin/binutils-2.17/ld/emulparams/elf32ppc_obsd.sh,v
retrieving revision 1.3
diff -u -p -r1.3 elf32ppc_obsd.sh
--- gnu/usr.bin/binutils-2.17/ld/emulparams/elf32ppc_obsd.sh    23 Aug 2015 
15:19:32 -0000      1.3
+++ gnu/usr.bin/binutils-2.17/ld/emulparams/elf32ppc_obsd.sh    7 Aug 2016 
03:18:37 -0000
@@ -1,7 +1,2 @@
-. ${srcdir}/emulparams/elf32ppccommon.sh
-# We deliberately keep the traditional OpenBSD W^X layout for both the
-# old BSS-PLT and the new Secure-PLT ABI.
-BSS_PLT=
-OTHER_TEXT_SECTIONS="*(.glink)"
-EXTRA_EM_FILE=ppc32elf
+. ${srcdir}/emulparams/elf32ppc.sh
 . ${srcdir}/emulparams/elf_obsd.sh
Index: gnu/usr.bin/binutils-2.17/ld/emulparams/elf64btsmip_obsd.sh
===================================================================
RCS file: /cvs/src/gnu/usr.bin/binutils-2.17/ld/emulparams/elf64btsmip_obsd.sh,v
retrieving revision 1.2
diff -u -p -r1.2 elf64btsmip_obsd.sh
--- gnu/usr.bin/binutils-2.17/ld/emulparams/elf64btsmip_obsd.sh 16 Jun 2015 
20:25:35 -0000      1.2
+++ gnu/usr.bin/binutils-2.17/ld/emulparams/elf64btsmip_obsd.sh 7 Aug 2016 
03:18:37 -0000
@@ -1,5 +1,6 @@
 . ${srcdir}/emulparams/elf64btsmip.sh
 MAXPAGESIZE=0x10000
+COMMONPAGESIZE=0x1000
 TEXT_START_ADDR="0x10000000"
 . ${srcdir}/emulparams/elf_obsd.sh
 # XXX causes GOT oflows
Index: gnu/usr.bin/binutils-2.17/ld/emulparams/elf64ltsmip_obsd.sh
===================================================================
RCS file: /cvs/src/gnu/usr.bin/binutils-2.17/ld/emulparams/elf64ltsmip_obsd.sh,v
retrieving revision 1.2
diff -u -p -r1.2 elf64ltsmip_obsd.sh
--- gnu/usr.bin/binutils-2.17/ld/emulparams/elf64ltsmip_obsd.sh 16 Jun 2015 
20:25:35 -0000      1.2
+++ gnu/usr.bin/binutils-2.17/ld/emulparams/elf64ltsmip_obsd.sh 7 Aug 2016 
03:18:37 -0000
@@ -1,5 +1,6 @@
 . ${srcdir}/emulparams/elf64ltsmip.sh
 MAXPAGESIZE=0x10000
+COMMONPAGESIZE=0x1000
 TEXT_START_ADDR="0x10000000"
 . ${srcdir}/emulparams/elf_obsd.sh
 # XXX causes GOT oflows
Index: gnu/usr.bin/binutils-2.17/ld/scripttempl/elf.sc
===================================================================
RCS file: /cvs/src/gnu/usr.bin/binutils-2.17/ld/scripttempl/elf.sc,v
retrieving revision 1.8
diff -u -p -r1.8 elf.sc
--- gnu/usr.bin/binutils-2.17/ld/scripttempl/elf.sc     9 Aug 2014 04:49:47 
-0000       1.8
+++ gnu/usr.bin/binutils-2.17/ld/scripttempl/elf.sc     7 Aug 2016 03:18:38 
-0000
@@ -267,6 +267,35 @@ SECTIONS
   ${CREATE_SHLIB-${CREATE_PIE-${RELOCATING+PROVIDE (__executable_start = 
${TEXT_START_ADDR}); . = ${TEXT_BASE_ADDRESS};}}}
   ${CREATE_SHLIB+${RELOCATING+. = ${SHLIB_TEXT_START_ADDR:-0} + 
SIZEOF_HEADERS;}}
   ${CREATE_PIE+${RELOCATING+. = ${SHLIB_TEXT_START_ADDR:-0} + SIZEOF_HEADERS;}}
+  .init         ${RELOCATING-0} : 
+  { 
+    ${RELOCATING+${INIT_START}}
+    KEEP (*(.init))
+    ${RELOCATING+${INIT_END}}
+  } =${NOP-0}
+
+  ${TEXT_PLT+${PLT}}
+  ${TINY_READONLY_SECTION}
+  .text         ${RELOCATING-0} :
+  {
+    ${RELOCATING+${TEXT_START_SYMBOLS}}
+    *(.text .stub${RELOCATING+ .text.* .gnu.linkonce.t.*})
+    KEEP (*(.text.*personality*))
+    /* .gnu.warning sections are handled specially by elf32.em.  */
+    *(.gnu.warning)
+    ${RELOCATING+${OTHER_TEXT_SECTIONS}}
+  } =${NOP-0}
+  .fini         ${RELOCATING-0} :
+  {
+    ${RELOCATING+${FINI_START}}
+    KEEP (*(.fini))
+    ${RELOCATING+${FINI_END}}
+  } =${NOP-0}
+  ${RELOCATING+PROVIDE (__${ETEXT_NAME} = .);}
+  ${RELOCATING+PROVIDE (_${ETEXT_NAME} = .);}
+  ${RELOCATING+PROVIDE (${ETEXT_NAME} = .);}
+
+  ${PAD_RO+${PAD_RO0}}
   ${CREATE_SHLIB-${INTERP}}
   ${INITIAL_READONLY_SECTIONS}
   ${TEXT_DYNAMIC+${DYNAMIC}}
@@ -337,34 +366,6 @@ cat <<EOF
   .rela.plt     ${RELOCATING-0} : { *(.rela.plt) }
   ${OTHER_PLT_RELOC_SECTIONS}
 
-  .init         ${RELOCATING-0} : 
-  { 
-    ${RELOCATING+${INIT_START}}
-    KEEP (*(.init))
-    ${RELOCATING+${INIT_END}}
-  } =${NOP-0}
-
-  ${TEXT_PLT+${PLT}}
-  ${TINY_READONLY_SECTION}
-  .text         ${RELOCATING-0} :
-  {
-    ${RELOCATING+${TEXT_START_SYMBOLS}}
-    *(.text .stub${RELOCATING+ .text.* .gnu.linkonce.t.*})
-    KEEP (*(.text.*personality*))
-    /* .gnu.warning sections are handled specially by elf32.em.  */
-    *(.gnu.warning)
-    ${RELOCATING+${OTHER_TEXT_SECTIONS}}
-  } =${NOP-0}
-  .fini         ${RELOCATING-0} :
-  {
-    ${RELOCATING+${FINI_START}}
-    KEEP (*(.fini))
-    ${RELOCATING+${FINI_END}}
-  } =${NOP-0}
-  ${RELOCATING+PROVIDE (__${ETEXT_NAME} = .);}
-  ${RELOCATING+PROVIDE (_${ETEXT_NAME} = .);}
-  ${RELOCATING+PROVIDE (${ETEXT_NAME} = .);}
-  ${PAD_RO+${PAD_RO0}}
   ${WRITABLE_RODATA-${RODATA}}
   .rodata1      ${RELOCATING-0} : { *(.rodata1) }
   ${CREATE_SHLIB-${SDATA2}}
@@ -374,11 +375,15 @@ cat <<EOF
   .eh_frame     ${RELOCATING-0} : ONLY_IF_RO { KEEP (*(.eh_frame)) }
   .gcc_except_table ${RELOCATING-0} : ONLY_IF_RO { *(.gcc_except_table 
.gcc_except_table.*) }
 
+  ${DATA_NONEXEC_PLT-${DATA_PLT+${PLT_BEFORE_GOT-${PAD_PLT+${PAD_PLT0}}}}}
+  ${DATA_NONEXEC_PLT-${DATA_PLT+${PLT_BEFORE_GOT-${PLT}}}}
+
   /* Adjust the address for the data segment.  We want to adjust up to
      the same address within the page on the next page up.  */
   ${CREATE_SHLIB-${CREATE_PIE-${RELOCATING+. = 
${DATA_ADDR-${DATA_SEGMENT_ALIGN}};}}}
   ${CREATE_SHLIB+${RELOCATING+. = ${SHLIB_DATA_ADDR-${DATA_SEGMENT_ALIGN}};}}
   ${CREATE_PIE+${RELOCATING+. = ${SHLIB_DATA_ADDR-${DATA_SEGMENT_ALIGN}};}}
+  ${DATA_GOT+${RELRO_NOW+${PAD_GOT+${RELOCATING+PROVIDE_HIDDEN(__got_start = 
.);}}}}
 
   /* Exception handling  */
   .eh_frame     ${RELOCATING-0} : ONLY_IF_RW { KEEP (*(.eh_frame)) }
@@ -419,11 +424,13 @@ cat <<EOF
   ${RELOCATING+${DATARELRO}}
   ${OTHER_RELRO_SECTIONS}
   ${TEXT_DYNAMIC-${DYNAMIC}}
-  ${DATA_GOT+${PAD_GOT+${PAD_GOT0}}}
+  ${DATA_GOT+${RELRO_NOW-${PAD_GOT+${PAD_GOT0}}}}
   ${DATA_GOT+${DATA_NONEXEC_PLT+${PLT}}}
   ${DATA_GOT+${RELRO_NOW+${GOT}}}
   ${DATA_GOT+${RELRO_NOW+${GOTPLT}}}
-  ${DATA_GOT+${RELRO_NOW+${PAD_GOT+${PAD_GOT1}}}}
+  ${DATA_GOT+${RELRO_NOW+${PAD_CDTOR+${RELOCATING+${CTOR}}}}}
+  ${DATA_GOT+${RELRO_NOW+${PAD_CDTOR+${RELOCATING+${DTOR}}}}}
+  ${DATA_GOT+${RELRO_NOW+${PAD_GOT+${RELOCATING+PROVIDE_HIDDEN(__got_end = 
.);}}}}
   ${DATA_GOT+${RELRO_NOW-${SEPARATE_GOTPLT+${GOT}}}}
   /* If PAD_CDTOR, and separate .got and .got.plt sections, CTOR and DTOR
      are relocated here to receive the same mprotect protection as .got */
@@ -437,10 +444,6 @@ cat <<EOF
   ${DATA_GOT+${RELRO_NOW-${SEPARATE_GOTPLT-${PAD_GOT+${PAD_GOT1}}}}}
   ${DATA_GOT+${RELRO_NOW-${GOTPLT}}}
 
-  ${DATA_NONEXEC_PLT-${DATA_PLT+${PLT_BEFORE_GOT-${PAD_PLT+${PAD_PLT0}}}}}
-  ${DATA_NONEXEC_PLT-${DATA_PLT+${PLT_BEFORE_GOT-${PLT}}}}
-  ${DATA_NONEXEC_PLT-${DATA_PLT+${PLT_BEFORE_GOT-${PAD_PLT+${PAD_PLT1}}}}}
-
   .data         ${RELOCATING-0} :
   {
     ${RELOCATING+${DATA_START_SYMBOLS}}
@@ -462,8 +465,6 @@ cat <<EOF
   ${SDATA_GOT+${RELOCATING+${OTHER_GOT_SYMBOLS}}}
   ${SDATA_GOT+${GOT}}
 
-  ${DATA_GOT+${RELRO_NOW+${PAD_CDTOR+${RELOCATING+${CTOR}}}}}
-  ${DATA_GOT+${RELRO_NOW+${PAD_CDTOR+${RELOCATING+${DTOR}}}}}
   ${DATA_GOT-${PAD_CDTOR+${RELOCATING+${CTOR}}}}
   ${DATA_GOT-${PAD_CDTOR+${RELOCATING+${DTOR}}}}
 

Reply via email to