Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys Move all the randomization inside kern_pax.c so we can c...



details:   https://anonhg.NetBSD.org/src/rev/cacb7347e344
branches:  trunk
changeset: 345113:cacb7347e344
user:      christos <christos%NetBSD.org@localhost>
date:      Sun May 08 01:28:09 2016 +0000

description:
Move all the randomization inside kern_pax.c so we can control it directly.
Add debugging flags to be able to set the random number externally.

diffstat:

 sys/kern/exec_elf.c  |  35 +++----------------
 sys/kern/kern_exec.c |   6 +-
 sys/kern/kern_pax.c  |  89 +++++++++++++++++++++++++++++++++++++++++++++++----
 sys/sys/pax.h        |   4 +-
 4 files changed, 94 insertions(+), 40 deletions(-)

diffs (260 lines):

diff -r 8ba2ce57c1e2 -r cacb7347e344 sys/kern/exec_elf.c
--- a/sys/kern/exec_elf.c       Sat May 07 23:51:30 2016 +0000
+++ b/sys/kern/exec_elf.c       Sun May 08 01:28:09 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: exec_elf.c,v 1.82 2016/03/19 18:56:37 christos Exp $   */
+/*     $NetBSD: exec_elf.c,v 1.83 2016/05/08 01:28:09 christos Exp $   */
 
 /*-
  * Copyright (c) 1994, 2000, 2005, 2015 The NetBSD Foundation, Inc.
@@ -57,7 +57,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: exec_elf.c,v 1.82 2016/03/19 18:56:37 christos Exp $");
+__KERNEL_RCSID(1, "$NetBSD: exec_elf.c,v 1.83 2016/05/08 01:28:09 christos Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_pax.h"
@@ -76,7 +76,6 @@
 #include <sys/stat.h>
 #include <sys/kauth.h>
 #include <sys/bitops.h>
-#include <sys/cprng.h>
 
 #include <sys/cpu.h>
 #include <machine/reg.h>
@@ -125,32 +124,10 @@
                if (ph[i].p_type == PT_LOAD && ph[i].p_align > align)
                        align = ph[i].p_align;
 
-#ifdef PAX_ASLR
-       if (pax_aslr_epp_active(epp)) {
-               size_t pax_align, l2, delta;
-               uint32_t r;
-
-               pax_align = align;
-
-               r = cprng_fast32();
-
-               if (pax_align == 0)
-                       pax_align = PGSHIFT;
-               l2 = ilog2(pax_align);
-               delta = PAX_ASLR_DELTA(r, l2, PAX_ASLR_DELTA_EXEC_LEN);
-               offset = ELF_TRUNC(delta, pax_align) + PAGE_SIZE;
-#ifdef PAX_ASLR_DEBUG
-               if (pax_aslr_debug) {
-                       uprintf("%s: r=%#x l2=%#zx pax_align=%#zx delta=%#zx\n",
-                           __func__, r, l2, pax_align, delta);
-                       uprintf("%s: pax offset=%#jx entry=%#jx\n", __func__,
-                           (uintmax_t)offset, (uintmax_t)eh->e_entry);
-               }
-#endif /* PAX_ASLR_DEBUG */
-       } else
-#endif /* PAX_ASLR */
-               offset = MAX(align, PAGE_SIZE);
-
+#ifndef PAX_ASLR
+# define pax_aslr_exec_offset(epp, align) MAX(align, PAGE_SIZE)
+#endif
+       offset = (Elf_Addr)pax_aslr_exec_offset(epp, align);
        offset += epp->ep_vm_minaddr;
 
        for (i = 0; i < eh->e_phnum; i++)
diff -r 8ba2ce57c1e2 -r cacb7347e344 sys/kern/kern_exec.c
--- a/sys/kern/kern_exec.c      Sat May 07 23:51:30 2016 +0000
+++ b/sys/kern/kern_exec.c      Sun May 08 01:28:09 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_exec.c,v 1.426 2016/04/04 23:07:06 christos Exp $ */
+/*     $NetBSD: kern_exec.c,v 1.427 2016/05/08 01:28:09 christos Exp $ */
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -59,7 +59,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.426 2016/04/04 23:07:06 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.427 2016/05/08 01:28:09 christos Exp $");
 
 #include "opt_exec.h"
 #include "opt_execfmt.h"
@@ -759,7 +759,7 @@
         */
 
 #ifdef PAX_ASLR
-#define        ASLR_GAP(epp)   (pax_aslr_epp_active(epp) ? (cprng_fast32() % PAGE_SIZE) : 0)
+#define        ASLR_GAP(epp)   pax_aslr_stack_gap(epp)
 #else
 #define        ASLR_GAP(epp)   0
 #endif
diff -r 8ba2ce57c1e2 -r cacb7347e344 sys/kern/kern_pax.c
--- a/sys/kern/kern_pax.c       Sat May 07 23:51:30 2016 +0000
+++ b/sys/kern/kern_pax.c       Sun May 08 01:28:09 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_pax.c,v 1.41 2016/04/10 15:41:05 christos Exp $   */
+/*     $NetBSD: kern_pax.c,v 1.42 2016/05/08 01:28:09 christos Exp $   */
 
 /*
  * Copyright (c) 2015 The NetBSD Foundation, Inc.
@@ -57,7 +57,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_pax.c,v 1.41 2016/04/10 15:41:05 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_pax.c,v 1.42 2016/05/08 01:28:09 christos Exp $");
 
 #include "opt_pax.h"
 
@@ -73,6 +73,7 @@
 #include <sys/syslog.h>
 #include <sys/vnode.h>
 #include <sys/queue.h>
+#include <sys/bitops.h>
 #include <sys/kauth.h>
 #include <sys/cprng.h>
 
@@ -136,8 +137,12 @@
 int pax_aslr_debug;
 /* flag set means disable */
 int pax_aslr_flags;
-#define PAX_ASLR_STACK 1
-#define PAX_ASLR_MMAP  2
+uint32_t pax_aslr_rand;
+#define PAX_ASLR_STACK         0x01
+#define PAX_ASLR_STACK_GAP     0x02
+#define PAX_ASLR_MMAP          0x04
+#define PAX_ASLR_EXEC_OFFSET   0x08
+#define PAX_ASLR_FIXED         0x10
 #endif
 
 static int pax_segvguard_enabled = 1;
@@ -283,6 +288,12 @@
                       SYSCTL_DESCR("Disable/Enable select ASLR features."),
                       NULL, 0, &pax_aslr_flags, 0,
                       CTL_CREATE, CTL_EOL);
+       sysctl_createv(clog, 0, &rnode, NULL,
+                      CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
+                      CTLTYPE_INT, "rand",
+                      SYSCTL_DESCR("Use the given fixed random value"),
+                      NULL, 0, &pax_aslr_rand, 0,
+                      CTL_CREATE, CTL_EOL);
 #endif
        sysctl_createv(clog, 0, &rnode, NULL,
                       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
@@ -459,7 +470,12 @@
        uint32_t len = (ep->ep_flags & EXEC_32) ?
            PAX_ASLR_DELTA_MMAP_LEN32 : PAX_ASLR_DELTA_MMAP_LEN;
 
-       vm->vm_aslr_delta_mmap = PAX_ASLR_DELTA(cprng_fast32(),
+       uint32_t rand = cprng_fast32();
+#ifdef PAX_ASLR_DEBUG
+       if (pax_aslr_flags & PAX_ASLR_FIXED)
+               rand = pax_aslr_rand;
+#endif
+       vm->vm_aslr_delta_mmap = PAX_ASLR_DELTA(rand,
            PAX_ASLR_DELTA_MMAP_LSB, len);
 
        PAX_DPRINTF("delta_mmap=%#jx/%u", vm->vm_aslr_delta_mmap, len);
@@ -496,6 +512,40 @@
        }
 }
 
+#define        PAX_TRUNC(a, b) ((a) & ~((b) - 1))
+vaddr_t
+pax_aslr_exec_offset(struct exec_package *epp, vaddr_t align)
+{
+       size_t pax_align, l2, delta;
+       uint32_t rand;
+       vaddr_t offset;
+
+       if (!pax_aslr_epp_active(epp))
+               goto out;
+
+#ifdef PAX_ASLR_DEBUG
+       if (pax_aslr_flags & PAX_ASLR_EXEC_OFFSET)
+               goto out;
+#endif
+
+       pax_align = align == 0 ? PGSHIFT : align;
+       l2 = ilog2(pax_align);
+
+       rand = cprng_fast32();
+#ifdef PAX_ASLR_DEBUG
+       if (pax_aslr_flags & PAX_ASLR_FIXED)
+               rand = pax_aslr_rand;
+#endif
+       delta = PAX_ASLR_DELTA(rand, l2, PAX_ASLR_DELTA_EXEC_LEN);
+       offset = PAX_TRUNC(delta, pax_align) + PAGE_SIZE;
+
+       PAX_DPRINTF("rand=%#x l2=%#zx pax_align=%#zx delta=%#zx offset=%#jx",
+           rand, l2, pax_align, delta, (uintmax_t)offset);
+       return offset;
+out:
+       return MAX(align, PAGE_SIZE);
+}
+
 void
 pax_aslr_stack(struct exec_package *epp, u_long *max_stack_size)
 {
@@ -508,8 +558,12 @@
 
        uint32_t len = (epp->ep_flags & EXEC_32) ?
            PAX_ASLR_DELTA_STACK_LEN32 : PAX_ASLR_DELTA_STACK_LEN;
-       u_long d = PAX_ASLR_DELTA(cprng_fast32(), PAX_ASLR_DELTA_STACK_LSB,
-           len);
+       uint32_t rand = cprng_fast32();
+#ifdef PAX_ASLR_DEBUG
+       if (pax_aslr_flags & PAX_ASLR_FIXED)
+               rand = pax_aslr_rand;
+#endif
+       u_long d = PAX_ASLR_DELTA(rand, PAX_ASLR_DELTA_STACK_LSB, len);
        u_long newminsaddr = (u_long)STACK_ALLOC(epp->ep_minsaddr, d);
        PAX_DPRINTF("old minsaddr=%#jx delta=%#lx new minsaddr=%#lx",
            (uintmax_t)epp->ep_minsaddr, d, newminsaddr);
@@ -518,6 +572,27 @@
        if (epp->ep_ssize > *max_stack_size)
                epp->ep_ssize = *max_stack_size;
 }
+
+uint32_t
+pax_aslr_stack_gap(struct exec_package *epp)
+{
+       if (!pax_aslr_epp_active(epp))
+               return 0;
+
+#ifdef PAX_ASLR_DEBUG
+       if (pax_aslr_flags & PAX_ASLR_STACK_GAP)
+               return 0;
+#endif
+
+       uint32_t rand = cprng_fast32();
+#ifdef PAX_ASLR_DEBUG
+       if (pax_aslr_flags & PAX_ASLR_FIXED)
+               rand = pax_aslr_rand;
+#endif
+       rand %= PAGE_SIZE;
+       PAX_DPRINTF("stack gap=%#x\n", rand);
+       return rand;
+}
 #endif /* PAX_ASLR */
 
 #ifdef PAX_SEGVGUARD
diff -r 8ba2ce57c1e2 -r cacb7347e344 sys/sys/pax.h
--- a/sys/sys/pax.h     Sat May 07 23:51:30 2016 +0000
+++ b/sys/sys/pax.h     Sun May 08 01:28:09 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pax.h,v 1.19 2016/04/07 03:31:12 christos Exp $ */
+/* $NetBSD: pax.h,v 1.20 2016/05/08 01:28:09 christos Exp $ */
 
 /*-
  * Copyright (c) 2006 Elad Efrat <elad%NetBSD.org@localhost>
@@ -79,6 +79,8 @@
 bool pax_aslr_active(struct lwp *);
 void pax_aslr_init_vm(struct lwp *, struct vmspace *, struct exec_package *);
 void pax_aslr_stack(struct exec_package *, u_long *);
+uint32_t pax_aslr_stack_gap(struct exec_package *);
+vaddr_t pax_aslr_exec_offset(struct exec_package *, vaddr_t);
 void pax_aslr_mmap(struct lwp *, vaddr_t *, vaddr_t, int);
 
 #endif /* !_SYS_PAX_H_ */



Home | Main Index | Thread Index | Old Index