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 <[email protected]>
@@ -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_ */