Make sure the GOT and PLT are not writable.
authorkettenis <kettenis@openbsd.org>
Tue, 23 Dec 2014 16:45:04 +0000 (16:45 +0000)
committerkettenis <kettenis@openbsd.org>
Tue, 23 Dec 2014 16:45:04 +0000 (16:45 +0000)
Note that ommitting PROT_EXEC for the PLT is deliberate; static PIE
binaries should never actually hit the PLT.

We're still debating what to do when mprotect(2) fails.  But that is no
excuse not to at least attempt to fix things up.

ok deraadt@

lib/csu/boot.h

index 60d778e..231f4c3 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: boot.h,v 1.2 2014/12/22 13:32:51 kettenis Exp $ */
+/*     $OpenBSD: boot.h,v 1.3 2014/12/23 16:45:04 kettenis 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[];
+
 void
 _dl_boot_bind(const long sp, long *dl_data, Elf_Dyn *dynamicp)
 {
@@ -66,6 +71,8 @@ _dl_boot_bind(const long sp, long *dl_data, Elf_Dyn *dynamicp)
        AuxInfo         *auxstack;
        long            *stack;
        Elf_Dyn         *dynp;
+       Elf_Addr        start;
+       size_t          size;
        int             n, argc;
        char **argv, **envp;
        long loff;
@@ -248,5 +255,20 @@ _dl_boot_bind(const long sp, long *dl_data, Elf_Dyn *dynamicp)
         * 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.
+        */
+
+#if defined(__sparc64__)
+       start = ELF_TRUNC((Elf_Addr)__plt_start, PAGE_SIZE);
+       size = ELF_ROUND((Elf_Addr)__plt_end - start, PAGE_SIZE);
+       mprotect((void *)start, size, PROT_READ);
+#endif
+
+       start = ELF_TRUNC((Elf_Addr)__got_start, PAGE_SIZE);
+       size = ELF_ROUND((Elf_Addr)__got_end - start, PAGE_SIZE);
+       mprotect((void *)start, size, PROT_READ);
 }
 #endif /* RCRT0 */