Module Name:    src
Committed By:   christos
Date:           Sun May  8 01:28:09 UTC 2016

Modified Files:
        src/sys/kern: exec_elf.c kern_exec.c kern_pax.c
        src/sys/sys: pax.h

Log Message:
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.


To generate a diff of this commit:
cvs rdiff -u -r1.82 -r1.83 src/sys/kern/exec_elf.c
cvs rdiff -u -r1.426 -r1.427 src/sys/kern/kern_exec.c
cvs rdiff -u -r1.41 -r1.42 src/sys/kern/kern_pax.c
cvs rdiff -u -r1.19 -r1.20 src/sys/sys/pax.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/exec_elf.c
diff -u src/sys/kern/exec_elf.c:1.82 src/sys/kern/exec_elf.c:1.83
--- src/sys/kern/exec_elf.c:1.82	Sat Mar 19 14:56:37 2016
+++ src/sys/kern/exec_elf.c	Sat May  7 21:28:09 2016
@@ -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 @@ __KERNEL_RCSID(1, "$NetBSD: exec_elf.c,v
 #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 @@ elf_placedynexec(struct exec_package *ep
 		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++)

Index: src/sys/kern/kern_exec.c
diff -u src/sys/kern/kern_exec.c:1.426 src/sys/kern/kern_exec.c:1.427
--- src/sys/kern/kern_exec.c:1.426	Mon Apr  4 19:07:06 2016
+++ src/sys/kern/kern_exec.c	Sat May  7 21:28:09 2016
@@ -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 @@ execve_loadvm(struct lwp *l, const char 
 	 */
 
 #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

Index: src/sys/kern/kern_pax.c
diff -u src/sys/kern/kern_pax.c:1.41 src/sys/kern/kern_pax.c:1.42
--- src/sys/kern/kern_pax.c:1.41	Sun Apr 10 11:41:05 2016
+++ src/sys/kern/kern_pax.c	Sat May  7 21:28:09 2016
@@ -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 @@ __KERNEL_RCSID(0, "$NetBSD: kern_pax.c,v
 #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_mprotect_debug;
 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_SETUP(sysctl_security_pax_setup, 
 		       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 @@ pax_aslr_init_vm(struct lwp *l, struct v
 	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 @@ pax_aslr_mmap(struct lwp *l, vaddr_t *ad
 	}
 }
 
+#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 @@ pax_aslr_stack(struct exec_package *epp,
 
 	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 @@ pax_aslr_stack(struct exec_package *epp,
 	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

Index: src/sys/sys/pax.h
diff -u src/sys/sys/pax.h:1.19 src/sys/sys/pax.h:1.20
--- src/sys/sys/pax.h:1.19	Wed Apr  6 23:31:12 2016
+++ src/sys/sys/pax.h	Sat May  7 21:28:09 2016
@@ -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 <e...@netbsd.org>
@@ -79,6 +79,8 @@ bool pax_aslr_epp_active(struct exec_pac
 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_ */

Reply via email to