Subject: ASLR patch
To: None <tech-kern@netbsd.org>
From: Christos Zoulas <christos@zoulas.com>
List: tech-kern
Date: 12/23/2007 22:59:54
Here's my adaptation of elad's code to current. Comments appreciated. If
I don't hear any objections, I will commit it.

christos

Index: usr.sbin/paxctl/paxctl.c
===================================================================
RCS file: /cvsroot/src/usr.sbin/paxctl/paxctl.c,v
retrieving revision 1.5
diff -u -u -r1.5 paxctl.c
--- usr.sbin/paxctl/paxctl.c	15 Dec 2007 19:44:56 -0000	1.5
+++ usr.sbin/paxctl/paxctl.c	24 Dec 2007 03:42:44 -0000
@@ -60,10 +60,12 @@
 /* NetBSD-specific note type: PaX.  There should be 1 NOTE per executable.
    section.  desc is a 32 bit bitmask */
 #define ELF_NOTE_TYPE_PAX_TAG		3
-#define	ELF_NOTE_PAX_MPROTECT		0x1	/* Force enable Mprotect */
-#define	ELF_NOTE_PAX_NOMPROTECT		0x2	/* Force disable Mprotect */
-#define	ELF_NOTE_PAX_GUARD		0x4	/* Force enable Segvguard */
-#define	ELF_NOTE_PAX_NOGUARD		0x8	/* Force disable Servguard */
+#define	ELF_NOTE_PAX_MPROTECT		0x01	/* Force enable Mprotect */
+#define	ELF_NOTE_PAX_NOMPROTECT		0x02	/* Force disable Mprotect */
+#define	ELF_NOTE_PAX_GUARD		0x04	/* Force enable Segvguard */
+#define	ELF_NOTE_PAX_NOGUARD		0x08	/* Force disable Servguard */
+#define	ELF_NOTE_PAX_ASLR		0x10	/* Force enable ASLR */
+#define	ELF_NOTE_PAX_NOASLR		0x20	/* Force disable ASLR */
 #define ELF_NOTE_PAX_NAMESZ		4
 #define ELF_NOTE_PAX_NAME		"PaX\0"
 #define ELF_NOTE_PAX_DESCSZ		4
@@ -78,6 +80,10 @@
 	const char *name;
 	int bits;
 } flags[] = {
+	{ 'A', "ASLR, explicit enable",
+	  ELF_NOTE_PAX_ASLR },
+	{ 'a', "ASLR, explicit disable",
+	  ELF_NOTE_PAX_NOASLR },
 	{ 'G', "Segvguard, explicit enable",
 	  ELF_NOTE_PAX_GUARD },
 	{ 'g', "Segvguard, explicit disable",
@@ -91,7 +97,7 @@
 static void
 usage(void)
 {
-	(void)fprintf(stderr, "Usage: %s [ <-|+><G|g|M|m> ] <file> ...\n",
+	(void)fprintf(stderr, "Usage: %s [ <-|+><A|a|G|g|M|m> ] <file> ...\n",
 #if HAVE_NBTOOL_CONFIG_H
 	    "paxctl"
 #else
Index: sys/kern/exec_elf32.c
===================================================================
RCS file: /cvsroot/src/sys/kern/exec_elf32.c,v
retrieving revision 1.127
diff -u -u -r1.127 exec_elf32.c
--- sys/kern/exec_elf32.c	3 Dec 2007 02:06:58 -0000	1.127
+++ sys/kern/exec_elf32.c	24 Dec 2007 03:42:45 -0000
@@ -87,15 +87,14 @@
 #include <sys/mount.h>
 #include <sys/stat.h>
 #include <sys/kauth.h>
+#include <sys/bitops.h>
 
 #include <sys/cpu.h>
 #include <machine/reg.h>
 
 #include <compat/common/compat_util.h>
 
-#if defined(PAX_MPROTECT) || defined(PAX_SEGVGUARD)
 #include <sys/pax.h>
-#endif /* PAX_MPROTECT || PAX_SEGVGUARD */
 
 extern const struct emul emul_netbsd;
 
@@ -604,16 +603,17 @@
 	char *interp = NULL;
 	u_long phsize;
 	struct proc *p;
+	boolean_t is_dyn;
 
 	if (epp->ep_hdrvalid < sizeof(Elf_Ehdr))
 		return ENOEXEC;
 
+	is_dyn = elf_check_header(eh, ET_DYN) == 0;
 	/*
 	 * XXX allow for executing shared objects. It seems silly
 	 * but other ELF-based systems allow it as well.
 	 */
-	if (elf_check_header(eh, ET_EXEC) != 0 &&
-	    elf_check_header(eh, ET_DYN) != 0)
+	if (elf_check_header(eh, ET_EXEC) != 0 && !is_dyn)
 		return ENOEXEC;
 
 	if (eh->e_phnum > MAXPHNUM)
@@ -671,6 +671,57 @@
 		pos = (Elf_Addr)startp;
 	}
 
+#if defined(PAX_MPROTECT) || defined(PAX_SEGVGUARD) || defined(PAX_ASLR)
+	if (epp->ep_pax_flags)
+		pax_adjust(l, epp->ep_pax_flags);
+#endif /* PAX_MPROTECT || PAX_SEGVGUARD || PAX_ASLR */
+
+
+#ifdef notyet
+/*
+ * Moving the segments around is not enough for the program to work.
+ * We also need to move the symbol string offsets and other things.
+ * This basically involves relocating the binary. We don't do that
+ * yet, until we have a dynamic linker in the kernel. The negative
+ * effect is that all programs get loaded in the same address, but
+ * PIE binaries still get the advantage that their dynamic libraries
+ * get loaded at random addresses.
+ */
+#ifdef PAX_ASLR
+	if (is_dyn && pax_aslr_active(l)) {
+		size_t pax_align = 0, pax_offset;
+
+		/*
+		 * find align XXX: not all sections might have the same
+		 * alignment
+		 */
+		for (i = 0; i < eh->e_phnum; i++)
+			if (ph[i].p_type == PT_LOAD) {
+				pax_align = ph[i].p_align;
+				break;
+			}
+
+		if (pax_align == 0)
+			pax_align = PGSHIFT;
+#ifdef DEBUG_ASLR
+		uprintf("r=0x%x a=0x%x p=0x%x Delta=0x%lx\n", epp->ep_random,
+		    ilog2(pax_align), PGSHIFT, PAX_ASLR_DELTA(epp->ep_random, 
+			ilog2(pax_align), 12));
+#endif
+		pax_offset = ELF_TRUNC(PAX_ASLR_DELTA(epp->ep_random,
+		    ilog2(pax_align), 12), pax_align);
+
+		for (i = 0; i < eh->e_phnum; i++)
+			ph[i].p_vaddr += pax_offset;
+		eh->e_entry += pax_offset;
+#ifdef DEBUG_ASLR
+		uprintf("pax offset=0x%x entry=0x%x\n",
+		    pax_offset, eh->e_entry);
+#endif
+	}
+#endif
+#endif
+
 	/*
 	 * Load all the necessary sections
 	 */
@@ -731,11 +782,6 @@
 		}
 	}
 
-#if defined(PAX_MPROTECT) || defined(PAX_SEGVGUARD)
-	if (epp->ep_pax_flags)
-		pax_adjust(l, epp->ep_pax_flags);
-#endif /* PAX_MPROTECT || PAX_SEGVGUARD */
-
 	/*
 	 * Check if we found a dynamically linked binary and arrange to load
 	 * its interpreter
Index: sys/kern/exec_subr.c
===================================================================
RCS file: /cvsroot/src/sys/kern/exec_subr.c,v
retrieving revision 1.56
diff -u -u -r1.56 exec_subr.c
--- sys/kern/exec_subr.c	26 Nov 2007 19:02:00 -0000	1.56
+++ sys/kern/exec_subr.c	24 Dec 2007 03:42:45 -0000
@@ -388,6 +388,19 @@
 		epp->ep_minsaddr = USRSTACK;
 		max_stack_size = MAXSSIZ;
 	}
+#ifdef PAX_ASLR
+	if (pax_aslr_active(l)) {
+		u_long d =  PAX_ASLR_DELTA(epp->ep_random, PAGE_SHIFT, 12);
+#ifdef DEBUG_ASLR
+		uprintf(("stack 0x%lx d=0x%lx 0x%lx\n",
+		    epp->ep_minsaddr, d, epp->ep_minsaddr - d));
+#endif
+		epp->ep_minsaddr -= d;
+		max_stack_size -= d;
+		l->l_proc->p_stackbase = epp->ep_minsaddr;
+	}
+#endif /* PAX_ASLR */
+	
 	epp->ep_maxsaddr = (u_long)STACK_GROW(epp->ep_minsaddr,
 		max_stack_size);
 	epp->ep_ssize = l->l_proc->p_rlimit[RLIMIT_STACK].rlim_cur;
Index: sys/kern/init_sysctl.c
===================================================================
RCS file: /cvsroot/src/sys/kern/init_sysctl.c,v
retrieving revision 1.115
diff -u -u -r1.115 init_sysctl.c
--- sys/kern/init_sysctl.c	22 Dec 2007 01:14:54 -0000	1.115
+++ sys/kern/init_sysctl.c	24 Dec 2007 03:42:47 -0000
@@ -94,8 +94,6 @@
 	PK_NOCLDWAIT, P_NOCLDWAIT,
 	PK_32, P_32,
 	PK_CLDSIGIGN, P_CLDSIGIGN,
-	PK_PAXMPROTECT, P_PAXMPROTECT,
-	PK_PAXNOMPROTECT, P_PAXNOMPROTECT,
 	PK_SYSTRACE, P_SYSTRACE,
 	PK_SUGID, P_SUGID,
 	0
Index: sys/kern/kern_exec.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_exec.c,v
retrieving revision 1.258
diff -u -u -r1.258 kern_exec.c
--- sys/kern/kern_exec.c	20 Dec 2007 23:03:08 -0000	1.258
+++ sys/kern/kern_exec.c	24 Dec 2007 03:42:48 -0000
@@ -63,6 +63,7 @@
 #include <sys/syscall.h>
 #include <sys/kauth.h>
 #include <sys/lwpctl.h>
+#include <sys/pax.h>
 
 #include <sys/syscallargs.h>
 #if NVERIEXEC > 0
@@ -73,9 +74,6 @@
 #include <sys/systrace.h>
 #endif /* SYSTRACE */
 
-#ifdef PAX_SEGVGUARD
-#include <sys/pax.h>
-#endif /* PAX_SEGVGUARD */
 
 #include <uvm/uvm_extern.h>
 
@@ -297,6 +295,10 @@
 		goto bad2;
 	epp->ep_hdrvalid = epp->ep_hdrlen - resid;
 
+	/* XXX elad */
+	/* Generate random seed to be used. */
+	epp->ep_random = arc4random();
+
 	/*
 	 * Set up default address space limits.  Can be overridden
 	 * by individual exec packages.
@@ -495,7 +497,8 @@
 
 	/* see if we can run it. */
 	if ((error = check_exec(l, &pack)) != 0) {
-		DPRINTF(("execve: check exec failed %d\n", error));
+		if (error != ENOENT)
+			DPRINTF(("execve: check exec failed %d\n", error));
 		goto freehdr;
 	}
 
@@ -659,6 +662,10 @@
 	vm->vm_maxsaddr = (void *)pack.ep_maxsaddr;
 	vm->vm_minsaddr = (void *)pack.ep_minsaddr;
 
+#ifdef PAX_ASLR
+	pax_aslr_init(l, vm);
+#endif /* PAX_ASLR */
+
 	/* create the new process's VM space by running the vmcmds */
 #ifdef DIAGNOSTIC
 	if (pack.ep_vmcmds.evs_used == 0)
Index: sys/kern/kern_pax.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_pax.c,v
retrieving revision 1.17
diff -u -u -r1.17 kern_pax.c
--- sys/kern/kern_pax.c	21 Sep 2007 19:14:12 -0000	1.17
+++ sys/kern/kern_pax.c	24 Dec 2007 03:42:48 -0000
@@ -44,12 +44,26 @@
 #include <sys/queue.h>
 #include <sys/kauth.h>
 
+#ifdef PAX_ASLR
+#include <sys/mman.h>
+#include <sys/rnd.h>
+
+int pax_aslr_enabled = 1;
+int pax_aslr_global = PAX_ASLR;
+
+specificdata_key_t pax_aslr_key;
+
+#define PAX_ASLR_DELTA_MMAP_LSB	PGSHIFT
+#define PAX_ASLR_DELTA_MMAP_LEN	((sizeof(void *) * NBBY) / 2)
+
+#endif /* PAX_ASLR */
+
 #ifdef PAX_MPROTECT
 static int pax_mprotect_enabled = 1;
 static int pax_mprotect_global = PAX_MPROTECT;
 
 specificdata_key_t pax_mprotect_key;
-#endif
+#endif /* PAX_MPROTECT */
 
 #ifdef PAX_SEGVGUARD
 #ifndef PAX_SEGVGUARD_EXPIRY
@@ -93,6 +107,8 @@
 #define	PAX_MPROTECT_EXPLICIT_DISABLE	(void *)0x02
 #define	PAX_SEGVGUARD_EXPLICIT_ENABLE	(void *)0x03
 #define	PAX_SEGVGUARD_EXPLICIT_DISABLE	(void *)0x04
+#define	PAX_ASLR_EXPLICIT_ENABLE	(void *)0x05
+#define	PAX_ASLR_EXPLICIT_DISABLE	(void *)0x06
 
 SYSCTL_SETUP(sysctl_security_pax_setup, "sysctl security.pax setup")
 {
@@ -111,9 +127,8 @@
 		       NULL, 0, NULL, 0,
 		       CTL_CREATE, CTL_EOL);
 
-	cnode = rnode;
-
 #ifdef PAX_MPROTECT
+	cnode = rnode;
 	sysctl_createv(clog, 0, &rnode, &rnode,
 		       CTLFLAG_PERMANENT,
 		       CTLTYPE_NODE, "mprotect",
@@ -136,9 +151,8 @@
 		       CTL_CREATE, CTL_EOL);
 #endif /* PAX_MPROTECT */
 
-	rnode = cnode;
-
 #ifdef PAX_SEGVGUARD
+	rnode = cnode;
 	sysctl_createv(clog, 0, &rnode, &rnode,
 		       CTLFLAG_PERMANENT,
 		       CTLTYPE_NODE, "segvguard",
@@ -176,6 +190,36 @@
 		       NULL, 0, &pax_segvguard_maxcrashes, 0,
 		       CTL_CREATE, CTL_EOL);
 #endif /* PAX_SEGVGUARD */
+
+#ifdef PAX_ASLR
+	rnode = cnode;
+	sysctl_createv(clog, 0, &rnode, &rnode,
+		       CTLFLAG_PERMANENT,
+		       CTLTYPE_NODE, "aslr",
+		       SYSCTL_DESCR("Address Space Layout Randomization."),
+		       NULL, 0, NULL, 0,
+		       CTL_CREATE, CTL_EOL);
+	sysctl_createv(clog, 0, &rnode, NULL,
+		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
+		       CTLTYPE_INT, "enabled",
+		       SYSCTL_DESCR("Restrictions enabled."),
+		       NULL, 0, &pax_aslr_enabled, 0,
+		       CTL_CREATE, CTL_EOL);
+	sysctl_createv(clog, 0, &rnode, NULL,
+		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
+		       CTLTYPE_INT, "global_protection",
+		       SYSCTL_DESCR("When enabled, unless explicitly "
+				    "specified, apply to all processes."),
+		       NULL, 0, &pax_aslr_global, 0,
+		       CTL_CREATE, CTL_EOL);
+	sysctl_createv(clog, 0, &rnode, NULL,
+		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
+		       CTLTYPE_INT, "mmap_len",
+		       SYSCTL_DESCR("Number of bytes randomized for "
+				    "mmap(2) calls."),
+		       NULL, PAX_ASLR_DELTA_MMAP_LEN, NULL, 0,
+		       CTL_CREATE, CTL_EOL);
+#endif /* PAX_ASLR */
 }
 
 /*
@@ -188,6 +232,10 @@
 	int error;
 #endif /* PAX_SEGVGUARD */
 
+#ifdef PAX_ASLR
+	proc_specific_key_create(&pax_aslr_key, NULL);
+#endif /* PAX_ASLR */
+
 #ifdef PAX_MPROTECT
 	proc_specific_key_create(&pax_mprotect_key, NULL);
 #endif /* PAX_MPROTECT */
@@ -226,6 +274,17 @@
 			    PAX_SEGVGUARD_EXPLICIT_DISABLE);
 	}
 #endif /* PAX_SEGVGUARD */
+
+#ifdef PAX_ASLR
+	if (pax_aslr_enabled) {
+		if (f & ELF_NOTE_PAX_ASLR)
+			proc_setspecific(l->l_proc, pax_aslr_key,
+			    PAX_ASLR_EXPLICIT_ENABLE);
+		if (f & ELF_NOTE_PAX_NOASLR)
+			proc_setspecific(l->l_proc, pax_aslr_key,
+			    PAX_ASLR_EXPLICIT_DISABLE);
+	}
+#endif /* PAX_ASLR */
 }
 
 #ifdef PAX_MPROTECT
@@ -252,6 +311,58 @@
 }
 #endif /* PAX_MPROTECT */
 
+#ifdef PAX_ASLR
+bool
+pax_aslr_active(struct lwp *l)
+{
+	void *t;
+	if (!pax_aslr_enabled)
+		return false;
+
+	t = proc_getspecific(l->l_proc, pax_aslr_key);
+	if ((pax_aslr_global && t == PAX_ASLR_EXPLICIT_DISABLE) ||
+	    (!pax_aslr_global && t != PAX_ASLR_EXPLICIT_ENABLE))
+		return false;
+	return true;
+}
+
+void
+pax_aslr_init(struct lwp *l, struct vmspace *vm)
+{
+	if (!pax_aslr_active(l))
+		return;
+
+	vm->vm_aslr_delta_mmap = PAX_ASLR_DELTA(arc4random(),
+	    PAX_ASLR_DELTA_MMAP_LSB, PAX_ASLR_DELTA_MMAP_LEN);
+}
+
+void
+pax_aslr(struct lwp *l, vaddr_t *addr, vaddr_t orig_addr, int f)
+{
+	if (!pax_aslr_active(l))
+		return;
+
+	if (!(f & MAP_FIXED) && ((orig_addr == 0) || !(f & MAP_ANON))) {
+#ifdef DEBUG_ASLR
+		uprintf("applying to 0x%lx orig_addr=0x%lx f=%x\n",
+		    (unsigned long)*addr, (unsigned long)orig_addr, f);
+#endif
+		if (!(l->l_proc->p_vmspace->vm_map.flags & VM_MAP_TOPDOWN))
+			*addr += l->l_proc->p_vmspace->vm_aslr_delta_mmap;
+		else
+			*addr -= l->l_proc->p_vmspace->vm_aslr_delta_mmap;
+#ifdef DEBUG_ASLR
+		uprintf("result 0x%lx\n", *addr);
+#endif
+	}
+#ifdef DEBUG_ASLR
+	else
+	    uprintf("not applying to 0x%lx orig_addr=0x%lx f=%x\n",
+		(unsigned long)*addr, (unsigned long)orig_addr, f);
+#endif
+}
+#endif /* PAX_ASLR */
+
 #ifdef PAX_SEGVGUARD
 static void
 pax_segvguard_cb(void *v)
Index: sys/kern/kern_sig.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_sig.c,v
retrieving revision 1.262
diff -u -u -r1.262 kern_sig.c
--- sys/kern/kern_sig.c	5 Dec 2007 07:06:53 -0000	1.262
+++ sys/kern/kern_sig.c	24 Dec 2007 03:42:49 -0000
@@ -730,7 +730,7 @@
 	 * the main context stack.
 	 */
 	if ((l->l_sigstk.ss_flags & SS_ONSTACK) == 0) {
-		ucp->uc_stack.ss_sp = (void *)USRSTACK;
+		ucp->uc_stack.ss_sp = (void *)l->l_proc->p_stackbase;
 		ucp->uc_stack.ss_size = ctob(l->l_proc->p_vmspace->vm_ssize);
 		ucp->uc_stack.ss_flags = 0;	/* XXX, def. is Very Fishy */
 	} else {
Index: sys/sys/exec.h
===================================================================
RCS file: /cvsroot/src/sys/sys/exec.h,v
retrieving revision 1.118
diff -u -u -r1.118 exec.h
--- sys/sys/exec.h	3 Dec 2007 02:06:58 -0000	1.118
+++ sys/sys/exec.h	24 Dec 2007 03:42:50 -0000
@@ -203,6 +203,7 @@
 	struct vnode *ep_interp;        /* vnode of (elf) interpeter */
 	uint32_t ep_pax_flags;		/* pax flags */
 	char	*ep_path;		/* absolute path of executable */
+	uint32_t ep_random;		/* random seed for PAX_ASLR */
 };
 #define	EXEC_INDIR	0x0001		/* script handling already done */
 #define	EXEC_HASFD	0x0002		/* holding a shell script */
Index: sys/sys/exec_elf.h
===================================================================
RCS file: /cvsroot/src/sys/sys/exec_elf.h,v
retrieving revision 1.93
diff -u -u -r1.93 exec_elf.h
--- sys/sys/exec_elf.h	7 Dec 2007 20:34:06 -0000	1.93
+++ sys/sys/exec_elf.h	24 Dec 2007 03:42:51 -0000
@@ -695,10 +695,12 @@
 /* NetBSD-specific note type: PaX.  There should be 1 NOTE per executable.
    section.  desc is a 32 bit bitmask */
 #define ELF_NOTE_TYPE_PAX_TAG		3
-#define	ELF_NOTE_PAX_MPROTECT		0x1	/* Force enable Mprotect */
-#define	ELF_NOTE_PAX_NOMPROTECT		0x2	/* Force disable Mprotect */
-#define	ELF_NOTE_PAX_GUARD		0x4	/* Force enable Segvguard */
-#define	ELF_NOTE_PAX_NOGUARD		0x8	/* Force disable Servguard */
+#define	ELF_NOTE_PAX_MPROTECT		0x01	/* Force enable Mprotect */
+#define	ELF_NOTE_PAX_NOMPROTECT		0x02	/* Force disable Mprotect */
+#define	ELF_NOTE_PAX_GUARD		0x04	/* Force enable Segvguard */
+#define	ELF_NOTE_PAX_NOGUARD		0x08	/* Force disable Servguard */
+#define	ELF_NOTE_PAX_ASLR		0x10	/* Force enable ASLR */
+#define	ELF_NOTE_PAX_NOASLR		0x20	/* Force disable ASLR */
 #define ELF_NOTE_PAX_NAMESZ		4
 #define ELF_NOTE_PAX_NAME		"PaX\0"
 #define ELF_NOTE_PAX_DESCSZ		4
Index: sys/sys/pax.h
===================================================================
RCS file: /cvsroot/src/sys/sys/pax.h,v
retrieving revision 1.9
diff -u -u -r1.9 pax.h
--- sys/sys/pax.h	24 Jun 2007 20:35:37 -0000	1.9
+++ sys/sys/pax.h	24 Dec 2007 03:42:51 -0000
@@ -27,8 +27,8 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef __SYS_PAX_H__
-#define	__SYS_PAX_H__
+#ifndef _SYS_PAX_H_
+#define _SYS_PAX_H_
 
 #include <uvm/uvm_extern.h>
 
@@ -38,8 +38,12 @@
 void pax_adjust(struct lwp *, uint32_t);
 
 void pax_mprotect(struct lwp *, vm_prot_t *, vm_prot_t *);
-
 int pax_segvguard(struct lwp *, struct vnode *, const char *, bool);
 
-#endif /* !__SYS_PAX_H__ */
+#define	PAX_ASLR_DELTA(delta, lsb, len)	\
+    (((delta) & ((1UL << (len)) - 1)) << (lsb))
+bool pax_aslr_active(struct lwp *);
+void pax_aslr_init(struct lwp *, struct vmspace *);
+void pax_aslr(struct lwp *, vaddr_t *, vaddr_t, int);
 
+#endif /* !_SYS_PAX_H_ */
Index: sys/sys/proc.h
===================================================================
RCS file: /cvsroot/src/sys/sys/proc.h,v
retrieving revision 1.263
diff -u -u -r1.263 proc.h
--- sys/sys/proc.h	22 Dec 2007 01:14:53 -0000	1.263
+++ sys/sys/proc.h	24 Dec 2007 03:42:51 -0000
@@ -331,6 +331,7 @@
 	u_short		p_xstat;	/* s: Exit status for wait; also stop signal */
 	u_short		p_acflag;	/* p: Acc. flags; see struct lwp also */
 	struct mdproc	p_md;		/*    Any machine-dependent fields */
+	vaddr_t		p_stackbase;	/*    ASLR randomized stack base */
 };
 
 #define	p_rlimit	p_limit->pl_rlimit
@@ -362,8 +363,6 @@
 #define	PK_32		0x00040000 /* 32-bit process (used on 64-bit kernels) */
 #define	PK_CLDSIGIGN	0x00080000 /* Process is ignoring SIGCHLD */
 #define	PK_SYSTRACE	0x00200000 /* Process system call tracing active */
-#define	PK_PAXMPROTECT 	0x08000000 /* Explicitly enable PaX MPROTECT */
-#define	PK_PAXNOMPROTECT	0x10000000 /* Explicitly disable PaX MPROTECT */
 #define	PK_MARKER	0x80000000 /* Is a dummy marker process */
 
 /*
Index: sys/uvm/uvm_extern.h
===================================================================
RCS file: /cvsroot/src/sys/uvm/uvm_extern.h,v
retrieving revision 1.140
diff -u -u -r1.140 uvm_extern.h
--- sys/uvm/uvm_extern.h	13 Dec 2007 02:45:11 -0000	1.140
+++ sys/uvm/uvm_extern.h	24 Dec 2007 03:42:52 -0000
@@ -498,6 +498,7 @@
 	void *	vm_daddr;	/* user virtual address of data XXX */
 	void *vm_maxsaddr;	/* user VA at max stack growth */
 	void *vm_minsaddr;	/* user VA at top of stack */
+	size_t vm_aslr_delta_mmap;	/* mmap() random delta for ASLR */
 };
 #define	VMSPACE_IS_KERNEL_P(vm)	VM_MAP_IS_KERNEL(&(vm)->vm_map)
 
Index: sys/uvm/uvm_mmap.c
===================================================================
RCS file: /cvsroot/src/sys/uvm/uvm_mmap.c,v
retrieving revision 1.119
diff -u -u -r1.119 uvm_mmap.c
--- sys/uvm/uvm_mmap.c	20 Dec 2007 23:03:14 -0000	1.119
+++ sys/uvm/uvm_mmap.c	24 Dec 2007 03:42:52 -0000
@@ -312,6 +312,9 @@
 	struct vnode *vp;
 	void *handle;
 	int error;
+#ifdef PAX_ASLR
+	vaddr_t orig_addr;
+#endif /* PAX_ASLR */
 
 	/*
 	 * first, extract syscall args from the uap.
@@ -324,6 +327,10 @@
 	fd = SCARG(uap, fd);
 	pos = SCARG(uap, pos);
 
+#ifdef PAX_ASLR
+	orig_addr = addr;
+#endif /* PAX_ASLR */
+
 	/*
 	 * Fixup the old deprecated MAP_COPY into MAP_PRIVATE, and
 	 * validate the flags.
@@ -551,6 +558,10 @@
 	pax_mprotect(l, &prot, &maxprot);
 #endif /* PAX_MPROTECT */
 
+#ifdef PAX_ASLR
+	pax_aslr(l, &addr, orig_addr, flags);
+#endif /* PAX_ASLR */
+
 	/*
 	 * now let kernel internal function uvm_mmap do the work.
 	 */