Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 22 Jun 2014 09:37:40 -0400
From:      Shawn Webb <lattera@gmail.com>
To:        freebsd-current@freebsd.org
Subject:   [CFT] New Round of ASLR Patches
Message-ID:  <20140622133740.GD1824@pwnie.vrt.sourcefire.com>

next in thread | raw e-mail | index | archive | help

--S5HS5MvDw4DmbRmb
Content-Type: multipart/mixed; boundary="yRA+Bmk8aPhU85Qt"
Content-Disposition: inline


--yRA+Bmk8aPhU85Qt
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hey All,

Attached is a new patch with the latest work regarding our ASLR
implementation. Here's what has changed since the last patch distributed
on 24 May 2014:

Shawn Webb:
Sat Jun 21 20:03:07 2014 -0400: PAX SEGVGUARD: Remove segvguard prior to
putting in a separate feature branch
Thu Jun 19 21:08:37 2014 -0400: PAX ASLR: More style(9) fixes
Thu Jun 19 20:59:44 2014 -0400: PAX ASLR: Add PAX_SYSCTLS to
sys/conf/NOTES
Thu Jun 19 20:48:42 2014 -0400: PAX ASLR: Remove extra NO_PIE/MK_PIE
entries that aren't now needed
Wed Jun 11 22:07:51 2014 -0400: PAX ASLR: Rollback code cleanup that
removed orig_addr from pax_aslr_mmap().
Wed Jun 11 17:54:12 2014 -0400: PAX ASLR: style(9) changes. Grammar
fixes. Code cleanup.
Fri May 30 18:36:49 2014 -0400: PAX ASLR: Pull in Oliver Pinter's change
to add stack randomization
Fri May 30 18:36:01 2014 -0400: Update copyright

Oliver Pinter:
Wed Jun 4 09:39:48 2014 +0200: PAX ASLR: added FEATURE(aslr, ...) to the
kernel, and modify ugidfw to use them
Wed May 28 00:27:06 2014 +0200: PAX: fix prison0 initialization after my
jail modifications
Sun May 25 21:20:23 2014 +0200: PAX: show pax settings in dmesg, and
validate some value
Sun May 25 19:48:44 2014 +0200: PAX ASLR: make security.pax.aslr sysctls
optional
Sun May 25 19:15:16 2014 +0200: PAX: check proc->p_ucred
Sun May 25 19:11:50 2014 +0200: PAX: added PAX_SYSCTLS kernel option
Sun May 25 19:10:16 2014 +0200: PAX ASLR: simplify jail handling
Sun May 25 19:00:12 2014 +0200: PAX: hook in pax_init_prison at
kern_jail_set

Thanks,

Shawn

--yRA+Bmk8aPhU85Qt
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="2014-06-21_aslr.patch"
Content-Transfer-Encoding: quoted-printable

diff --git a/lib/libugidfw/ugidfw.c b/lib/libugidfw/ugidfw.c
index 0dc423d..a4a38bc 100644
--- a/lib/libugidfw/ugidfw.c
+++ b/lib/libugidfw/ugidfw.c
@@ -36,6 +36,9 @@
 #include <sys/sysctl.h>
 #include <sys/ucred.h>
 #include <sys/mount.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/sysctl.h>
=20
 #include <security/mac_bsdextended/mac_bsdextended.h>
=20
@@ -44,6 +47,8 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
=20
 #include "ugidfw.h"
=20
@@ -329,14 +334,19 @@ bsde_rule_to_string(struct mac_bsdextended_rule *rule=
, char *buf, size_t buflen)
 			cur +=3D len;
 		}
 		if (rule->mbr_object.mbo_flags & MBO_FSID_DEFINED) {
-			numfs =3D getmntinfo(&mntbuf, MNT_NOWAIT);
-			for (i =3D 0; i < numfs; i++)
-				if (memcmp(&(rule->mbr_object.mbo_fsid),
-				    &(mntbuf[i].f_fsid),
-				    sizeof(mntbuf[i].f_fsid)) =3D=3D 0)
-					break;
-			len =3D snprintf(cur, left, "filesys %s ",
-			    i =3D=3D numfs ? "???" : mntbuf[i].f_mntonname);
+			if (rule->mbr_object.mbo_inode =3D=3D 0) {
+				numfs =3D getmntinfo(&mntbuf, MNT_NOWAIT);
+				for (i =3D 0; i < numfs; i++)
+					if (memcmp(&(rule->mbr_object.mbo_fsid),
+					    &(mntbuf[i].f_fsid),
+					    sizeof(mntbuf[i].f_fsid)) =3D=3D 0)
+						break;
+				len =3D snprintf(cur, left, "filesys %s ",
+				    i =3D=3D numfs ? "???" : mntbuf[i].f_mntonname);
+			} else {
+				len =3D snprintf(cur, left, "filesys %s ",
+				    rule->mbr_object.mbo_paxpath);
+			}
 			if (len < 0 || len > left)
 				goto truncated;
 			left -=3D len;
@@ -500,6 +510,33 @@ bsde_rule_to_string(struct mac_bsdextended_rule *rule,=
 char *buf, size_t buflen)
 		cur +=3D len;
 	}
=20
+	if (rule->mbr_pax) {
+		len =3D snprintf(cur, left, " paxflags ");
+		if (len < 0 || len > left)
+			goto truncated;
+		left -=3D len;
+		cur +=3D len;
+
+		if (rule->mbr_pax & MBI_FORCE_ASLR_ENABLED) {
+			len =3D snprintf(cur, left, "A");
+			if (len < 0 || len > left)
+				goto truncated;
+
+			left -=3D len;
+			cur +=3D len;
+		}
+
+		if (rule->mbr_pax & MBI_FORCE_ASLR_DISABLED) {
+			len =3D snprintf(cur, left, "a");
+			if (len < 0 || len > left)
+				goto truncated;
+
+			left -=3D len;
+			cur +=3D len;
+		}
+
+	}
+
 	return (0);
=20
 truncated:
@@ -507,8 +544,8 @@ truncated:
 }
=20
 int
-bsde_parse_uidrange(char *spec, uid_t *min, uid_t *max,
-    size_t buflen, char *errstr){
+bsde_parse_uidrange(char *spec, uid_t *min, uid_t *max, size_t buflen, cha=
r *errstr)
+{
 	struct passwd *pwd;
 	uid_t uid1, uid2;
 	char *spec1, *spec2, *endp;
@@ -556,8 +593,8 @@ bsde_parse_uidrange(char *spec, uid_t *min, uid_t *max,
 }
=20
 int
-bsde_parse_gidrange(char *spec, gid_t *min, gid_t *max,
-    size_t buflen, char *errstr){
+bsde_parse_gidrange(char *spec, gid_t *min, gid_t *max, size_t buflen, cha=
r *errstr)
+{
 	struct group *grp;
 	gid_t gid1, gid2;
 	char *spec1, *spec2, *endp;
@@ -766,10 +803,15 @@ bsde_parse_type(char *spec, int *type, size_t buflen,=
 char *errstr)
 }
=20
 int
-bsde_parse_fsid(char *spec, struct fsid *fsid, size_t buflen, char *errstr)
+bsde_parse_fsid(char *spec, struct fsid *fsid, ino_t *inode, size_t buflen=
, char *errstr)
 {
 	size_t len;
 	struct statfs buf;
+	struct stat sb;
+	int fd, paxstatus;
+	size_t bufsz;
+
+	*inode =3D 0;
=20
 	if (statfs(spec, &buf) < 0) {
 		len =3D snprintf(errstr, buflen, "Unable to get id for %s: %s",
@@ -779,6 +821,21 @@ bsde_parse_fsid(char *spec, struct fsid *fsid, size_t =
buflen, char *errstr)
=20
 	*fsid =3D buf.f_fsid;
=20
+	if (strcmp(buf.f_fstypename, "devfs") !=3D 0) {
+		bufsz =3D sizeof(int);
+		if (!sysctlbyname("kern.features.aslr", &paxstatus, &bufsz,
+		    NULL, 0)) {
+			fd =3D open(spec, O_RDONLY);
+			if (fd !=3D -1) {
+				if (fstat(fd, &sb) =3D=3D 0)
+					if(S_ISDIR(sb.st_mode) =3D=3D 0)
+						*inode =3D sb.st_ino;
+
+				close(fd);
+			}
+		}
+	}
+
 	return (0);
 }
=20
@@ -852,13 +909,18 @@ bsde_parse_object(int argc, char *argv[],
 				return (-1);
 			}
 			if (bsde_parse_fsid(argv[current+1], &fsid,
-			    buflen, errstr) < 0)
+			    &object->mbo_inode, buflen, errstr) < 0)
 				return (-1);
 			flags |=3D MBO_FSID_DEFINED;
 			if (nextnot) {
 				neg ^=3D MBO_FSID_DEFINED;
 				nextnot =3D 0;
 			}
+			if (object->mbo_inode)
+				snprintf(object->mbo_paxpath, MAXPATHLEN, "%s",
+				    argv[current+1]);
+			else
+				memset(object->mbo_paxpath, 0x00, MAXPATHLEN);
 			current +=3D 2;
 		} else if (strcmp(argv[current], "suid") =3D=3D 0) {
 			flags |=3D MBO_SUID;
@@ -991,12 +1053,48 @@ bsde_parse_mode(int argc, char *argv[], mode_t *mode=
, size_t buflen,
 }
=20
 int
+bsde_parse_paxflags(int argc, char *argv[], uint32_t *pax, size_t buflen, =
char *errstr)
+{
+	size_t len;
+	int i;
+
+	if (argc =3D=3D 0) {
+		len =3D snprintf(errstr, buflen, "paxflags expects mode value");
+		return (-1);
+	}
+
+	if (argc !=3D 1) {
+		len =3D snprintf(errstr, buflen, "'%s' unexpected", argv[1]);
+		return (-1);
+	}
+
+	*pax =3D 0;
+	for (i =3D 0; i < strlen(argv[0]); i++) {
+		switch (argv[0][i]) {
+		case 'A':
+			*pax |=3D MBI_FORCE_ASLR_ENABLED;
+			break;
+		case 'a':
+			*pax |=3D MBI_FORCE_ASLR_DISABLED;
+			break;
+		default:
+			len =3D snprintf(errstr, buflen, "Unknown mode letter: %c",
+			    argv[0][i]);
+			return (-1);
+		}=20
+	}
+
+	return (0);
+}
+
+int
 bsde_parse_rule(int argc, char *argv[], struct mac_bsdextended_rule *rule,
     size_t buflen, char *errstr)
 {
 	int subject, subject_elements, subject_elements_length;
 	int object, object_elements, object_elements_length;
 	int mode, mode_elements, mode_elements_length;
+	int paxflags, paxflags_elements, paxflags_elements_length=3D0;
 	int error, i;
 	size_t len;
=20
@@ -1037,11 +1135,23 @@ bsde_parse_rule(int argc, char *argv[], struct mac_=
bsdextended_rule *rule,
 		return (-1);
 	}
=20
+	/* Search forward for paxflags */
+	paxflags =3D -1;
+	for (i =3D 1; i < argc; i++)
+		if (strcmp(argv[i], "paxflags") =3D=3D 0)
+			paxflags =3D i;
+
+	if (paxflags >=3D 0) {
+		paxflags_elements =3D paxflags + 1;
+		paxflags_elements_length =3D argc - paxflags_elements;
+	}
+
 	subject_elements_length =3D object - subject - 1;
 	object_elements =3D object + 1;
 	object_elements_length =3D mode - object_elements;
 	mode_elements =3D mode + 1;
-	mode_elements_length =3D argc - mode_elements;
+	mode_elements_length =3D argc - mode_elements -
+	    (paxflags_elements_length ? paxflags_elements_length+1 : 0);
=20
 	error =3D bsde_parse_subject(subject_elements_length,
 	    argv + subject_elements, &rule->mbr_subject, buflen, errstr);
@@ -1058,6 +1168,13 @@ bsde_parse_rule(int argc, char *argv[], struct mac_b=
sdextended_rule *rule,
 	if (error)
 		return (-1);
=20
+	if (paxflags >=3D 0) {
+		error =3D bsde_parse_paxflags(paxflags_elements_length, argv + paxflags_=
elements,
+				&rule->mbr_pax, buflen, errstr);
+		if (error)
+			return (-1);
+	}
+
 	return (0);
 }
=20
diff --git a/lib/libugidfw/ugidfw.h b/lib/libugidfw/ugidfw.h
index 5b7fcf2..cef469c 100644
--- a/lib/libugidfw/ugidfw.h
+++ b/lib/libugidfw/ugidfw.h
@@ -39,6 +39,8 @@ int	bsde_rule_to_string(struct mac_bsdextended_rule *rule=
, char *buf,
 	    size_t buflen);
 int	bsde_parse_mode(int argc, char *argv[], mode_t *mode, size_t buflen,
 	    char *errstr);
+int	bsde_parse_paxflags(int argc, char *argv[], uint32_t *pax, size_t bufl=
en,
+	    char *errstr);
 int	bsde_parse_rule(int argc, char *argv[],
 	    struct mac_bsdextended_rule *rule, size_t buflen, char *errstr);
 int	bsde_parse_rule_string(const char *string,
diff --git a/sys/amd64/amd64/elf_machdep.c b/sys/amd64/amd64/elf_machdep.c
index fdc4d56..ffb5e31 100644
--- a/sys/amd64/amd64/elf_machdep.c
+++ b/sys/amd64/amd64/elf_machdep.c
@@ -26,12 +26,17 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
=20
+#include "opt_pax.h"
+
 #include <sys/param.h>
 #include <sys/kernel.h>
 #include <sys/systm.h>
 #include <sys/exec.h>
 #include <sys/imgact.h>
 #include <sys/linker.h>
+#ifdef PAX_ASLR
+#include <sys/pax.h>
+#endif
 #include <sys/proc.h>
 #include <sys/sysent.h>
 #include <sys/imgact_elf.h>
@@ -81,6 +86,11 @@ struct sysentvec elf64_freebsd_sysvec =3D {
 	.sv_shared_page_base =3D SHAREDPAGE,
 	.sv_shared_page_len =3D PAGE_SIZE,
 	.sv_schedtail	=3D NULL,
+#ifdef PAX_ASLR
+	.sv_pax_aslr_init =3D _pax_aslr_init,
+#else
+	.sv_pax_aslr_init =3D NULL,
+#endif
 };
 INIT_SYSENTVEC(elf64_sysvec, &elf64_freebsd_sysvec);
=20
diff --git a/sys/amd64/include/vmparam.h b/sys/amd64/include/vmparam.h
index bda9722..5e83a8f 100644
--- a/sys/amd64/include/vmparam.h
+++ b/sys/amd64/include/vmparam.h
@@ -170,7 +170,7 @@
 #define	VM_MAXUSER_ADDRESS	UVADDR(NUPML4E, 0, 0, 0)
=20
 #define	SHAREDPAGE		(VM_MAXUSER_ADDRESS - PAGE_SIZE)
-#define	USRSTACK		SHAREDPAGE
+#define	USRSTACK		(SHAREDPAGE - 4*PAGE_SIZE)
=20
 #define	VM_MAX_ADDRESS		UPT_MAX_ADDRESS
 #define	VM_MIN_ADDRESS		(0)
diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32=
_sysvec.c
index c06ce11..f4f99f58 100644
--- a/sys/amd64/linux32/linux32_sysvec.c
+++ b/sys/amd64/linux32/linux32_sysvec.c
@@ -33,6 +33,7 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 #include "opt_compat.h"
+#include "opt_pax.h"
=20
 #ifndef COMPAT_FREEBSD32
 #error "Unable to compile Linux-emulator due to missing COMPAT_FREEBSD32 o=
ption!"
@@ -84,6 +85,10 @@ __FBSDID("$FreeBSD$");
 #include <compat/linux/linux_signal.h>
 #include <compat/linux/linux_util.h>
=20
+#ifdef PAX_ASLR
+#include <sys/pax.h>
+#endif
+
 MODULE_VERSION(linux, 1);
=20
 MALLOC_DEFINE(M_LINUX, "linux", "Linux mode structures");
@@ -1037,6 +1042,11 @@ struct sysentvec elf_linux_sysvec =3D {
 	.sv_shared_page_base =3D LINUX32_SHAREDPAGE,
 	.sv_shared_page_len =3D PAGE_SIZE,
 	.sv_schedtail	=3D linux_schedtail,
+#ifdef PAX_ASLR
+	.sv_pax_aslr_init =3D _pax_aslr_init32,
+#else
+	.sv_pax_aslr_init =3D NULL,
+#endif
 };
 INIT_SYSENTVEC(elf_sysvec, &elf_linux_sysvec);
=20
diff --git a/sys/arm/arm/elf_machdep.c b/sys/arm/arm/elf_machdep.c
index 8ef9bd4..26e37e6 100644
--- a/sys/arm/arm/elf_machdep.c
+++ b/sys/arm/arm/elf_machdep.c
@@ -26,6 +26,8 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
=20
+#include "opt_pax.h"
+
 #include <sys/param.h>
 #include <sys/kernel.h>
 #include <sys/systm.h>
@@ -46,6 +48,10 @@ __FBSDID("$FreeBSD$");
 #include <machine/elf.h>
 #include <machine/md_var.h>
=20
+#ifdef PAX_ASLR
+#include <sys/pax.h>
+#endif
+
 struct sysentvec elf32_freebsd_sysvec =3D {
 	.sv_size	=3D SYS_MAXSYSCALL,
 	.sv_table	=3D sysent,
@@ -79,6 +85,11 @@ struct sysentvec elf32_freebsd_sysvec =3D {
 	.sv_fetch_syscall_args =3D cpu_fetch_syscall_args,
 	.sv_syscallnames =3D syscallnames,
 	.sv_schedtail	=3D NULL,
+#ifdef PAX_ASLR
+	.sv_pax_aslr_init =3D _pax_aslr_init,
+#else
+	.sv_pax_aslr_init =3D NULL,
+#endif
 };
=20
 static Elf32_Brandinfo freebsd_brand_info =3D {
diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/f=
reebsd32_misc.c
index 68e761b..96a81d9 100644
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$");
 #include "opt_compat.h"
 #include "opt_inet.h"
 #include "opt_inet6.h"
+#include "opt_pax.h"
=20
 #define __ELF_WORD_SIZE 32
=20
@@ -113,6 +114,10 @@ __FBSDID("$FreeBSD$");
=20
 FEATURE(compat_freebsd_32bit, "Compatible with 32-bit FreeBSD");
=20
+#ifdef PAX_ASLR
+#include <sys/pax.h>
+#endif
+
 #ifndef __mips__
 CTASSERT(sizeof(struct timeval32) =3D=3D 8);
 CTASSERT(sizeof(struct timespec32) =3D=3D 8);
@@ -2886,6 +2891,10 @@ freebsd32_copyout_strings(struct image_params *imgp)
 		szsigcode =3D 0;
 	destp =3D	(uintptr_t)arginfo;
=20
+#ifdef PAX_ASLR
+	pax_aslr_stack(curthread, &destp);
+#endif
+
 	/*
 	 * install sigcode
 	 */
diff --git a/sys/compat/ia32/ia32_sysvec.c b/sys/compat/ia32/ia32_sysvec.c
index a8e52e8..ade8da5 100644
--- a/sys/compat/ia32/ia32_sysvec.c
+++ b/sys/compat/ia32/ia32_sysvec.c
@@ -29,6 +29,7 @@
 __FBSDID("$FreeBSD$");
=20
 #include "opt_compat.h"
+#include "opt_pax.h"
=20
 #define __ELF_WORD_SIZE 32
=20
@@ -74,6 +75,10 @@ __FBSDID("$FreeBSD$");
 #include <machine/pcb.h>
 #include <machine/cpufunc.h>
=20
+#ifdef PAX_ASLR
+#include <sys/pax.h>
+#endif
+
 CTASSERT(sizeof(struct ia32_mcontext) =3D=3D 640);
 CTASSERT(sizeof(struct ia32_ucontext) =3D=3D 704);
 CTASSERT(sizeof(struct ia32_sigframe) =3D=3D 800);
@@ -139,6 +144,11 @@ struct sysentvec ia32_freebsd_sysvec =3D {
 	.sv_shared_page_base =3D FREEBSD32_SHAREDPAGE,
 	.sv_shared_page_len =3D PAGE_SIZE,
 	.sv_schedtail	=3D NULL,
+#ifdef PAX_ASLR
+	.sv_pax_aslr_init =3D _pax_aslr_init32,
+#else
+	.sv_pax_aslr_init =3D NULL,
+#endif
 };
 INIT_SYSENTVEC(elf_ia32_sysvec, &ia32_freebsd_sysvec);
=20
diff --git a/sys/conf/NOTES b/sys/conf/NOTES
index 4d27713..671ef83 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -2972,3 +2972,7 @@ options 	RANDOM_RWFILE	# Read and write entropy cache
=20
 # Module to enable execution of application via emulators like QEMU
 options         IMAGACT_BINMISC
+
+# Address Space Layout Randomization (ASLR)
+options		PAX_ASLR
+options		PAX_SYSCTLS
diff --git a/sys/conf/files b/sys/conf/files
index cc907c50..1e73c88 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -2907,6 +2907,9 @@ kern/kern_mtxpool.c		standard
 kern/kern_mutex.c		standard
 kern/kern_ntptime.c		standard
 kern/kern_osd.c			standard
+kern/kern_pax.c			optional pax_aslr
+kern/kern_pax_aslr.c		optional pax_aslr
+kern/kern_pax_log.c		optional pax_aslr
 kern/kern_physio.c		standard
 kern/kern_pmc.c			standard
 kern/kern_poll.c		optional device_polling
diff --git a/sys/conf/options b/sys/conf/options
index 32fb4d4..6e81e4e 100644
--- a/sys/conf/options
+++ b/sys/conf/options
@@ -916,6 +916,12 @@ RACCT		opt_global.h
 # Resource Limits
 RCTL		opt_global.h
=20
+# PaX - hardening options
+PAX_ASLR	opt_pax.h
+PAX_ASLR_MAX_SEC	opt_pax.h
+PAX_MPROTECT	opt_pax.h
+PAX_SYSCTLS	opt_pax.h
+
 # Random number generator(s)
 RANDOM_YARROW	opt_random.h
 RANDOM_FORTUNA	opt_random.h
diff --git a/sys/i386/i386/elf_machdep.c b/sys/i386/i386/elf_machdep.c
index 034b4c4..9571252 100644
--- a/sys/i386/i386/elf_machdep.c
+++ b/sys/i386/i386/elf_machdep.c
@@ -26,6 +26,8 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
=20
+#include "opt_pax.h"
+
 #include <sys/param.h>
 #include <sys/kernel.h>
 #include <sys/systm.h>
@@ -46,6 +48,10 @@ __FBSDID("$FreeBSD$");
 #include <machine/elf.h>
 #include <machine/md_var.h>
=20
+#ifdef PAX_ASLR
+#include <sys/pax.h>
+#endif
+
 struct sysentvec elf32_freebsd_sysvec =3D {
 	.sv_size	=3D SYS_MAXSYSCALL,
 	.sv_table	=3D sysent,
@@ -81,6 +87,11 @@ struct sysentvec elf32_freebsd_sysvec =3D {
 	.sv_shared_page_base =3D SHAREDPAGE,
 	.sv_shared_page_len =3D PAGE_SIZE,
 	.sv_schedtail	=3D NULL,
+#ifdef PAX_ASLR
+	.sv_pax_aslr_init =3D _pax_aslr_init,
+#else
+	.sv_pax_aslr_init =3D NULL,
+#endif
 };
 INIT_SYSENTVEC(elf32_sysvec, &elf32_freebsd_sysvec);
=20
diff --git a/sys/i386/ibcs2/ibcs2_sysvec.c b/sys/i386/ibcs2/ibcs2_sysvec.c
index 5d007c7..1bb9d89 100644
--- a/sys/i386/ibcs2/ibcs2_sysvec.c
+++ b/sys/i386/ibcs2/ibcs2_sysvec.c
@@ -31,6 +31,8 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
=20
+#include "opt_pax.h"
+
 #include <sys/param.h>
 #include <sys/kernel.h>
 #include <sys/systm.h>
@@ -50,6 +52,10 @@ __FBSDID("$FreeBSD$");
 #include <i386/ibcs2/ibcs2_syscall.h>
 #include <i386/ibcs2/ibcs2_signal.h>
=20
+#ifdef PAX_ASLR
+#include <sys/pax.h>
+#endif
+
 MODULE_VERSION(ibcs2, 1);
=20
 extern int bsd_to_ibcs2_errno[];
@@ -89,6 +95,11 @@ struct sysentvec ibcs2_svr3_sysvec =3D {
 	.sv_fetch_syscall_args =3D cpu_fetch_syscall_args,
 	.sv_syscallnames =3D NULL,
 	.sv_schedtail	=3D NULL,
+#ifdef PAX_ASLR
+	.sv_pax_aslr_init =3D _pax_aslr_init, /* XXXOP */
+#else
+	.sv_pax_aslr_init =3D NULL,
+#endif
 };
=20
 static int
diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c
index 0ad6791..403070c 100644
--- a/sys/i386/linux/linux_sysvec.c
+++ b/sys/i386/linux/linux_sysvec.c
@@ -29,6 +29,8 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
=20
+#include "opt_pax.h"
+
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/exec.h>
@@ -72,6 +74,10 @@ __FBSDID("$FreeBSD$");
 #include <compat/linux/linux_signal.h>
 #include <compat/linux/linux_util.h>
=20
+#ifdef PAX_ASLR
+#include <sys/pax.h>
+#endif
+
 MODULE_VERSION(linux, 1);
=20
 MALLOC_DEFINE(M_LINUX, "linux", "Linux mode structures");
@@ -974,6 +980,11 @@ struct sysentvec linux_sysvec =3D {
 	.sv_shared_page_base =3D LINUX_SHAREDPAGE,
 	.sv_shared_page_len =3D PAGE_SIZE,
 	.sv_schedtail	=3D linux_schedtail,
+#ifdef PAX_ASLR
+	.sv_pax_aslr_init =3D _pax_aslr_init, /* XXXOP */
+#else
+	.sv_pax_aslr_init =3D NULL,
+#endif
 };
 INIT_SYSENTVEC(aout_sysvec, &linux_sysvec);
=20
@@ -1012,6 +1023,11 @@ struct sysentvec elf_linux_sysvec =3D {
 	.sv_shared_page_base =3D LINUX_SHAREDPAGE,
 	.sv_shared_page_len =3D PAGE_SIZE,
 	.sv_schedtail	=3D linux_schedtail,
+#ifdef PAX_ASLR
+	.sv_pax_aslr_init =3D _pax_aslr_init,
+#else
+	.sv_pax_aslr_init =3D NULL,
+#endif
 };
 INIT_SYSENTVEC(elf_sysvec, &elf_linux_sysvec);
=20
diff --git a/sys/ia64/ia64/elf_machdep.c b/sys/ia64/ia64/elf_machdep.c
index 05cb641..e3d19c1 100644
--- a/sys/ia64/ia64/elf_machdep.c
+++ b/sys/ia64/ia64/elf_machdep.c
@@ -25,6 +25,8 @@
  * $FreeBSD$
  */
=20
+#include "opt_pax.h"
+
 #include <sys/param.h>
 #include <sys/kernel.h>
 #include <sys/systm.h>
@@ -49,6 +51,10 @@
 #include <machine/md_var.h>
 #include <machine/unwind.h>
=20
+#ifdef PAX_ASLR
+#include <sys/pax.h>
+#endif
+
 Elf_Addr link_elf_get_gp(linker_file_t);
=20
 extern Elf_Addr fptr_storage[];
@@ -86,6 +92,12 @@ struct sysentvec elf64_freebsd_sysvec =3D {
 	.sv_fetch_syscall_args =3D cpu_fetch_syscall_args,
 	.sv_syscallnames =3D syscallnames,
 	.sv_schedtail	=3D NULL,
+#ifdef PAX_ASLR
+	.sv_pax_aslr_init =3D _pax_aslr_init,
+#else
+	.sv_pax_aslr_init =3D NULL,
+#endif
+
 };
=20
 static Elf64_Brandinfo freebsd_brand_info =3D {
diff --git a/sys/kern/imgact_aout.c b/sys/kern/imgact_aout.c
index 3ae78de..aac03f1 100644
--- a/sys/kern/imgact_aout.c
+++ b/sys/kern/imgact_aout.c
@@ -27,6 +27,8 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
=20
+#include "opt_pax.h"
+
 #include <sys/param.h>
 #include <sys/exec.h>
 #include <sys/imgact.h>
@@ -62,6 +64,10 @@ __FBSDID("$FreeBSD$");
 #include <compat/ia32/ia32_signal.h>
 #endif
=20
+#ifdef PAX_ASLR
+#include <sys/pax.h>
+#endif
+
 static int	exec_aout_imgact(struct image_params *imgp);
 static int	aout_fixup(register_t **stack_base, struct image_params *imgp);
=20
@@ -99,6 +105,11 @@ struct sysentvec aout_sysvec =3D {
 	.sv_fetch_syscall_args =3D cpu_fetch_syscall_args,
 	.sv_syscallnames =3D syscallnames,
 	.sv_schedtail	=3D NULL,
+#ifdef PAX_ASLR
+	.sv_pax_aslr_init =3D _pax_aslr_init, /* XXXOP */
+#else
+	.sv_pax_aslr_init =3D NULL,
+#endif
 };
=20
 #elif defined(__amd64__)
@@ -143,6 +154,11 @@ struct sysentvec aout_sysvec =3D {
 	.sv_set_syscall_retval =3D ia32_set_syscall_retval,
 	.sv_fetch_syscall_args =3D ia32_fetch_syscall_args,
 	.sv_syscallnames =3D freebsd32_syscallnames,
+#ifdef PAX_ASLR
+	.sv_pax_aslr_init =3D _pax_aslr_init32, /* XXXOP */
+#else
+	.sv_pax_aslr_init =3D NULL,
+#endif
 };
 #else
 #error "Port me"
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
index 591094e..d0e01d3 100644
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
 #include "opt_capsicum.h"
 #include "opt_compat.h"
 #include "opt_core.h"
+#include "opt_pax.h"
=20
 #include <sys/param.h>
 #include <sys/capsicum.h>
@@ -48,6 +49,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/mman.h>
 #include <sys/namei.h>
 #include <sys/pioctl.h>
+#include <sys/jail.h>
 #include <sys/proc.h>
 #include <sys/procfs.h>
 #include <sys/racct.h>
@@ -81,6 +83,10 @@ __FBSDID("$FreeBSD$");
 #include <machine/elf.h>
 #include <machine/md_var.h>
=20
+#if defined(PAX_ASLR)
+#include <sys/pax.h>
+#endif
+
 #define ELF_NOTE_ROUNDSIZE	4
 #define OLD_EI_BRAND	8
=20
@@ -655,16 +661,16 @@ __elfN(load_file)(struct proc *p, const char *file, u=
_long *addr,
 	hdr =3D (const Elf_Ehdr *)imgp->image_header;
 	if ((error =3D __elfN(check_header)(hdr)) !=3D 0)
 		goto fail;
-	if (hdr->e_type =3D=3D ET_DYN)
+	if (hdr->e_type =3D=3D ET_DYN) {
 		rbase =3D *addr;
-	else if (hdr->e_type =3D=3D ET_EXEC)
+	} else if (hdr->e_type =3D=3D ET_EXEC) {
 		rbase =3D 0;
-	else {
+	} else {
 		error =3D ENOEXEC;
 		goto fail;
 	}
=20
-	/* Only support headers that fit within first page for now      */
+	/* Only support headers that fit within first page for now */
 	if ((hdr->e_phoff > PAGE_SIZE) ||
 	    (u_int)hdr->e_phentsize * hdr->e_phnum > PAGE_SIZE - hdr->e_phoff) {
 		error =3D ENOEXEC;
@@ -789,16 +795,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *i=
mgp)
 	if (hdr->e_type =3D=3D ET_DYN) {
 		if ((brand_info->flags & BI_CAN_EXEC_DYN) =3D=3D 0)
 			return (ENOEXEC);
-		/*
-		 * Honour the base load address from the dso if it is
-		 * non-zero for some reason.
-		 */
-		if (baddr =3D=3D 0)
-			et_dyn_addr =3D ET_DYN_LOAD_ADDR;
-		else
-			et_dyn_addr =3D 0;
-	} else
-		et_dyn_addr =3D 0;
+	}
 	sv =3D brand_info->sysvec;
 	if (interp !=3D NULL && brand_info->interp_newpath !=3D NULL)
 		newinterp =3D brand_info->interp_newpath;
@@ -819,6 +816,25 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *i=
mgp)
 	error =3D exec_new_vmspace(imgp, sv);
 	imgp->proc->p_sysent =3D sv;
=20
+#if defined(PAX_MPROTECT) || defined(PAX_ASLR)
+	pax_elf(imgp, 0);
+#endif
+
+	et_dyn_addr =3D 0;
+	if (hdr->e_type =3D=3D ET_DYN) {
+		/*
+		 * Honour the base load address from the dso if it is
+		 * non-zero for some reason.
+		 */
+		if (baddr =3D=3D 0) {
+			et_dyn_addr =3D ET_DYN_LOAD_ADDR;
+#ifdef PAX_ASLR
+			if (pax_aslr_active(NULL, imgp->proc))
+				et_dyn_addr +=3D imgp->proc->p_vmspace->vm_aslr_delta_exec;
+#endif
+		}
+	}
+
 	vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY);
 	if (error)
 		return (error);
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index 141d438..9301b57 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -410,6 +410,7 @@ struct sysentvec null_sysvec =3D {
 	.sv_fetch_syscall_args =3D null_fetch_syscall_args,
 	.sv_syscallnames =3D NULL,
 	.sv_schedtail	=3D NULL,
+	.sv_pax_aslr_init =3D NULL,
 };
=20
 /*
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
index 667715e..24caccc 100644
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$");
 #include "opt_capsicum.h"
 #include "opt_hwpmc_hooks.h"
 #include "opt_ktrace.h"
+#include "opt_pax.h"
 #include "opt_vm.h"
=20
 #include <sys/param.h>
@@ -94,6 +95,10 @@ __FBSDID("$FreeBSD$");
 dtrace_execexit_func_t	dtrace_fasttrap_exec;
 #endif
=20
+#if defined(PAX_ASLR)
+#include <sys/pax.h>
+#endif
+
 SDT_PROVIDER_DECLARE(proc);
 SDT_PROBE_DEFINE1(proc, kernel, , exec, "char *");
 SDT_PROBE_DEFINE1(proc, kernel, , exec__failure, "int");
@@ -404,6 +409,7 @@ do_execve(td, args, mac_p)
 	imgp->pagesizes =3D 0;
 	imgp->pagesizeslen =3D 0;
 	imgp->stack_prot =3D 0;
+	imgp->pax_flags =3D 0;
=20
 #ifdef MAC
 	error =3D mac_execve_enter(imgp, mac_p);
@@ -1064,6 +1070,10 @@ exec_new_vmspace(imgp, sv)
 		map =3D &vmspace->vm_map;
 	}
=20
+#ifdef PAX_ASLR
+	pax_aslr_init(curthread, imgp);
+#endif
+
 	/* Map a shared page */
 	obj =3D sv->sv_shared_page_obj;
 	if (obj !=3D NULL) {
@@ -1107,6 +1117,9 @@ exec_new_vmspace(imgp, sv)
 	 */
 	vmspace->vm_ssize =3D sgrowsiz >> PAGE_SHIFT;
 	vmspace->vm_maxsaddr =3D (char *)sv->sv_usrstack - ssiz;
+#ifdef PAX_ASLR
+	vmspace->vm_maxsaddr -=3D vmspace->vm_aslr_delta_stack;
+#endif
=20
 	return (0);
 }
@@ -1266,6 +1279,9 @@ exec_copyout_strings(imgp)
 			szsigcode =3D *(p->p_sysent->sv_szsigcode);
 	}
 	destp =3D	(uintptr_t)arginfo;
+#ifdef PAX_ASLR
+	pax_aslr_stack(curthread, &destp);
+#endif
=20
 	/*
 	 * install sigcode
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index b3d9c24..3cd85d8 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -513,6 +513,11 @@ do_fork(struct thread *td, int flags, struct proc *p2,=
 struct thread *td2,
 	}
=20
 	/*
+	 * XXXOP: this is the right place?
+	 */
+	p2->p_pax =3D p1->p_pax;
+
+	/*
 	 * p_limit is copy-on-write.  Bump its refcount.
 	 */
 	lim_fork(p1, p2);
diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c
index 47cd568..d9036bd 100644
--- a/sys/kern/kern_jail.c
+++ b/sys/kern/kern_jail.c
@@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$");
 #include "opt_ddb.h"
 #include "opt_inet.h"
 #include "opt_inet6.h"
+#include "opt_pax.h"
=20
 #include <sys/param.h>
 #include <sys/types.h>
@@ -74,6 +75,10 @@ __FBSDID("$FreeBSD$");
 #endif /* INET6 */
 #endif /* DDB */
=20
+#if defined(PAX_ASLR)
+#include <sys/pax.h>
+#endif
+
 #include <security/mac/mac_framework.h>
=20
 #define	DEFAULT_HOSTUUID	"00000000-0000-0000-0000-000000000000"
@@ -117,6 +122,10 @@ struct prison prison0 =3D {
 };
 MTX_SYSINIT(prison0, &prison0.pr_mtx, "jail mutex", MTX_DEF);
=20
+#if defined(PAX_ASLR)
+SYSINIT(pax, SI_SUB_PAX, SI_ORDER_MIDDLE, pax_init_prison, (void *) &priso=
n0);
+#endif
+
 /* allprison, allprison_racct and lastprid are protected by allprison_lock=
=2E */
 struct	sx allprison_lock;
 SX_SYSINIT(allprison_lock, &allprison_lock, "allprison");
@@ -1307,6 +1316,10 @@ kern_jail_set(struct thread *td, struct uio *optuio,=
 int flags)
 			goto done_releroot;
 		}
=20
+#if defined(PAX_ASLR)
+		pax_init_prison(pr);
+#endif
+
 		mtx_lock(&pr->pr_mtx);
 		/*
 		 * New prisons do not yet have a reference, because we do not
diff --git a/sys/kern/kern_pax.c b/sys/kern/kern_pax.c
new file mode 100644
index 0000000..1bd5ad0
--- /dev/null
+++ b/sys/kern/kern_pax.c
@@ -0,0 +1,214 @@
+/*-
+ * Copyright (c) 2006 Elad Efrat <elad@NetBSD.org>
+ * Copyright (c) 2013-2014, by Oliver Pinter <oliver.pntr at gmail.com>
+ * Copyright (c) 2014, by Shawn Webb <lattera at gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTI=
ES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF US=
E,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_compat.h"
+#include "opt_pax.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/imgact.h>
+#include <sys/imgact_elf.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/sysent.h>
+#include <sys/stat.h>
+#include <sys/proc.h>
+#include <sys/elf_common.h>
+#include <sys/mount.h>
+#include <sys/sysctl.h>
+#include <sys/vnode.h>
+#include <sys/queue.h>
+#include <sys/libkern.h>
+#include <sys/jail.h>
+
+#include <sys/mman.h>
+#include <sys/libkern.h>
+#include <sys/exec.h>
+#include <sys/kthread.h>
+
+#include <sys/syslimits.h>
+#include <sys/param.h>
+
+#include <vm/pmap.h>
+#include <vm/vm_map.h>
+#include <vm/vm_extern.h>
+
+#include <machine/elf.h>
+
+#include <sys/pax.h>
+
+#include <security/mac_bsdextended/mac_bsdextended.h>
+
+SYSCTL_NODE(_security, OID_AUTO, pax, CTLFLAG_RD, 0,
+    "PaX (exploit mitigation) features.");
+
+struct prison *
+pax_get_prison(struct thread *td, struct proc *proc)
+{
+
+	if (td !=3D NULL) {
+		if ((td->td_proc !=3D NULL) && (td->td_proc->p_ucred !=3D NULL))
+			return (td->td_proc->p_ucred->cr_prison);
+
+		return (NULL);
+	}
+	if ((proc =3D=3D NULL) || (proc->p_ucred =3D=3D NULL))
+		return (NULL);
+
+	return (proc->p_ucred->cr_prison);
+}
+
+void
+pax_elf(struct image_params *imgp, uint32_t mode)
+{
+	u_int flags =3D 0;
+
+	if ((mode & MBI_ALLPAX) =3D=3D MBI_ALLPAX)
+		goto end;
+
+	if (mode & MBI_FORCE_ASLR_ENABLED)
+		flags |=3D PAX_NOTE_ASLR;
+	else if (mode & MBI_FORCE_ASLR_DISABLED)
+		flags |=3D PAX_NOTE_NOASLR;
+
+end:
+	if (imgp !=3D NULL) {
+		imgp->pax_flags =3D flags;
+		if (imgp->proc !=3D NULL) {
+			PROC_LOCK(imgp->proc);
+			imgp->proc->p_pax =3D flags;
+			PROC_UNLOCK(imgp->proc);
+		}
+	}
+}
+
+
+/*
+ * print out PaX settings on boot time, and validate some of them
+ */
+void
+pax_init(void)
+{
+#if defined(PAX_ASLR)
+	const char *status_str[] =3D {
+		[0] =3D "disabled",
+		[1] =3D "opt-in",
+		[2] =3D "opt-out",
+		[3] =3D "force enabled",
+		[4] =3D "UNKNOWN -> changed to \"force enabled\""
+	};
+#endif
+
+#ifdef PAX_ASLR
+	switch (pax_aslr_status) {
+	case	0:
+	case	1:
+	case	2:
+	case	3:
+		break;
+	default:
+		printf("[PAX ASLR] WARNING, invalid PAX settings in loader.conf!"
+		    " (pax_aslr_status =3D %d)\n", pax_aslr_status);
+		pax_aslr_status =3D 3;
+		break;
+	}
+	printf("[PAX ASLR] status: %s\n", status_str[pax_aslr_status]);
+	printf("[PAX ASLR] mmap: %d bit\n", pax_aslr_mmap_len);
+	printf("[PAX ASLR] exec base: %d bit\n", pax_aslr_exec_len);
+	printf("[PAX ASLR] stack: %d bit\n", pax_aslr_stack_len);
+
+#ifdef COMPAT_FREEBSD32
+	switch (pax_aslr_compat_status) {
+	case	0:
+	case	1:
+	case	2:
+	case	3:
+		break;
+	default:
+		printf("[PAX ASLR (compat)] WARNING, invalid PAX settings in loader.conf=
! "
+		    "(pax_aslr_compat_status =3D %d)\n", pax_aslr_compat_status);
+		pax_aslr_compat_status =3D 3;
+		break;
+	}
+	printf("[PAX ASLR (compat)] status: %s\n", status_str[pax_aslr_compat_sta=
tus]);
+	printf("[PAX ASLR (compat)] mmap: %d bit\n", pax_aslr_compat_mmap_len);
+	printf("[PAX ASLR (compat)] exec base: %d bit\n", pax_aslr_compat_exec_le=
n);
+	printf("[PAX ASLR (compat)] stack: %d bit\n", pax_aslr_compat_stack_len);
+#endif /* COMPAT_FREEBSD32 */
+#endif /* PAX_ASLR */
+
+	printf("[PAX LOG] logging to system: %d\n", pax_log_log);
+	printf("[PAX LOG] logging to user: %d\n", pax_log_ulog);
+}
+SYSINIT(pax, SI_SUB_PAX, SI_ORDER_FIRST, pax_init, NULL);
+
+void
+pax_init_prison(struct prison *pr)
+{
+
+	if (pr =3D=3D NULL)
+		return;
+
+	if (pr->pr_pax_set)
+		return;
+
+	mtx_lock(&(pr->pr_mtx));
+
+	if (pax_aslr_debug)
+		uprintf("[PaX ASLR] %s: Setting prison %s ASLR variables\n",
+		    __func__, pr->pr_name);
+
+#ifdef PAX_ASLR
+	pr->pr_pax_aslr_status =3D pax_aslr_status;
+	pr->pr_pax_aslr_debug =3D pax_aslr_debug;
+	pr->pr_pax_aslr_mmap_len =3D pax_aslr_mmap_len;
+	pr->pr_pax_aslr_stack_len =3D pax_aslr_stack_len;
+	pr->pr_pax_aslr_exec_len =3D pax_aslr_exec_len;
+
+#ifdef COMPAT_FREEBSD32
+	pr->pr_pax_aslr_compat_status =3D pax_aslr_compat_status;
+	pr->pr_pax_aslr_compat_mmap_len =3D pax_aslr_compat_mmap_len;
+	pr->pr_pax_aslr_compat_stack_len =3D pax_aslr_compat_stack_len;
+	pr->pr_pax_aslr_compat_exec_len =3D pax_aslr_compat_exec_len;
+#endif /* COMPAT_FREEBSD32 */
+#endif /* PAX_ASLR */
+
+	pr->pr_pax_log_log =3D pax_log_log;
+	pr->pr_pax_log_ulog =3D pax_log_ulog;
+
+	pr->pr_pax_set =3D 1;
+
+	mtx_unlock(&(pr->pr_mtx));
+}
diff --git a/sys/kern/kern_pax_aslr.c b/sys/kern/kern_pax_aslr.c
new file mode 100644
index 0000000..4b5e8dd
--- /dev/null
+++ b/sys/kern/kern_pax_aslr.c
@@ -0,0 +1,685 @@
+/*-
+ * Copyright (c) 2006 Elad Efrat <elad@NetBSD.org>
+ * Copyright (c) 2013-2014, by Oliver Pinter <oliver.pntr at gmail.com>
+ * Copyright (c) 2014, by Shawn Webb <lattera at gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTI=
ES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF US=
E,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_compat.h"
+#include "opt_pax.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/imgact.h>
+#include <sys/imgact_elf.h>
+#include <sys/sysent.h>
+#include <sys/stat.h>
+#include <sys/proc.h>
+#include <sys/elf_common.h>
+#include <sys/mount.h>
+#include <sys/sysctl.h>
+#include <sys/vnode.h>
+#include <sys/queue.h>
+#include <sys/libkern.h>
+#include <sys/jail.h>
+
+#include <sys/mman.h>
+#include <sys/libkern.h>
+#include <sys/exec.h>
+#include <sys/kthread.h>
+
+#include <vm/pmap.h>
+#include <vm/vm_map.h>
+#include <vm/vm_extern.h>
+
+#include <machine/elf.h>
+
+#include <sys/pax.h>
+
+FEATURE(aslr, "Address Space Layout Randomization.");
+
+int pax_aslr_status =3D PAX_ASLR_OPTOUT;
+int pax_aslr_debug =3D 0;
+
+#ifdef PAX_ASLR_MAX_SEC
+int pax_aslr_mmap_len =3D PAX_ASLR_DELTA_MMAP_MAX_LEN;
+int pax_aslr_stack_len =3D PAX_ASLR_DELTA_STACK_MAX_LEN;
+int pax_aslr_exec_len =3D PAX_ASLR_DELTA_EXEC_MAX_LEN;
+#else
+int pax_aslr_mmap_len =3D PAX_ASLR_DELTA_MMAP_DEF_LEN;
+int pax_aslr_stack_len =3D PAX_ASLR_DELTA_STACK_DEF_LEN;
+int pax_aslr_exec_len =3D PAX_ASLR_DELTA_EXEC_DEF_LEN;
+#endif /* PAX_ASLR_MAX_SEC */
+
+#ifdef COMPAT_FREEBSD32
+int pax_aslr_compat_status =3D PAX_ASLR_OPTOUT;
+#ifdef PAX_ASLR_MAX_SEC
+int pax_aslr_compat_mmap_len =3D PAX_ASLR_COMPAT_DELTA_MMAP_MAX_LEN;
+int pax_aslr_compat_stack_len =3D PAX_ASLR_COMPAT_DELTA_STACK_MAX_LEN;
+int pax_aslr_compat_exec_len =3D PAX_ASLR_COMPAT_DELTA_EXEC_MAX_LEN;
+#else
+int pax_aslr_compat_mmap_len =3D PAX_ASLR_COMPAT_DELTA_MMAP_MIN_LEN;
+int pax_aslr_compat_stack_len =3D PAX_ASLR_COMPAT_DELTA_STACK_MIN_LEN;
+int pax_aslr_compat_exec_len =3D PAX_ASLR_COMPAT_DELTA_EXEC_MIN_LEN;
+#endif /* PAX_ASLR_MAX_SEC */
+#endif /* COMPAT_FREEBSD32 */
+
+TUNABLE_INT("security.pax.aslr.status", &pax_aslr_status);
+TUNABLE_INT("security.pax.aslr.mmap_len", &pax_aslr_mmap_len);
+TUNABLE_INT("security.pax.aslr.debug", &pax_aslr_debug);
+TUNABLE_INT("security.pax.aslr.stack_len", &pax_aslr_stack_len);
+TUNABLE_INT("security.pax.aslr.exec_len", &pax_aslr_exec_len);
+#ifdef COMPAT_FREEBSD32
+TUNABLE_INT("security.pax.aslr.compat.status", &pax_aslr_compat_status);
+TUNABLE_INT("security.pax.aslr.compat.mmap", &pax_aslr_compat_mmap_len);
+TUNABLE_INT("security.pax.aslr.compat.stack", &pax_aslr_compat_stack_len);
+TUNABLE_INT("security.pax.aslr.compat.stack", &pax_aslr_compat_exec_len);
+#endif
+
+
+#ifdef PAX_SYSCTLS
+/*
+ * sysctls and tunables
+ */
+static int sysctl_pax_aslr_debug(SYSCTL_HANDLER_ARGS);
+static int sysctl_pax_aslr_status(SYSCTL_HANDLER_ARGS);
+static int sysctl_pax_aslr_mmap(SYSCTL_HANDLER_ARGS);
+static int sysctl_pax_aslr_stack(SYSCTL_HANDLER_ARGS);
+static int sysctl_pax_aslr_exec(SYSCTL_HANDLER_ARGS);
+
+SYSCTL_DECL(_security_pax);
+
+SYSCTL_NODE(_security_pax, OID_AUTO, aslr, CTLFLAG_RD, 0,
+    "Address Space Layout Randomization.");
+
+SYSCTL_PROC(_security_pax_aslr, OID_AUTO, status,
+    CTLTYPE_INT|CTLFLAG_RWTUN|CTLFLAG_PRISON|CTLFLAG_SECURE,
+    NULL, 0, sysctl_pax_aslr_status, "I",
+    "Restrictions status. "
+    "0 - disabled, "
+    "1 - opt-in,  "
+    "2 - opt-out, "
+    "3 - force enabled");
+
+SYSCTL_PROC(_security_pax_aslr, OID_AUTO, debug,
+    CTLTYPE_INT|CTLFLAG_RWTUN|CTLFLAG_PRISON|CTLFLAG_SECURE,
+    NULL, 0, sysctl_pax_aslr_debug, "I",
+    "ASLR debug mode");
+
+SYSCTL_PROC(_security_pax_aslr, OID_AUTO, mmap_len,
+    CTLTYPE_INT|CTLFLAG_RWTUN|CTLFLAG_PRISON|CTLFLAG_SECURE,
+    NULL, 0, sysctl_pax_aslr_mmap, "I",
+    "Number of bits randomized for mmap(2) calls. "
+    "32 bit: [8,16] 64 bit: [16,32]");
+
+SYSCTL_PROC(_security_pax_aslr, OID_AUTO, stack_len,
+    CTLTYPE_INT|CTLFLAG_RWTUN|CTLFLAG_PRISON|CTLFLAG_SECURE,
+    NULL, 0, sysctl_pax_aslr_stack, "I",
+    "Number of bits randomized for the stack. "
+    "32 bit: [6,12] 64 bit: [12,21]");
+
+SYSCTL_PROC(_security_pax_aslr, OID_AUTO, exec_len,
+    CTLTYPE_INT|CTLFLAG_RWTUN|CTLFLAG_PRISON|CTLFLAG_SECURE,
+    NULL, 0, sysctl_pax_aslr_exec, "I",
+    "Number of bits randomized for the PIE exec base. "
+    "32 bit: [6,12] 64 bit: [12,21]");
+
+static int
+sysctl_pax_aslr_status(SYSCTL_HANDLER_ARGS)
+{
+	struct prison *pr;
+	int err, val;
+
+	pr =3D pax_get_prison(req->td, NULL);
+
+	val =3D (pr !=3D NULL) ? pr->pr_pax_aslr_status : pax_aslr_status;
+	err =3D sysctl_handle_int(oidp, &val, sizeof(int), req);
+	if (err || (req->newptr =3D=3D NULL))
+		return (err);
+
+	switch (val) {
+	case    PAX_ASLR_DISABLED:
+	case    PAX_ASLR_OPTIN:
+	case    PAX_ASLR_OPTOUT:
+	case    PAX_ASLR_FORCE_ENABLED:
+		if ((pr =3D=3D NULL) || (pr =3D=3D &prison0))
+			pax_aslr_status =3D val;
+
+		if (pr !=3D NULL) {
+			mtx_lock(&(pr->pr_mtx));
+			pr->pr_pax_aslr_status =3D val;
+			mtx_unlock(&(pr->pr_mtx));
+		}
+		break;
+	default:
+		return (EINVAL);
+	}
+
+	return (0);
+}
+
+static int
+sysctl_pax_aslr_debug(SYSCTL_HANDLER_ARGS)
+{
+	struct prison *pr=3DNULL;
+	int err, val;
+
+	pr =3D pax_get_prison(req->td, NULL);
+
+	if ((pr !=3D NULL) && !(pr->pr_pax_set))
+		pax_init_prison(pr);
+
+	val =3D (pr !=3D NULL) ? pr->pr_pax_aslr_debug : pax_aslr_debug;
+	err =3D sysctl_handle_int(oidp, &val, sizeof(int), req);
+	if (err || !req->newptr)
+		return (err);
+
+	switch (val) {
+	case	0:
+	case	1:
+		break;
+	default:
+		return (EINVAL);
+
+	}
+
+	if ((pr =3D=3D NULL) || (pr =3D=3D &prison0))
+		pax_aslr_debug =3D val;
+
+	if (pr !=3D NULL) {
+		mtx_lock(&(pr->pr_mtx));
+		pr->pr_pax_aslr_debug =3D val;
+		mtx_unlock(&(pr->pr_mtx));
+	}
+
+	return (0);
+}
+
+static int
+sysctl_pax_aslr_mmap(SYSCTL_HANDLER_ARGS)
+{
+	struct prison *pr=3DNULL;
+	int err, val;
+
+	pr =3D pax_get_prison(req->td, NULL);
+
+	if ((pr !=3D NULL) && !(pr->pr_pax_set))
+		pax_init_prison(pr);
+
+	val =3D (pr !=3D NULL) ? pr->pr_pax_aslr_mmap_len : pax_aslr_mmap_len;
+	err =3D sysctl_handle_int(oidp, &val, sizeof(int), req);
+	if (err || !req->newptr)
+		return (err);
+
+	if (val < PAX_ASLR_DELTA_MMAP_MIN_LEN ||
+	    val > PAX_ASLR_DELTA_MMAP_MAX_LEN)
+		return (EINVAL);
+
+	if ((pr =3D=3D NULL) || (pr =3D=3D &prison0))
+		pax_aslr_mmap_len =3D val;
+
+	if (pr !=3D NULL) {
+		mtx_lock(&(pr->pr_mtx));
+		pr->pr_pax_aslr_mmap_len =3D val;
+		mtx_unlock(&(pr->pr_mtx));
+	}
+
+	return (0);
+}
+
+static int
+sysctl_pax_aslr_stack(SYSCTL_HANDLER_ARGS)
+{
+	struct prison *pr=3DNULL;
+	int err, val;
+
+	pr =3D pax_get_prison(req->td, NULL);
+
+	if ((pr !=3D NULL) && !(pr->pr_pax_set))
+		pax_init_prison(pr);
+
+	val =3D (pr !=3D NULL) ? pr->pr_pax_aslr_stack_len : pax_aslr_stack_len;
+	err =3D sysctl_handle_int(oidp, &val, sizeof(int), req);
+	if (err || !req->newptr)
+		return (err);
+
+	if (val < PAX_ASLR_DELTA_STACK_MIN_LEN ||
+	    val > PAX_ASLR_DELTA_STACK_MAX_LEN)
+		return (EINVAL);
+
+	if ((pr =3D=3D NULL) || (pr =3D=3D &prison0))
+		pax_aslr_stack_len =3D val;
+
+	if (pr !=3D NULL) {
+		mtx_lock(&(pr->pr_mtx));
+		pr->pr_pax_aslr_stack_len =3D val;
+		mtx_unlock(&(pr->pr_mtx));
+	}
+
+	return (0);
+}
+
+static int
+sysctl_pax_aslr_exec(SYSCTL_HANDLER_ARGS)
+{
+	struct prison *pr=3DNULL;
+	int err, val;
+
+	pr =3D pax_get_prison(req->td, NULL);
+
+	if ((pr !=3D NULL) && !(pr->pr_pax_set))
+		pax_init_prison(pr);
+
+	val =3D (pr !=3D NULL) ? pr->pr_pax_aslr_exec_len : pax_aslr_exec_len;
+	err =3D sysctl_handle_int(oidp, &val, sizeof(int), req);
+	if (err || (req->newptr =3D=3D NULL))
+		return (err);
+
+	if (val < PAX_ASLR_DELTA_EXEC_MIN_LEN ||
+	    val > PAX_ASLR_DELTA_EXEC_MAX_LEN)
+		return (EINVAL);
+
+	if ((pr =3D=3D NULL) || (pr =3D=3D &prison0))
+		pax_aslr_exec_len =3D val;
+
+	if (pr !=3D NULL) {
+		mtx_lock(&(pr->pr_mtx));
+		pr->pr_pax_aslr_exec_len =3D val;
+		mtx_unlock(&(pr->pr_mtx));
+	}
+
+	return (0);
+}
+
+/*
+ * COMPAT_FREEBSD32 and linuxulator..
+ */
+#ifdef COMPAT_FREEBSD32
+static int sysctl_pax_aslr_compat_status(SYSCTL_HANDLER_ARGS);
+static int sysctl_pax_aslr_compat_mmap(SYSCTL_HANDLER_ARGS);
+static int sysctl_pax_aslr_compat_stack(SYSCTL_HANDLER_ARGS);
+static int sysctl_pax_aslr_compat_exec(SYSCTL_HANDLER_ARGS);
+
+SYSCTL_NODE(_security_pax_aslr, OID_AUTO, compat, CTLFLAG_RD, 0,
+    "Setting for COMPAT_FREEBSD32 and linuxulator.");
+
+SYSCTL_PROC(_security_pax_aslr_compat, OID_AUTO, status,
+    CTLTYPE_INT|CTLFLAG_RWTUN|CTLFLAG_PRISON,
+    NULL, 0, sysctl_pax_aslr_compat_status, "I",
+    "Restrictions status. "
+    "0 - disabled, "
+    "1 - enabled,  "
+    "2 - global enabled, "
+    "3 - force global enabled");
+
+SYSCTL_PROC(_security_pax_aslr_compat, OID_AUTO, mmap_len,
+    CTLTYPE_INT|CTLFLAG_RWTUN|CTLFLAG_PRISON,
+    NULL, 0, sysctl_pax_aslr_compat_mmap, "I",
+    "Number of bits randomized for mmap(2) calls. "
+    "32 bit: [8,16]");
+
+SYSCTL_PROC(_security_pax_aslr_compat, OID_AUTO, stack_len,
+    CTLTYPE_INT|CTLFLAG_RWTUN|CTLFLAG_PRISON,
+    NULL, 0, sysctl_pax_aslr_compat_stack, "I",
+    "Number of bits randomized for the stack. "
+    "32 bit: [6,12]");
+
+SYSCTL_PROC(_security_pax_aslr_compat, OID_AUTO, exec_len,
+    CTLTYPE_INT|CTLFLAG_RWTUN|CTLFLAG_PRISON,
+    NULL, 0, sysctl_pax_aslr_compat_exec, "I",
+    "Number of bits randomized for the PIE exec base. "
+    "32 bit: [6,12]");
+
+static int
+sysctl_pax_aslr_compat_status(SYSCTL_HANDLER_ARGS)
+{
+	struct prison *pr;
+	int err, val;
+
+	pr =3D pax_get_prison(req->td, NULL);
+
+	val =3D (pr !=3D NULL) ?pr->pr_pax_aslr_compat_status : pax_aslr_compat_s=
tatus;
+	err =3D sysctl_handle_int(oidp, &val, sizeof(int), req);
+	if (err || (req->newptr =3D=3D NULL))
+		return (err);
+
+	switch (val) {
+	case    PAX_ASLR_DISABLED:
+	case    PAX_ASLR_OPTIN:
+	case    PAX_ASLR_OPTOUT:
+	case    PAX_ASLR_FORCE_ENABLED:
+		if ((pr =3D=3D NULL) || (pr =3D=3D &prison0))
+			pax_aslr_compat_status =3D val;
+
+		if (pr !=3D NULL) {
+			mtx_lock(&(pr->pr_mtx));
+			pr->pr_pax_aslr_compat_status =3D val;
+			mtx_unlock(&(pr->pr_mtx));
+		}
+		break;
+	default:
+		return (EINVAL);
+	}
+
+	return (0);
+}
+
+static int
+sysctl_pax_aslr_compat_mmap(SYSCTL_HANDLER_ARGS)
+{
+	struct prison *pr;
+	int err, val;
+
+	pr =3D pax_get_prison(req->td, NULL);
+
+	val =3D (pr !=3D NULL) ? pr->pr_pax_aslr_compat_mmap_len : pax_aslr_compa=
t_mmap_len;
+	err =3D sysctl_handle_int(oidp, &val, sizeof(int), req);
+	if (err || !req->newptr)
+		return (err);
+
+	if (val < PAX_ASLR_COMPAT_DELTA_MMAP_MIN_LEN ||
+	    val > PAX_ASLR_COMPAT_DELTA_MMAP_MAX_LEN)
+		return (EINVAL);
+
+	if ((pr =3D=3D NULL) || (pr =3D=3D &prison0))
+		pax_aslr_compat_mmap_len =3D val;
+
+	if (pr !=3D NULL) {
+		mtx_lock(&(pr->pr_mtx));
+		pr->pr_pax_aslr_compat_mmap_len =3D val;
+		mtx_unlock(&(pr->pr_mtx));
+	}
+
+	return (0);
+}
+
+static int
+sysctl_pax_aslr_compat_stack(SYSCTL_HANDLER_ARGS)
+{
+	struct prison *pr;
+	int err, val;
+
+	pr =3D pax_get_prison(req->td, NULL);
+
+	val =3D (pr !=3D NULL) ? pr->pr_pax_aslr_compat_stack_len : pax_aslr_comp=
at_stack_len;
+	err =3D sysctl_handle_int(oidp, &val, sizeof(int), req);
+	if (err || !req->newptr)
+		return (err);
+
+	if (val < PAX_ASLR_COMPAT_DELTA_STACK_MIN_LEN ||
+	    val > PAX_ASLR_COMPAT_DELTA_STACK_MAX_LEN)
+		return (EINVAL);
+
+	if ((pr =3D=3D NULL) || (pr =3D=3D &prison0))
+		pax_aslr_compat_stack_len =3D val;
+
+	if (pr !=3D NULL) {
+		mtx_lock(&(pr->pr_mtx));
+		pr->pr_pax_aslr_compat_stack_len =3D val;
+		mtx_unlock(&(pr->pr_mtx));
+	}
+
+	return (0);
+}
+
+static int
+sysctl_pax_aslr_compat_exec(SYSCTL_HANDLER_ARGS)
+{
+	struct prison *pr;
+	int err, val;
+
+	pr =3D pax_get_prison(req->td, NULL);
+
+	if (pr !=3D NULL)
+		val =3D pr->pr_pax_aslr_compat_exec_len;
+	else
+		val =3D pax_aslr_compat_exec_len;
+
+	err =3D sysctl_handle_int(oidp, &val, sizeof(int), req);
+	if (err || !req->newptr)
+		return (err);
+
+	if (val < PAX_ASLR_COMPAT_DELTA_EXEC_MIN_LEN ||
+	    val > PAX_ASLR_COMPAT_DELTA_EXEC_MAX_LEN)
+		return (EINVAL);
+
+	if ((pr =3D=3D NULL) || (pr =3D=3D &prison0))
+		pax_aslr_compat_exec_len =3D val;
+
+	if (pr !=3D NULL) {
+		mtx_lock(&(pr->pr_mtx));
+		pr->pr_pax_aslr_compat_exec_len =3D val;
+		mtx_unlock(&(pr->pr_mtx));
+	}
+
+	return (0);
+}
+
+#endif /* COMPAT_FREEBSD32 */
+#endif /* PAX_SYSCTLS */
+
+
+/*
+ * ASLR functions
+ */
+bool
+pax_aslr_active(struct thread *td, struct proc *proc)
+{
+	int status;
+	struct prison *pr;
+	uint32_t flags;
+
+	if ((td =3D=3D NULL) && (proc =3D=3D NULL))
+		return (true);
+
+	pr =3D pax_get_prison(td, proc);
+
+	flags =3D (td !=3D NULL) ? td->td_proc->p_pax : proc->p_pax;
+	if (((flags & 0xaaaaaaaa) & ((flags & 0x55555555) << 1)) !=3D 0) {
+		pax_log_aslr(pr, __func__, "inconsistent paxflags: %x\n", flags);
+		pax_ulog_aslr(pr, NULL, "inconsistent paxflags: %x\n", flags);
+		return (true);
+	}
+
+	if (pr !=3D NULL)
+		status =3D pr->pr_pax_aslr_status;
+	else
+		status =3D pax_aslr_status;
+
+	switch (status) {
+	case    PAX_ASLR_DISABLED:
+		return (false);
+	case    PAX_ASLR_FORCE_ENABLED:
+		return (true);
+	case    PAX_ASLR_OPTIN:
+		if ((flags & PAX_NOTE_ASLR) =3D=3D 0) {
+			pax_log_aslr(pr, __func__,
+			    "ASLR is opt-in, and executable does not have ASLR enabled\n");
+			pax_ulog_aslr(pr, NULL,
+			    "ASLR is opt-in, and executable does not have ASLR enabled\n");
+			return (false);
+		}
+		break;
+	case    PAX_ASLR_OPTOUT:
+		if ((flags & PAX_NOTE_NOASLR) !=3D 0) {
+			pax_log_aslr(pr, __func__,
+			    "ASLR is opt-out, and executable explicitly disabled ASLR\n");
+			pax_ulog_aslr(pr, NULL,
+			    "ASLR is opt-out, and executable explicitly disabled ASLR\n");
+			return (false);
+		}
+		break;
+	default:
+		return (true);
+	}
+
+	return (true);
+}
+
+void
+_pax_aslr_init(struct vmspace *vm, struct prison *pr)
+{
+	if (vm =3D=3D NULL)
+		panic("[PaX ASLR] %s: vm =3D=3D NULL", __func__);
+
+	vm->vm_aslr_delta_mmap =3D PAX_ASLR_DELTA(arc4random(),
+	    PAX_ASLR_DELTA_MMAP_LSB, (pr !=3D NULL) ?
+	    pr->pr_pax_aslr_mmap_len :
+	    pax_aslr_mmap_len);
+	vm->vm_aslr_delta_stack =3D PAX_ASLR_DELTA(arc4random(),
+	    PAX_ASLR_DELTA_STACK_LSB, (pr !=3D NULL) ?
+	    pr->pr_pax_aslr_stack_len :
+	    pax_aslr_stack_len);
+	vm->vm_aslr_delta_stack =3D ALIGN(vm->vm_aslr_delta_stack);
+	vm->vm_aslr_delta_exec =3D PAX_ASLR_DELTA(arc4random(),
+	    PAX_ASLR_DELTA_EXEC_LSB, (pr !=3D NULL) ?
+	    pr->pr_pax_aslr_exec_len :
+	    pax_aslr_exec_len);
+
+	if ((pr !=3D NULL) && pr->pr_pax_aslr_debug) {
+		pax_log_aslr(pr, __func__, "vm_aslr_delta_mmap=3D%p\n",
+		    (void *) vm->vm_aslr_delta_mmap);
+		pax_log_aslr(pr, __func__, "vm_aslr_delta_stack=3D%p\n",
+		    (void *) vm->vm_aslr_delta_stack);
+		pax_log_aslr(pr, __func__, "vm_aslr_delta_exec=3D%p\n",
+		    (void *) vm->vm_aslr_delta_exec);
+		pax_ulog_aslr(pr, NULL, "vm_aslr_delta_mmap=3D%p\n",
+		    (void *) vm->vm_aslr_delta_mmap);
+		pax_ulog_aslr(pr, NULL, "vm_aslr_delta_stack=3D%p\n",
+		    (void *) vm->vm_aslr_delta_stack);
+		pax_ulog_aslr(pr, NULL, "vm_aslr_delta_exec=3D%p\n",
+		    (void *) vm->vm_aslr_delta_exec);
+	}
+}
+
+#ifdef COMPAT_FREEBSD32
+void
+_pax_aslr_init32(struct vmspace *vm, struct prison *pr)
+{
+	if (vm =3D=3D NULL)
+		panic("[PaX ASLR] %s: vm =3D=3D NULL", __func__);
+
+	vm->vm_aslr_delta_mmap =3D PAX_ASLR_DELTA(arc4random(),
+	    PAX_ASLR_COMPAT_DELTA_MMAP_LSB, (pr !=3D NULL) ?
+	    pr->pr_pax_aslr_compat_mmap_len :
+	    pax_aslr_compat_mmap_len);
+	vm->vm_aslr_delta_stack =3D PAX_ASLR_DELTA(arc4random(),
+	    PAX_ASLR_COMPAT_DELTA_STACK_LSB, (pr !=3D NULL) ?
+	    pr->pr_pax_aslr_compat_stack_len :
+	    pax_aslr_compat_stack_len);
+	vm->vm_aslr_delta_stack =3D ALIGN(vm->vm_aslr_delta_stack);
+	vm->vm_aslr_delta_exec =3D PAX_ASLR_DELTA(arc4random(),
+	    PAX_ASLR_DELTA_EXEC_LSB, (pr !=3D NULL) ?
+	    pr->pr_pax_aslr_compat_exec_len :
+	    pax_aslr_compat_exec_len);
+
+	if ((pr !=3D NULL) && pr->pr_pax_aslr_debug) {
+		pax_log_aslr(pr, __func__, "vm_aslr_delta_mmap=3D%p\n",
+		    (void *) vm->vm_aslr_delta_mmap);
+		pax_log_aslr(pr, __func__, "vm_aslr_delta_stack=3D%p\n",
+		    (void *) vm->vm_aslr_delta_stack);
+		pax_log_aslr(pr, __func__, "vm_aslr_delta_exec=3D%p\n",
+		    (void *) vm->vm_aslr_delta_exec);
+		pax_ulog_aslr(pr, NULL, "vm_aslr_delta_mmap=3D%p\n",
+		    (void *) vm->vm_aslr_delta_mmap);
+		pax_ulog_aslr(pr, NULL, "vm_aslr_delta_stack=3D%p\n",
+		    (void *) vm->vm_aslr_delta_stack);
+		pax_ulog_aslr(pr, NULL, "vm_aslr_delta_exec=3D%p\n",
+		    (void *) vm->vm_aslr_delta_exec);
+	}
+}
+#endif
+
+void
+pax_aslr_init(struct thread *td, struct image_params *imgp)
+{
+	struct prison *pr;
+	struct vmspace *vm;
+
+	pr =3D pax_get_prison(td, NULL);
+
+	if (imgp =3D=3D NULL)
+		panic("[PaX ASLR] %s: imgp =3D=3D NULL", __func__);
+
+	if (!pax_aslr_active(td, NULL))
+		return;
+
+	vm =3D imgp->proc->p_vmspace;
+
+	if (imgp->sysent->sv_pax_aslr_init !=3D NULL)
+		imgp->sysent->sv_pax_aslr_init(vm, pr);
+}
+
+void
+pax_aslr_mmap(struct thread *td, vm_offset_t *addr, vm_offset_t orig_addr,=
 int flags)
+{
+	struct prison *pr;
+
+	if (!pax_aslr_active(td, NULL))
+		return;
+
+	orig_addr =3D *addr;
+
+	pr =3D pax_get_prison(td, NULL);
+
+	if (!(flags & MAP_FIXED) && ((orig_addr =3D=3D 0) || !(flags & MAP_ANON))=
) {
+		pax_log_aslr(pr, __func__, "applying to %p orig_addr=3D%p flags=3D%x\n",
+		    (void *)*addr, (void *)orig_addr, flags);
+
+		if (!(td->td_proc->p_vmspace->vm_map.flags & MAP_ENTRY_GROWS_DOWN))
+			*addr +=3D td->td_proc->p_vmspace->vm_aslr_delta_mmap;
+		else
+			*addr -=3D td->td_proc->p_vmspace->vm_aslr_delta_mmap;
+		pax_log_aslr(pr, __func__, "result %p\n", (void *)*addr);
+	} else {
+		pax_log_aslr(pr, __func__, "not applying to %p orig_addr=3D%p flags=3D%x=
\n",
+		    (void *)*addr, (void *)orig_addr, flags);
+	}
+}
+
+void
+pax_aslr_stack(struct thread *td, uintptr_t *addr)
+{
+	struct prison *pr;
+	uintptr_t orig_addr;
+
+	if (!pax_aslr_active(td, NULL))
+		return;
+
+	pr =3D pax_get_prison(td, NULL);
+
+	orig_addr =3D *addr;
+	*addr -=3D td->td_proc->p_vmspace->vm_aslr_delta_stack;
+	pax_log_aslr(pr, __func__, "orig_addr=3D%p, new_addr=3D%p\n",
+	    (void *)orig_addr, (void *)*addr);
+	pax_ulog_aslr(pr, NULL, "orig_addr=3D%p, new_addr=3D%p\n",
+	    (void *)orig_addr, (void *)*addr);
+}
diff --git a/sys/kern/kern_pax_log.c b/sys/kern/kern_pax_log.c
new file mode 100644
index 0000000..943ac81
--- /dev/null
+++ b/sys/kern/kern_pax_log.c
@@ -0,0 +1,188 @@
+/*-
+ * Copyright (c) 2014, by Oliver Pinter <oliver.pntr at gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURP=
OSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENT=
IAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STR=
ICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY W=
AY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/cdefs.h>
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/types.h>
+#include <sys/kernel.h>
+#include <sys/pax.h>
+#include <sys/sbuf.h>
+#include <sys/jail.h>
+#include <machine/stdarg.h>
+
+#define __PAX_LOG_TEMPLATE(SUBJECT, name)					\
+void										\
+pax_log_##name(struct prison *pr, const char *caller_name, const char* fmt=
, ...)\
+{										\
+	struct sbuf *sb;							\
+	va_list args;								\
+										\
+	if ((pr !=3D NULL) && (pr->pr_pax_log_log =3D=3D 0))				\
+		return;								\
+										\
+	sb =3D sbuf_new_auto();							\
+	if (sb =3D=3D NULL)								\
+		panic("%s: Could not allocate memory", __func__);		\
+	sbuf_printf(sb, "[PAX "#SUBJECT"] ");					\
+	if (caller_name !=3D NULL)						\
+		sbuf_printf(sb, "%s: ", caller_name);				\
+	va_start(args, fmt);							\
+	sbuf_vprintf(sb, fmt, args);						\
+	va_end(args);								\
+	if (sbuf_finish(sb) !=3D 0)						\
+		panic("%s: Could not generate message", __func__);		\
+										\
+	printf("%s", sbuf_data(sb));						\
+	sbuf_delete(sb);							\
+}										\
+										\
+void										\
+pax_ulog_##name(struct prison *pr, const char *caller_name, const char* fm=
t, ...)\
+{										\
+	struct sbuf *sb;							\
+	va_list args;								\
+										\
+	if ((pr !=3D NULL) && (pr->pr_pax_log_ulog =3D=3D 0))				\
+		return;								\
+										\
+	sb =3D sbuf_new_auto();							\
+	if (sb =3D=3D NULL)								\
+		panic("%s: Could not allocate memory", __func__);		\
+	sbuf_printf(sb, "[PAX "#SUBJECT"] ");					\
+	if (caller_name !=3D NULL)						\
+		sbuf_printf(sb, "%s: ", caller_name);				\
+	va_start(args, fmt);							\
+	sbuf_vprintf(sb, fmt, args);						\
+	va_end(args);								\
+	if (sbuf_finish(sb) !=3D 0)						\
+		panic("%s: Could not generate message", __func__);		\
+										\
+	uprintf("%s", sbuf_data(sb));						\
+	sbuf_delete(sb);							\
+}
+
+
+static int sysctl_pax_log_log(SYSCTL_HANDLER_ARGS);
+static int sysctl_pax_log_ulog(SYSCTL_HANDLER_ARGS);
+
+int pax_log_log =3D PAX_LOG_LOG;
+int pax_log_ulog =3D PAX_LOG_ULOG;
+
+SYSCTL_DECL(_security_pax);
+
+SYSCTL_NODE(_security_pax, OID_AUTO, log, CTLFLAG_RD, 0,
+    "PAX related logging facility.");
+
+SYSCTL_PROC(_security_pax_log, OID_AUTO, log,
+    CTLTYPE_INT|CTLFLAG_RWTUN|CTLFLAG_PRISON|CTLFLAG_SECURE,
+    NULL, 0, sysctl_pax_log_log, "I",
+    "log to syslog "
+    "0 - disabled, "
+    "1 - enabled ");
+TUNABLE_INT("security.pax.log.log", &pax_log_log);
+
+SYSCTL_PROC(_security_pax_log, OID_AUTO, ulog,
+    CTLTYPE_INT|CTLFLAG_RWTUN|CTLFLAG_PRISON|CTLFLAG_SECURE,
+    NULL, 0, sysctl_pax_log_ulog, "I",
+    "log to user terminal"
+    "0 - disabled, "
+    "1 - enabled ");
+TUNABLE_INT("security.pax.log.ulog", &pax_log_ulog);
+
+static int
+sysctl_pax_log_log(SYSCTL_HANDLER_ARGS)
+{
+	int err;
+	int val;
+	struct prison *pr=3DNULL;
+
+	pr =3D pax_get_prison(req->td, NULL);
+
+	if ((pr !=3D NULL) && !(pr->pr_pax_set))
+		pax_init_prison(pr);
+
+	val =3D (pr !=3D NULL) ? pr->pr_pax_log_log : pax_log_log;
+	err =3D sysctl_handle_int(oidp, &val, sizeof(int), req);
+	if (err || !req->newptr)
+		return (err);
+
+	switch (val) {
+	case	0:
+	case	1:
+		break;
+	default:
+		return (EINVAL);
+
+	}
+
+	if ((pr =3D=3D NULL) || (pr =3D=3D &prison0))
+		pax_log_log =3D val;
+	if (pr !=3D NULL)
+		pr->pr_pax_log_log =3D val;
+
+	return (0);
+}
+
+static int
+sysctl_pax_log_ulog(SYSCTL_HANDLER_ARGS)
+{
+	int err;
+	int val;
+	struct prison *pr=3DNULL;
+
+	pr =3D pax_get_prison(req->td, NULL);
+
+	if ((pr !=3D NULL) && !(pr->pr_pax_set))
+		pax_init_prison(pr);
+
+	val =3D (pr !=3D NULL) ? pr->pr_pax_log_ulog : pax_log_ulog;
+	err =3D sysctl_handle_int(oidp, &val, sizeof(int), req);
+	if (err || !req->newptr)
+		return (err);
+
+	switch (val) {
+	case	0:
+	case	1:
+		break;
+	default:
+		return (EINVAL);
+
+	}
+
+	if ((pr =3D=3D NULL) || (pr =3D=3D &prison0))
+		pax_log_ulog =3D val;
+	if (pr !=3D NULL)
+		pr->pr_pax_log_ulog =3D val;
+
+	return (0);
+}
+
+
+__PAX_LOG_TEMPLATE(ASLR, aslr)
diff --git a/sys/mips/mips/elf_machdep.c b/sys/mips/mips/elf_machdep.c
index d374713..f95ba35 100644
--- a/sys/mips/mips/elf_machdep.c
+++ b/sys/mips/mips/elf_machdep.c
@@ -28,6 +28,8 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
=20
+#include "opt_pax.h"
+
 #include <sys/param.h>
 #include <sys/kernel.h>
 #include <sys/systm.h>
@@ -49,6 +51,10 @@ __FBSDID("$FreeBSD$");
 #include <machine/md_var.h>
 #include <machine/cache.h>
=20
+#ifdef PAX_ASLR
+#include <sys/pax.h>
+#endif
+
 #ifdef __mips_n64
 struct sysentvec elf64_freebsd_sysvec =3D {
 	.sv_size	=3D SYS_MAXSYSCALL,
@@ -83,6 +89,11 @@ struct sysentvec elf64_freebsd_sysvec =3D {
 	.sv_fetch_syscall_args =3D cpu_fetch_syscall_args,
 	.sv_syscallnames =3D syscallnames,
 	.sv_schedtail	=3D NULL,
+#ifdef PAX_ASLR
+	.sv_pax_aslr_init =3D _pax_aslr_init,
+#else
+	.sv_pax_aslr_init =3D NULL,
+#endif
 };
=20
 static Elf64_Brandinfo freebsd_brand_info =3D {
@@ -139,6 +150,11 @@ struct sysentvec elf32_freebsd_sysvec =3D {
 	.sv_fetch_syscall_args =3D cpu_fetch_syscall_args,
 	.sv_syscallnames =3D syscallnames,
 	.sv_schedtail	=3D NULL,
+#ifdef PAX_ASLR
+	.sv_pax_aslr_init =3D _pax_aslr_init32,
+#else
+	.sv_pax_aslr_init =3D NULL,
+#endif
 };
=20
 static Elf32_Brandinfo freebsd_brand_info =3D {
diff --git a/sys/mips/mips/freebsd32_machdep.c b/sys/mips/mips/freebsd32_ma=
chdep.c
index dfdf70f..103ad84 100644
--- a/sys/mips/mips/freebsd32_machdep.c
+++ b/sys/mips/mips/freebsd32_machdep.c
@@ -31,6 +31,7 @@
  */
=20
 #include "opt_compat.h"
+#include "opt_pax.h"
=20
 #define __ELF_WORD_SIZE 32
=20
@@ -66,6 +67,10 @@
 #include <compat/freebsd32/freebsd32_util.h>
 #include <compat/freebsd32/freebsd32_proto.h>
=20
+#ifdef PAX_ASLR
+#include <sys/pax.h>
+#endif
+
 static void freebsd32_exec_setregs(struct thread *, struct image_params *,=
 u_long);
 static int get_mcontext32(struct thread *, mcontext32_t *, int);
 static int set_mcontext32(struct thread *, const mcontext32_t *);
@@ -106,6 +111,11 @@ struct sysentvec elf32_freebsd_sysvec =3D {
 	.sv_fetch_syscall_args =3D cpu_fetch_syscall_args,
 	.sv_syscallnames =3D freebsd32_syscallnames,
 	.sv_schedtail	=3D NULL,
+#ifdef PAX_ASLR
+	.sv_pax_aslr_init =3D _pax_aslr_init32,
+#else
+	.sv_pax_aslr_init =3D NULL,
+#endif
 };
 INIT_SYSENTVEC(elf32_sysvec, &elf32_freebsd_sysvec);
=20
diff --git a/sys/powerpc/powerpc/elf32_machdep.c b/sys/powerpc/powerpc/elf3=
2_machdep.c
index dbe58df..229fe97 100644
--- a/sys/powerpc/powerpc/elf32_machdep.c
+++ b/sys/powerpc/powerpc/elf32_machdep.c
@@ -25,6 +25,8 @@
  * $FreeBSD$
  */
=20
+#include "opt_pax.h"
+
 #include <sys/param.h>
 #include <sys/kernel.h>
 #include <sys/systm.h>
@@ -52,6 +54,10 @@
 #include <machine/reg.h>
 #include <machine/md_var.h>
=20
+#ifdef PAX_ASLR
+#include <sys/pax.h>
+#endif
+
 #ifdef __powerpc64__
 #include <compat/freebsd32/freebsd32_proto.h>
 #include <compat/freebsd32/freebsd32_util.h>
@@ -107,6 +113,11 @@ struct sysentvec elf32_freebsd_sysvec =3D {
 	.sv_shared_page_base =3D FREEBSD32_SHAREDPAGE,
 	.sv_shared_page_len =3D PAGE_SIZE,
 	.sv_schedtail	=3D NULL,
+#ifdef PAX_ASLR
+	.sv_pax_aslr_init =3D _pax_aslr_init32,
+#else
+	.sv_pax_aslr_init =3D NULL,
+#endif
 };
 INIT_SYSENTVEC(elf32_sysvec, &elf32_freebsd_sysvec);
=20
diff --git a/sys/powerpc/powerpc/elf64_machdep.c b/sys/powerpc/powerpc/elf6=
4_machdep.c
index 0c41a8d..095f37b0 100644
--- a/sys/powerpc/powerpc/elf64_machdep.c
+++ b/sys/powerpc/powerpc/elf64_machdep.c
@@ -25,6 +25,8 @@
  * $FreeBSD$
  */
=20
+#include "opt_pax.h"
+
 #include <sys/param.h>
 #include <sys/kernel.h>
 #include <sys/systm.h>
@@ -48,6 +50,10 @@
 #include <machine/elf.h>
 #include <machine/md_var.h>
=20
+#ifdef PAX_ASLR
+#include <sys/pax.h>
+#endif
+
 struct sysentvec elf64_freebsd_sysvec =3D {
 	.sv_size	=3D SYS_MAXSYSCALL,
 	.sv_table	=3D sysent,
@@ -83,6 +89,11 @@ struct sysentvec elf64_freebsd_sysvec =3D {
 	.sv_shared_page_base =3D SHAREDPAGE,
 	.sv_shared_page_len =3D PAGE_SIZE,
 	.sv_schedtail	=3D NULL,
+#ifdef PAX_ASLR
+	.sv_pax_aslr_init =3D _pax_aslr_init,
+#else
+	.sv_pax_aslr_init =3D NULL,
+#endif
 };
 INIT_SYSENTVEC(elf64_sysvec, &elf64_freebsd_sysvec);
=20
diff --git a/sys/security/mac_bsdextended/mac_bsdextended.c b/sys/security/=
mac_bsdextended/mac_bsdextended.c
index ccbc525..520168d 100644
--- a/sys/security/mac_bsdextended/mac_bsdextended.c
+++ b/sys/security/mac_bsdextended/mac_bsdextended.c
@@ -47,6 +47,8 @@
  * firewall-like rules regarding users and file system objects.
  */
=20
+#include "opt_pax.h"
+
 #include <sys/param.h>
 #include <sys/acl.h>
 #include <sys/kernel.h>
@@ -56,14 +58,20 @@
 #include <sys/module.h>
 #include <sys/mount.h>
 #include <sys/mutex.h>
+#include <sys/param.h>
 #include <sys/priv.h>
 #include <sys/proc.h>
 #include <sys/systm.h>
 #include <sys/vnode.h>
 #include <sys/sysctl.h>
 #include <sys/syslog.h>
+#include <sys/syslimits.h>
 #include <sys/stat.h>
=20
+#ifdef PAX_ASLR
+#include <sys/pax.h>
+#endif
+
 #include <security/mac/mac_policy.h>
 #include <security/mac_bsdextended/mac_bsdextended.h>
 #include <security/mac_bsdextended/ugidfw_internal.h>
@@ -117,7 +125,6 @@ SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, firstma=
tch_enabled,
 static int
 ugidfw_rule_valid(struct mac_bsdextended_rule *rule)
 {
-
 	if ((rule->mbr_subject.mbs_flags | MBS_ALL_FLAGS) !=3D MBS_ALL_FLAGS)
 		return (EINVAL);
 	if ((rule->mbr_subject.mbs_neg | MBS_ALL_FLAGS) !=3D MBS_ALL_FLAGS)
@@ -129,8 +136,13 @@ ugidfw_rule_valid(struct mac_bsdextended_rule *rule)
 	if ((rule->mbr_object.mbo_neg | MBO_TYPE_DEFINED) &&
 	    (rule->mbr_object.mbo_type | MBO_ALL_TYPE) !=3D MBO_ALL_TYPE)
 		return (EINVAL);
+#ifdef PAX_ASLR
+	if ((rule->mbr_pax | MBI_ALLPAX) !=3D MBI_ALLPAX)
+		return (EINVAL);
+#endif
 	if ((rule->mbr_mode | MBI_ALLPERM) !=3D MBI_ALLPERM)
 		return (EINVAL);
+
 	return (0);
 }
=20
@@ -227,7 +239,7 @@ ugidfw_destroy(struct mac_policy_conf *mpc)
=20
 static int
 ugidfw_rulecheck(struct mac_bsdextended_rule *rule,
-    struct ucred *cred, struct vnode *vp, struct vattr *vap, int acc_mode)
+    struct ucred *cred, struct vnode *vp, struct vattr *vap, int acc_mode,=
 struct image_params *imgp)
 {
 	int mac_granted, match, priv_granted;
 	int i;
@@ -305,6 +317,10 @@ ugidfw_rulecheck(struct mac_bsdextended_rule *rule,
 		match =3D (bcmp(&(vp->v_mount->mnt_stat.f_fsid),
 		    &(rule->mbr_object.mbo_fsid),
 		    sizeof(rule->mbr_object.mbo_fsid)) =3D=3D 0);
+#if defined(PAX_ASLR)
+		if (match && rule->mbr_object.mbo_inode)
+			match =3D (vap->va_fileid =3D=3D rule->mbr_object.mbo_inode);
+#endif
 		if (rule->mbr_object.mbo_neg & MBO_FSID_DEFINED)
 			match =3D !match;
 		if (!match)
@@ -413,6 +429,11 @@ ugidfw_rulecheck(struct mac_bsdextended_rule *rule,
 		return (EACCES);
 	}
=20
+#ifdef PAX_ASLR
+	if (imgp !=3D NULL)
+		pax_elf(imgp, rule->mbr_pax);
+#endif
+
 	/*
 	 * If the rule matched, permits access, and first match is enabled,
 	 * return success.
@@ -425,7 +446,7 @@ ugidfw_rulecheck(struct mac_bsdextended_rule *rule,
=20
 int
 ugidfw_check(struct ucred *cred, struct vnode *vp, struct vattr *vap,
-    int acc_mode)
+    int acc_mode, struct image_params *imgp)
 {
 	int error, i;
=20
@@ -441,7 +462,7 @@ ugidfw_check(struct ucred *cred, struct vnode *vp, stru=
ct vattr *vap,
 		if (rules[i] =3D=3D NULL)
 			continue;
 		error =3D ugidfw_rulecheck(rules[i], cred,
-		    vp, vap, acc_mode);
+		    vp, vap, acc_mode, imgp);
 		if (error =3D=3D EJUSTRETURN)
 			break;
 		if (error) {
@@ -454,7 +475,7 @@ ugidfw_check(struct ucred *cred, struct vnode *vp, stru=
ct vattr *vap,
 }
=20
 int
-ugidfw_check_vp(struct ucred *cred, struct vnode *vp, int acc_mode)
+ugidfw_check_vp(struct ucred *cred, struct vnode *vp, int acc_mode, struct=
 image_params *imgp)
 {
 	int error;
 	struct vattr vap;
@@ -464,7 +485,7 @@ ugidfw_check_vp(struct ucred *cred, struct vnode *vp, i=
nt acc_mode)
 	error =3D VOP_GETATTR(vp, &vap, cred);
 	if (error)
 		return (error);
-	return (ugidfw_check(cred, vp, &vap, acc_mode));
+	return (ugidfw_check(cred, vp, &vap, acc_mode, imgp));
 }
=20
 int
diff --git a/sys/security/mac_bsdextended/mac_bsdextended.h b/sys/security/=
mac_bsdextended/mac_bsdextended.h
index c09abc0..c3cbf28 100644
--- a/sys/security/mac_bsdextended/mac_bsdextended.h
+++ b/sys/security/mac_bsdextended/mac_bsdextended.h
@@ -51,6 +51,9 @@
 #define	MBI_ADMIN	010000
 #define	MBI_STAT	020000
 #define	MBI_APPEND	040000
+#define MBI_FORCE_ASLR_ENABLED          0x01
+#define MBI_FORCE_ASLR_DISABLED         0x02
+#define MBI_ALLPAX (MBI_FORCE_ASLR_ENABLED | MBI_FORCE_ASLR_DISABLED)
 #define	MBI_ALLPERM	(MBI_EXEC | MBI_WRITE | MBI_READ | MBI_ADMIN | \
 			    MBI_STAT | MBI_APPEND)
=20
@@ -78,6 +81,7 @@ struct mac_bsdextended_subject {
 #define	MBO_UID_SUBJECT	0x00000020	/* uid must match subject */
 #define	MBO_GID_SUBJECT	0x00000040	/* gid must match subject */
 #define	MBO_TYPE_DEFINED 0x00000080	/* object type should be matched */
+#define MBO_PAXPATH_DEFINED 0x00000100 /* TODO: paxpath should be matched =
*/
=20
 #define MBO_ALL_FLAGS (MBO_UID_DEFINED | MBO_GID_DEFINED | MBO_FSID_DEFINE=
D | \
 	    MBO_SUID | MBO_SGID | MBO_UID_SUBJECT | MBO_GID_SUBJECT | \
@@ -103,12 +107,15 @@ struct mac_bsdextended_object {
 	gid_t	mbo_gid_max;
 	struct fsid mbo_fsid;
 	int	mbo_type;
+	ino_t	mbo_inode;
+	char	mbo_paxpath[MAXPATHLEN];
 };
=20
 struct mac_bsdextended_rule {
 	struct mac_bsdextended_subject	mbr_subject;
 	struct mac_bsdextended_object	mbr_object;
 	mode_t				mbr_mode;	/* maximum access */
+	uint32_t			mbr_pax;
 };
=20
 #endif /* _SYS_SECURITY_MAC_BSDEXTENDED_H */
diff --git a/sys/security/mac_bsdextended/ugidfw_internal.h b/sys/security/=
mac_bsdextended/ugidfw_internal.h
index 5597fd1..18c74dc 100644
--- a/sys/security/mac_bsdextended/ugidfw_internal.h
+++ b/sys/security/mac_bsdextended/ugidfw_internal.h
@@ -36,8 +36,9 @@
  */
 int	ugidfw_accmode2mbi(accmode_t accmode);
 int	ugidfw_check(struct ucred *cred, struct vnode *vp, struct vattr *vap,
-	    int acc_mode);
-int	ugidfw_check_vp(struct ucred *cred, struct vnode *vp, int acc_mode);
+	    int acc_mode, struct image_params *imgp);
+int	ugidfw_check_vp(struct ucred *cred, struct vnode *vp, int acc_mode,
+	    struct image_params *imgp);
=20
 /*
  * System access control checks.
diff --git a/sys/security/mac_bsdextended/ugidfw_system.c b/sys/security/ma=
c_bsdextended/ugidfw_system.c
index 49e4f1d..2829a00 100644
--- a/sys/security/mac_bsdextended/ugidfw_system.c
+++ b/sys/security/mac_bsdextended/ugidfw_system.c
@@ -66,7 +66,7 @@ ugidfw_system_check_acct(struct ucred *cred, struct vnode=
 *vp,
 {
=20
 	if (vp !=3D NULL)
-		return (ugidfw_check_vp(cred, vp, MBI_WRITE));
+		return (ugidfw_check_vp(cred, vp, MBI_WRITE, NULL));
 	else
 		return (0);
 }
@@ -77,7 +77,7 @@ ugidfw_system_check_auditctl(struct ucred *cred, struct v=
node *vp,
 {
=20
 	if (vp !=3D NULL)
-		return (ugidfw_check_vp(cred, vp, MBI_WRITE));
+		return (ugidfw_check_vp(cred, vp, MBI_WRITE, NULL));
 	else
 		return (0);
 }
@@ -87,5 +87,5 @@ ugidfw_system_check_swapon(struct ucred *cred, struct vno=
de *vp,
     struct label *vplabel)
 {
=20
-	return (ugidfw_check_vp(cred, vp, MBI_WRITE));
+	return (ugidfw_check_vp(cred, vp, MBI_WRITE, NULL));
 }
diff --git a/sys/security/mac_bsdextended/ugidfw_vnode.c b/sys/security/mac=
_bsdextended/ugidfw_vnode.c
index 8ec2d48..2065e6e 100644
--- a/sys/security/mac_bsdextended/ugidfw_vnode.c
+++ b/sys/security/mac_bsdextended/ugidfw_vnode.c
@@ -65,7 +65,7 @@ ugidfw_vnode_check_access(struct ucred *cred, struct vnod=
e *vp,
     struct label *vplabel, accmode_t accmode)
 {
=20
-	return (ugidfw_check_vp(cred, vp, ugidfw_accmode2mbi(accmode)));
+	return (ugidfw_check_vp(cred, vp, ugidfw_accmode2mbi(accmode), NULL));
 }
=20
 int
@@ -73,7 +73,7 @@ ugidfw_vnode_check_chdir(struct ucred *cred, struct vnode=
 *dvp,
     struct label *dvplabel)
 {
=20
-	return (ugidfw_check_vp(cred, dvp, MBI_EXEC));
+	return (ugidfw_check_vp(cred, dvp, MBI_EXEC, NULL));
 }
=20
 int
@@ -81,7 +81,7 @@ ugidfw_vnode_check_chroot(struct ucred *cred, struct vnod=
e *dvp,
     struct label *dvplabel)
 {
=20
-	return (ugidfw_check_vp(cred, dvp, MBI_EXEC));
+	return (ugidfw_check_vp(cred, dvp, MBI_EXEC, NULL));
 }
=20
 int
@@ -89,7 +89,7 @@ ugidfw_check_create_vnode(struct ucred *cred, struct vnod=
e *dvp,
     struct label *dvplabel, struct componentname *cnp, struct vattr *vap)
 {
=20
-	return (ugidfw_check_vp(cred, dvp, MBI_WRITE));
+	return (ugidfw_check_vp(cred, dvp, MBI_WRITE, NULL));
 }
=20
 int
@@ -97,7 +97,7 @@ ugidfw_vnode_check_deleteacl(struct ucred *cred, struct v=
node *vp,
     struct label *vplabel, acl_type_t type)
 {
=20
-	return (ugidfw_check_vp(cred, vp, MBI_ADMIN));
+	return (ugidfw_check_vp(cred, vp, MBI_ADMIN, NULL));
 }
=20
 int
@@ -105,7 +105,7 @@ ugidfw_vnode_check_deleteextattr(struct ucred *cred, st=
ruct vnode *vp,
     struct label *vplabel, int attrnamespace, const char *name)
 {
=20
-	return (ugidfw_check_vp(cred, vp, MBI_WRITE));
+	return (ugidfw_check_vp(cred, vp, MBI_WRITE, NULL));
 }
=20
 int
@@ -114,7 +114,7 @@ ugidfw_vnode_check_exec(struct ucred *cred, struct vnod=
e *vp,
     struct label *execlabel)
 {
=20
-	return (ugidfw_check_vp(cred, vp, MBI_READ|MBI_EXEC));
+	return (ugidfw_check_vp(cred, vp, MBI_READ|MBI_EXEC, imgp));
 }
=20
 int
@@ -122,7 +122,7 @@ ugidfw_vnode_check_getacl(struct ucred *cred, struct vn=
ode *vp,
     struct label *vplabel, acl_type_t type)
 {
=20
-	return (ugidfw_check_vp(cred, vp, MBI_STAT));
+	return (ugidfw_check_vp(cred, vp, MBI_STAT, NULL));
 }
=20
 int
@@ -130,7 +130,7 @@ ugidfw_vnode_check_getextattr(struct ucred *cred, struc=
t vnode *vp,
     struct label *vplabel, int attrnamespace, const char *name)
 {
=20
-	return (ugidfw_check_vp(cred, vp, MBI_READ));
+	return (ugidfw_check_vp(cred, vp, MBI_READ, NULL));
 }
=20
 int
@@ -140,10 +140,10 @@ ugidfw_vnode_check_link(struct ucred *cred, struct vn=
ode *dvp,
 {
 	int error;
=20
-	error =3D ugidfw_check_vp(cred, dvp, MBI_WRITE);
+	error =3D ugidfw_check_vp(cred, dvp, MBI_WRITE, NULL);
 	if (error)
 		return (error);
-	error =3D ugidfw_check_vp(cred, vp, MBI_WRITE);
+	error =3D ugidfw_check_vp(cred, vp, MBI_WRITE, NULL);
 	if (error)
 		return (error);
 	return (0);
@@ -154,7 +154,7 @@ ugidfw_vnode_check_listextattr(struct ucred *cred, stru=
ct vnode *vp,
     struct label *vplabel, int attrnamespace)
 {
=20
-	return (ugidfw_check_vp(cred, vp, MBI_READ));
+	return (ugidfw_check_vp(cred, vp, MBI_READ, NULL));
 }
=20
 int
@@ -162,7 +162,7 @@ ugidfw_vnode_check_lookup(struct ucred *cred, struct vn=
ode *dvp,
     struct label *dvplabel, struct componentname *cnp)
 {
=20
-	return (ugidfw_check_vp(cred, dvp, MBI_EXEC));
+	return (ugidfw_check_vp(cred, dvp, MBI_EXEC, NULL));
 }
=20
 int
@@ -170,7 +170,7 @@ ugidfw_vnode_check_open(struct ucred *cred, struct vnod=
e *vp,
     struct label *vplabel, accmode_t accmode)
 {
=20
-	return (ugidfw_check_vp(cred, vp, ugidfw_accmode2mbi(accmode)));
+	return (ugidfw_check_vp(cred, vp, ugidfw_accmode2mbi(accmode), NULL));
 }
=20
 int
@@ -178,7 +178,7 @@ ugidfw_vnode_check_readdir(struct ucred *cred, struct v=
node *dvp,
     struct label *dvplabel)
 {
=20
-	return (ugidfw_check_vp(cred, dvp, MBI_READ));
+	return (ugidfw_check_vp(cred, dvp, MBI_READ, NULL));
 }
=20
 int
@@ -186,7 +186,7 @@ ugidfw_vnode_check_readdlink(struct ucred *cred, struct=
 vnode *vp,
     struct label *vplabel)
 {
=20
-	return (ugidfw_check_vp(cred, vp, MBI_READ));
+	return (ugidfw_check_vp(cred, vp, MBI_READ, NULL));
 }
=20
 int
@@ -196,10 +196,10 @@ ugidfw_vnode_check_rename_from(struct ucred *cred, st=
ruct vnode *dvp,
 {
 	int error;
=20
-	error =3D ugidfw_check_vp(cred, dvp, MBI_WRITE);
+	error =3D ugidfw_check_vp(cred, dvp, MBI_WRITE, NULL);
 	if (error)
 		return (error);
-	return (ugidfw_check_vp(cred, vp, MBI_WRITE));
+	return (ugidfw_check_vp(cred, vp, MBI_WRITE, NULL));
 }
=20
 int
@@ -209,11 +209,11 @@ ugidfw_vnode_check_rename_to(struct ucred *cred, stru=
ct vnode *dvp,
 {
 	int error;
=20
-	error =3D ugidfw_check_vp(cred, dvp, MBI_WRITE);
+	error =3D ugidfw_check_vp(cred, dvp, MBI_WRITE, NULL);
 	if (error)
 		return (error);
 	if (vp !=3D NULL)
-		error =3D ugidfw_check_vp(cred, vp, MBI_WRITE);
+		error =3D ugidfw_check_vp(cred, vp, MBI_WRITE, NULL);
 	return (error);
 }
=20
@@ -222,7 +222,7 @@ ugidfw_vnode_check_revoke(struct ucred *cred, struct vn=
ode *vp,
     struct label *vplabel)
 {
=20
-	return (ugidfw_check_vp(cred, vp, MBI_ADMIN));
+	return (ugidfw_check_vp(cred, vp, MBI_ADMIN, NULL));
 }
=20
 int
@@ -230,7 +230,7 @@ ugidfw_check_setacl_vnode(struct ucred *cred, struct vn=
ode *vp,
     struct label *vplabel, acl_type_t type, struct acl *acl)
 {
=20
-	return (ugidfw_check_vp(cred, vp, MBI_ADMIN));
+	return (ugidfw_check_vp(cred, vp, MBI_ADMIN, NULL));
 }
=20
 int
@@ -238,7 +238,7 @@ ugidfw_vnode_check_setextattr(struct ucred *cred, struc=
t vnode *vp,
     struct label *vplabel, int attrnamespace, const char *name)
 {
=20
-	return (ugidfw_check_vp(cred, vp, MBI_WRITE));
+	return (ugidfw_check_vp(cred, vp, MBI_WRITE, NULL));
 }
=20
 int
@@ -246,7 +246,7 @@ ugidfw_vnode_check_setflags(struct ucred *cred, struct =
vnode *vp,
     struct label *vplabel, u_long flags)
 {
=20
-	return (ugidfw_check_vp(cred, vp, MBI_ADMIN));
+	return (ugidfw_check_vp(cred, vp, MBI_ADMIN, NULL));
 }
=20
 int
@@ -254,7 +254,7 @@ ugidfw_vnode_check_setmode(struct ucred *cred, struct v=
node *vp,
     struct label *vplabel, mode_t mode)
 {
=20
-	return (ugidfw_check_vp(cred, vp, MBI_ADMIN));
+	return (ugidfw_check_vp(cred, vp, MBI_ADMIN, NULL));
 }
=20
 int
@@ -262,7 +262,7 @@ ugidfw_vnode_check_setowner(struct ucred *cred, struct =
vnode *vp,
     struct label *vplabel, uid_t uid, gid_t gid)
 {
=20
-	return (ugidfw_check_vp(cred, vp, MBI_ADMIN));
+	return (ugidfw_check_vp(cred, vp, MBI_ADMIN, NULL));
 }
=20
 int
@@ -270,7 +270,7 @@ ugidfw_vnode_check_setutimes(struct ucred *cred, struct=
 vnode *vp,
     struct label *vplabel, struct timespec atime, struct timespec utime)
 {
=20
-	return (ugidfw_check_vp(cred, vp, MBI_ADMIN));
+	return (ugidfw_check_vp(cred, vp, MBI_ADMIN, NULL));
 }
=20
 int
@@ -278,7 +278,7 @@ ugidfw_vnode_check_stat(struct ucred *active_cred,
     struct ucred *file_cred, struct vnode *vp, struct label *vplabel)
 {
=20
-	return (ugidfw_check_vp(active_cred, vp, MBI_STAT));
+	return (ugidfw_check_vp(active_cred, vp, MBI_STAT, NULL));
 }
=20
 int
@@ -288,8 +288,8 @@ ugidfw_vnode_check_unlink(struct ucred *cred, struct vn=
ode *dvp,
 {
 	int error;
=20
-	error =3D ugidfw_check_vp(cred, dvp, MBI_WRITE);
+	error =3D ugidfw_check_vp(cred, dvp, MBI_WRITE, NULL);
 	if (error)
 		return (error);
-	return (ugidfw_check_vp(cred, vp, MBI_WRITE));
+	return (ugidfw_check_vp(cred, vp, MBI_WRITE, NULL));
 }
diff --git a/sys/sparc64/sparc64/elf_machdep.c b/sys/sparc64/sparc64/elf_ma=
chdep.c
index 4d55717..e0eba33 100644
--- a/sys/sparc64/sparc64/elf_machdep.c
+++ b/sys/sparc64/sparc64/elf_machdep.c
@@ -34,6 +34,8 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
=20
+#include "opt_pax.h"
+
 #include <sys/param.h>
 #include <sys/kernel.h>
 #include <sys/systm.h>
@@ -52,6 +54,10 @@ __FBSDID("$FreeBSD$");
=20
 #include <machine/elf.h>
=20
+#ifdef PAX_ASLR
+#include <sys/pax.h>
+#endif
+
 #include "linker_if.h"
=20
 static struct sysentvec elf64_freebsd_sysvec =3D {
@@ -87,6 +93,11 @@ static struct sysentvec elf64_freebsd_sysvec =3D {
 	.sv_fetch_syscall_args =3D cpu_fetch_syscall_args,
 	.sv_syscallnames =3D syscallnames,
 	.sv_schedtail	=3D NULL,
+#ifdef PAX_ASLR
+	.sv_pax_aslr_init =3D _pax_aslr_init,
+#else
+	.sv_pax_aslr_init =3D NULL,
+#endif
 };
=20
 static Elf64_Brandinfo freebsd_brand_info =3D {
diff --git a/sys/sys/imgact.h b/sys/sys/imgact.h
index 17cfcc2..15c2c4f 100644
--- a/sys/sys/imgact.h
+++ b/sys/sys/imgact.h
@@ -78,6 +78,7 @@ struct image_params {
 	unsigned long pagesizes;
 	int pagesizeslen;
 	vm_prot_t stack_prot;
+	int pax_flags;
 };
=20
 #ifdef _KERNEL
diff --git a/sys/sys/jail.h b/sys/sys/jail.h
index 59d791c..699b21c 100644
--- a/sys/sys/jail.h
+++ b/sys/sys/jail.h
@@ -184,6 +184,19 @@ struct prison {
 	char		 pr_hostname[MAXHOSTNAMELEN];	/* (p) jail hostname */
 	char		 pr_domainname[MAXHOSTNAMELEN];	/* (p) jail domainname */
 	char		 pr_hostuuid[HOSTUUIDLEN];	/* (p) jail hostuuid */
+    /* Lock only needed for pax_* if pr_pax_set =3D=3D 0 */
+	int		 pr_pax_set;			/* (p) PaX settings initialized */
+	int		 pr_pax_aslr_status;		/* (p) PaX ASLR enabled */
+	int		 pr_pax_aslr_debug;		/* (p) PaX ASLR debug */
+	int		 pr_pax_aslr_mmap_len;		/* (p) Number of bits randomized with mmap */
+	int		 pr_pax_aslr_stack_len;		/* (p) Number of bits randomized with stack=
 */
+	int		 pr_pax_aslr_exec_len;		/* (p) Number of bits randomized with the ex=
ecbase */
+	int		 pr_pax_aslr_compat_status;	/* (p) PaX ASLR enabled (compat32) */
+	int		 pr_pax_aslr_compat_mmap_len;	/* (p) Number of bits randomized with =
mmap (compat32) */
+	int		 pr_pax_aslr_compat_stack_len;	/* (p) Number of bits randomized with=
 stack (compat32) */
+	int		 pr_pax_aslr_compat_exec_len;	/* (p) Number of bits randomized with =
the execbase (compat32) */
+	int		 pr_pax_log_log;		/* (p) XXX */
+	int		 pr_pax_log_ulog;		/* (p) XXX */
 };
=20
 struct prison_racct {
diff --git a/sys/sys/kernel.h b/sys/sys/kernel.h
index 3c5258a..aedb52e 100644
--- a/sys/sys/kernel.h
+++ b/sys/sys/kernel.h
@@ -102,6 +102,7 @@ enum sysinit_sub_id {
 	SI_SUB_WITNESS		=3D 0x1A80000,	/* witness initialization */
 	SI_SUB_MTX_POOL_DYNAMIC	=3D 0x1AC0000,	/* dynamic mutex pool */
 	SI_SUB_LOCK		=3D 0x1B00000,	/* various locks */
+	SI_SUB_PAX		=3D 0x1B50000,	/* pax setup */
 	SI_SUB_EVENTHANDLER	=3D 0x1C00000,	/* eventhandler init */
 	SI_SUB_VNET_PRELINK	=3D 0x1E00000,	/* vnet init before modules */
 	SI_SUB_KLD		=3D 0x2000000,	/* KLD and module setup */
diff --git a/sys/sys/pax.h b/sys/sys/pax.h
new file mode 100644
index 0000000..a0f2bf6
--- /dev/null
+++ b/sys/sys/pax.h
@@ -0,0 +1,226 @@
+/*-
+ * Copyright (c) 2006 Elad Efrat <elad@NetBSD.org>
+ * Copyright (c) 2013-2014, by Oliver Pinter <oliver.pntr at gmail.com>
+ * Copyright (c) 2014, by Shawn Webb <lattera at gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTI=
ES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF US=
E,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef	__SYS_PAX_H
+#define	__SYS_PAX_H
+
+struct image_params;
+struct prison;
+struct thread;
+struct vnode;
+struct vmspace;
+struct vm_offset_t;
+
+/*
+ * used in sysctl handler
+ */
+#define PAX_ASLR_DISABLED	0
+#define PAX_ASLR_OPTIN		1
+#define PAX_ASLR_OPTOUT		2
+#define PAX_ASLR_FORCE_ENABLED	3
+
+#ifndef PAX_ASLR_DELTA
+#define	PAX_ASLR_DELTA(delta, lsb, len)	\
+	(((delta) & ((1UL << (len)) - 1)) << (lsb))
+#endif /* PAX_ASLR_DELTA */
+
+#ifdef PAX_ASLR
+/*
+ * generic ASLR values
+ *
+ *  	MMAP	| 32 bit | 64 bit |
+ * 	+-------+--------+--------+
+ * 	| MIN	|  8 bit | 16 bit |
+ * 	+-------+--------+--------+
+ * 	| DEF	|  8 bit | 21 bit |
+ * 	+-------+--------+--------+
+ * 	| MAX   | 16 bit | 32 bit |
+ * 	+-------+--------+--------+
+ *
+ *  	STACK	| 32 bit | 64 bit |
+ * 	+-------+--------+--------+
+ * 	| MIN	|  6 bit | 12 bit |
+ * 	+-------+--------+--------+
+ * 	| DEF	|  6 bit | 16 bit |
+ * 	+-------+--------+--------+
+ * 	| MAX   | 10 bit | 21 bit |
+ * 	+-------+--------+--------+
+ *
+ *  	EXEC	| 32 bit | 64 bit |
+ * 	+-------+--------+--------+
+ * 	| MIN	|  6 bit | 12 bit |
+ * 	+-------+--------+--------+
+ * 	| DEF	|  6 bit | 21 bit |
+ * 	+-------+--------+--------+
+ * 	| MAX   | 10 bit | 21 bit |
+ * 	+-------+--------+--------+
+ *
+ */
+#ifndef PAX_ASLR_DELTA_MMAP_LSB
+#define PAX_ASLR_DELTA_MMAP_LSB		PAGE_SHIFT
+#endif /* PAX_ASLR_DELTA_MMAP_LSB */
+
+#ifndef PAX_ASLR_DELTA_MMAP_MIN_LEN
+#define PAX_ASLR_DELTA_MMAP_MIN_LEN	((sizeof(void *) * NBBY) / 4)
+#endif /* PAX_ASLR_DELTA_MMAP_MAX_LEN */
+
+#ifndef PAX_ASLR_DELTA_MMAP_MAX_LEN
+#define PAX_ASLR_DELTA_MMAP_MAX_LEN	((sizeof(void *) * NBBY) / 2)
+#endif /* PAX_ASLR_DELTA_MMAP_MAX_LEN */
+
+#ifndef PAX_ASLR_DELTA_STACK_LSB
+#define PAX_ASLR_DELTA_STACK_LSB	3
+#endif /* PAX_ASLR_DELTA_STACK_LSB */
+
+#ifndef PAX_ASLR_DELTA_STACK_MIN_LEN
+#define PAX_ASLR_DELTA_STACK_MIN_LEN	((sizeof(void *) * NBBY) / 5)
+#endif /* PAX_ASLR_DELTA_STACK_MAX_LEN */
+
+#ifndef PAX_ASLR_DELTA_STACK_MAX_LEN
+#define PAX_ASLR_DELTA_STACK_MAX_LEN	((sizeof(void *) * NBBY) / 3)
+#endif /* PAX_ASLR_DELTA_STACK_MAX_LEN */
+
+#ifndef PAX_ASLR_DELTA_EXEC_LSB
+#define PAX_ASLR_DELTA_EXEC_LSB		PAGE_SHIFT
+#endif /* PAX_ASLR_DELTA_EXEC_LSB */
+
+#ifndef PAX_ASLR_DELTA_EXEC_MIN_LEN
+#define PAX_ASLR_DELTA_EXEC_MIN_LEN	((sizeof(void *) * NBBY) / 5)
+#endif /* PAX_ASLR_DELTA_EXEC_MAX_LEN */
+
+#ifndef PAX_ASLR_DELTA_EXEC_MAX_LEN
+#define PAX_ASLR_DELTA_EXEC_MAX_LEN	((sizeof(void *) * NBBY) / 3)
+#endif /* PAX_ASLR_DELTA_EXEC_MAX_LEN */
+
+/*
+ * ASLR default values for native host
+ */
+#ifdef __amd64__
+#ifndef PAX_ASLR_DELTA_MMAP_DEF_LEN
+#define PAX_ASLR_DELTA_MMAP_DEF_LEN	21
+#endif /* PAX_ASLR_DELTA_MMAP_DEF_LEN */
+#ifndef PAX_ASLR_DELTA_STACK_DEF_LEN
+#define PAX_ASLR_DELTA_STACK_DEF_LEN	16
+#endif /* PAX_ASLR_DELTA_STACK_DEF_LEN */
+#ifndef PAX_ASLR_DELTA_EXEC_DEF_LEN
+#define PAX_ASLR_DELTA_EXEC_DEF_LEN	21
+#endif /* PAX_ASLR_DELTA_EXEC_DEF_LEN */
+#else
+#ifndef PAX_ASLR_DELTA_MMAP_DEF_LEN
+#define PAX_ASLR_DELTA_MMAP_DEF_LEN	PAX_ASLR_DELTA_MMAP_MIN_LEN
+#endif /* PAX_ASLR_DELTA_MMAP_DEF_LEN */
+#ifndef PAX_ASLR_DELTA_STACK_DEF_LEN
+#define PAX_ASLR_DELTA_STACK_DEF_LEN	PAX_ASLR_DELTA_STACK_MIN_LEN
+#endif /* PAX_ASLR_DELTA_STACK_DEF_LEN */
+#ifndef PAX_ASLR_DELTA_EXEC_DEF_LEN
+#define PAX_ASLR_DELTA_EXEC_DEF_LEN	PAX_ASLR_DELTA_EXEC_MIN_LEN
+#endif /* PAX_ASLR_DELTA_EXEC_DEF_LEN */
+#endif /* __amd64__ */
+
+/*
+ * ASLR values for COMPAT_FREEBSD32 and COMPAT_LINUX
+ */
+#ifndef PAX_ASLR_COMPAT_DELTA_MMAP_LSB
+#define PAX_ASLR_COMPAT_DELTA_MMAP_LSB		PAGE_SHIFT
+#endif /* PAX_ASLR_COMPAT_DELTA_MMAP_LSB */
+
+#ifndef PAX_ASLR_COMPAT_DELTA_MMAP_MIN_LEN
+#define PAX_ASLR_COMPAT_DELTA_MMAP_MIN_LEN	((sizeof(int) * NBBY) / 4)
+#endif /* PAX_ASLR_COMPAT_DELTA_MMAP_MAX_LEN */
+
+#ifndef PAX_ASLR_COMPAT_DELTA_MMAP_MAX_LEN
+#define PAX_ASLR_COMPAT_DELTA_MMAP_MAX_LEN	((sizeof(int) * NBBY) / 2)
+#endif /* PAX_ASLR_COMPAT_DELTA_MMAP_MAX_LEN */
+
+#ifndef PAX_ASLR_COMPAT_DELTA_STACK_LSB
+#define PAX_ASLR_COMPAT_DELTA_STACK_LSB		3
+#endif /* PAX_ASLR_COMPAT_DELTA_STACK_LSB */
+
+#ifndef PAX_ASLR_COMPAT_DELTA_STACK_MIN_LEN
+#define PAX_ASLR_COMPAT_DELTA_STACK_MIN_LEN	((sizeof(int) * NBBY) / 5)
+#endif /* PAX_ASLR_COMPAT_DELTA_STACK_MAX_LEN */
+
+#ifndef PAX_ASLR_COMPAT_DELTA_STACK_MAX_LEN
+#define PAX_ASLR_COMPAT_DELTA_STACK_MAX_LEN	((sizeof(int) * NBBY) / 3)
+#endif /* PAX_ASLR_COMPAT_DELTA_STACK_MAX_LEN */
+
+#ifndef PAX_ASLR_COMPAT_DELTA_EXEC_MIN_LEN
+#define PAX_ASLR_COMPAT_DELTA_EXEC_MIN_LEN	((sizeof(int) * NBBY) / 5)
+#endif /* PAX_ASLR_COMPAT_DELTA_EXEC_MAX_LEN */
+
+#ifndef PAX_ASLR_COMPAT_DELTA_EXEC_MAX_LEN
+#define PAX_ASLR_COMPAT_DELTA_EXEC_MAX_LEN	((sizeof(int) * NBBY) / 3)
+#endif /* PAX_ASLR_COMPAT_DELTA_EXEC_MAX_LEN */
+
+extern int pax_aslr_status;
+extern int pax_aslr_debug;
+
+extern int pax_aslr_mmap_len;
+extern int pax_aslr_stack_len;
+extern int pax_aslr_exec_len;
+#ifdef COMPAT_FREEBSD32
+extern int pax_aslr_compat_status;
+extern int pax_aslr_compat_mmap_len;
+extern int pax_aslr_compat_stack_len;
+extern int pax_aslr_compat_exec_len;
+#endif /* COMPAT_FREEBSD32 */
+#endif /* PAX_ASLR */
+
+extern int pax_log_log;
+extern int pax_log_ulog;
+
+#define ELF_NOTE_TYPE_PAX_TAG   3
+#define PAX_NOTE_MPROTECT   0x01
+#define PAX_NOTE_NOMPROTECT 0x02
+#define PAX_NOTE_GUARD      0x04
+#define PAX_NOTE_NOGUARD    0x08
+#define PAX_NOTE_ASLR       0x10
+#define PAX_NOTE_NOASLR     0x20
+
+#define PAX_LOG_LOG		0
+#define PAX_LOG_ULOG		0
+
+void pax_init(void);
+void pax_init_prison(struct prison *pr);
+bool pax_aslr_active(struct thread *td, struct proc *proc);
+void _pax_aslr_init(struct vmspace *vm, struct prison *pr);
+void _pax_aslr_init32(struct vmspace *vm, struct prison *pr);
+void pax_aslr_init(struct thread *td, struct image_params *imgp);
+void pax_aslr_mmap(struct thread *td, vm_offset_t *addr,=20
+    vm_offset_t orig_addr, int flags);
+void pax_aslr_stack(struct thread *td, uintptr_t *addr);
+struct prison *pax_get_prison(struct thread *td, struct proc *proc);
+void pax_elf(struct image_params *, uint32_t);
+
+void pax_log_aslr(struct prison *pr, const char *func, const char *fmt, ..=
=2E);
+void pax_ulog_aslr(struct prison *pr, const char *func, const char *fmt, .=
=2E.);
+
+#endif /* __SYS_PAX_H */
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index fbd064c..558d7bf 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -539,6 +539,7 @@ struct proc {
 	u_int		p_stops;	/* (c) Stop event bitmask. */
 	u_int		p_stype;	/* (c) Stop event type. */
 	char		p_step;		/* (c) Process is stopped. */
+	u_int		p_pax;		/* (b) PaX is enabled to this process */
 	u_char		p_pfsflags;	/* (c) Procfs flags. */
 	struct nlminfo	*p_nlminfo;	/* (?) Only used by/for lockd. */
 	struct kaioinfo	*p_aioinfo;	/* (y) ASYNC I/O info. */
diff --git a/sys/sys/sysent.h b/sys/sys/sysent.h
index c49db41..cfbcdc0 100644
--- a/sys/sys/sysent.h
+++ b/sys/sys/sysent.h
@@ -77,9 +77,11 @@ struct sysent {			/* system call table */
 #define	SY_THR_INCR	0x8
=20
 struct image_params;
+struct prison;
 struct __sigset;
 struct syscall_args;
 struct trapframe;
+struct vmspace;
 struct vnode;
=20
 struct sysentvec {
@@ -130,6 +132,7 @@ struct sysentvec {
 	uint32_t	sv_timekeep_gen;
 	void		*sv_shared_page_obj;
 	void		(*sv_schedtail)(struct thread *);
+	void		(*sv_pax_aslr_init)(struct vmspace *vm, struct prison *pr);
 };
=20
 #define	SV_ILP32	0x000100
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index d8ba33f..4ba8106 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -65,6 +65,8 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
=20
+#include "opt_pax.h"
+
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
@@ -292,6 +294,12 @@ vmspace_alloc(vm_offset_t min, vm_offset_t max, pmap_p=
init_t pinit)
 	vm->vm_taddr =3D 0;
 	vm->vm_daddr =3D 0;
 	vm->vm_maxsaddr =3D 0;
+#ifdef PAX_ASLR
+	vm->vm_aslr_delta_mmap =3D 0;
+	vm->vm_aslr_delta_stack =3D 0;
+	vm->vm_aslr_delta_exec =3D 0;
+#endif
+
 	return (vm);
 }
=20
diff --git a/sys/vm/vm_map.h b/sys/vm/vm_map.h
index 8cced05..e8e9ffe 100644
--- a/sys/vm/vm_map.h
+++ b/sys/vm/vm_map.h
@@ -241,6 +241,9 @@ struct vmspace {
 	caddr_t vm_taddr;	/* (c) user virtual address of text */
 	caddr_t vm_daddr;	/* (c) user virtual address of data */
 	caddr_t vm_maxsaddr;	/* user VA at max stack growth */
+	vm_size_t vm_aslr_delta_mmap;	/* mmap() random delta for ASLR */
+	vm_size_t vm_aslr_delta_stack;	/* stack random delta for ASLR */
+	vm_size_t vm_aslr_delta_exec;	/* exec base random delta for ASLR */
 	volatile int vm_refcnt;	/* number of references */
 	/*
 	 * Keep the PMAP last, so that CPU-specific variations of that
diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c
index a524839..fd8876e 100644
--- a/sys/vm/vm_mmap.c
+++ b/sys/vm/vm_mmap.c
@@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
=20
 #include "opt_compat.h"
 #include "opt_hwpmc_hooks.h"
+#include "opt_pax.h"
=20
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -91,6 +92,10 @@ __FBSDID("$FreeBSD$");
 #include <sys/pmckern.h>
 #endif
=20
+#ifdef PAX_ASLR
+#include <sys/pax.h>
+#endif
+
 int old_mlock =3D 0;
 SYSCTL_INT(_vm, OID_AUTO, old_mlock, CTLFLAG_RW | CTLFLAG_TUN, &old_mlock,=
 0,
     "Do not apply RLIMIT_MEMLOCK on mlockall");
@@ -203,6 +208,9 @@ sys_mmap(td, uap)
 	struct file *fp;
 	struct vnode *vp;
 	vm_offset_t addr;
+#ifdef PAX_ASLR
+	vm_offset_t orig_addr;
+#endif
 	vm_size_t size, pageoff;
 	vm_prot_t cap_maxprot, prot, maxprot;
 	void *handle;
@@ -213,6 +221,9 @@ sys_mmap(td, uap)
 	cap_rights_t rights;
=20
 	addr =3D (vm_offset_t) uap->addr;
+#ifdef PAX_ASLR
+	orig_addr =3D addr;
+#endif
 	size =3D uap->len;
 	prot =3D uap->prot & VM_PROT_ALL;
 	flags =3D uap->flags;
@@ -416,6 +427,9 @@ sys_mmap(td, uap)
 map:
 	td->td_fpop =3D fp;
 	maxprot &=3D cap_maxprot;
+#ifdef PAX_ASLR
+	pax_aslr_mmap(td, &addr, orig_addr, flags);
+#endif
 	error =3D vm_mmap(&vms->vm_map, &addr, size, prot, maxprot,
 	    flags, handle_type, handle, pos);
 	td->td_fpop =3D NULL;
diff --git a/tools/build/options/WITHOUT_PIE b/tools/build/options/WITHOUT_=
PIE
new file mode 100644
index 0000000..82019ce
--- /dev/null
+++ b/tools/build/options/WITHOUT_PIE
@@ -0,0 +1 @@
+Enable building of Position-Independent Executables (PIEs).
diff --git a/usr.sbin/ugidfw/ugidfw.c b/usr.sbin/ugidfw/ugidfw.c
index 977922a..515df16 100644
--- a/usr.sbin/ugidfw/ugidfw.c
+++ b/usr.sbin/ugidfw/ugidfw.c
@@ -46,6 +46,8 @@ __FBSDID("$FreeBSD$");
 #include <string.h>
 #include <ugidfw.h>
=20
+#define UGIDFW_BUFSIZ (BUFSIZ*2)
+
 void add_rule(int argc, char *argv[]);
 void list_rules(void);
 void remove_rule(int argc, char *argv[]);
@@ -71,22 +73,22 @@ usage(void)
 void
 add_rule(int argc, char *argv[])
 {
-	char errstr[BUFSIZ], charstr[BUFSIZ];
+	char errstr[UGIDFW_BUFSIZ], charstr[UGIDFW_BUFSIZ];
 	struct mac_bsdextended_rule rule;
 	int error, rulenum;
=20
-	error =3D bsde_parse_rule(argc, argv, &rule, BUFSIZ, errstr);
+	error =3D bsde_parse_rule(argc, argv, &rule, UGIDFW_BUFSIZ, errstr);
 	if (error) {
 		warnx("%s", errstr);
 		return;
 	}
=20
-	error =3D bsde_add_rule(&rulenum, &rule, BUFSIZ, errstr);
+	error =3D bsde_add_rule(&rulenum, &rule, UGIDFW_BUFSIZ, errstr);
 	if (error) {
 		warnx("%s", errstr);
 		return;
 	}
-	if (bsde_rule_to_string(&rule, charstr, BUFSIZ) =3D=3D -1)
+	if (bsde_rule_to_string(&rule, charstr, UGIDFW_BUFSIZ) =3D=3D -1)
 		warnx("Added rule, but unable to print string.");
 	else
 		printf("%d %s\n", rulenum, charstr);
@@ -95,25 +97,25 @@ add_rule(int argc, char *argv[])
 void
 list_rules(void)
 {
-	char errstr[BUFSIZ], charstr[BUFSIZ];
+	char errstr[UGIDFW_BUFSIZ], charstr[UGIDFW_BUFSIZ];
 	struct mac_bsdextended_rule rule;
 	int error, i, rule_count, rule_slots;
=20
-	rule_slots =3D bsde_get_rule_slots(BUFSIZ, errstr);
+	rule_slots =3D bsde_get_rule_slots(UGIDFW_BUFSIZ, errstr);
 	if (rule_slots =3D=3D -1) {
 		warnx("unable to get rule slots; mac_bsdextended.ko "
 		    "may not be loaded");
 		errx(1, "bsde_get_rule_slots: %s", errstr);
 	}
=20
-	rule_count =3D bsde_get_rule_count(BUFSIZ, errstr);
+	rule_count =3D bsde_get_rule_count(UGIDFW_BUFSIZ, errstr);
 	if (rule_count =3D=3D -1)
 		errx(1, "bsde_get_rule_count: %s", errstr);
=20
 	printf("%d slots, %d rules\n", rule_slots, rule_count);
=20
 	for (i =3D 0; i < rule_slots; i++) {
-		error =3D bsde_get_rule(i, &rule, BUFSIZ, errstr);
+		error =3D bsde_get_rule(i, &rule, UGIDFW_BUFSIZ, errstr);
 		switch (error) {
 		case -2:
 			continue;
@@ -124,7 +126,7 @@ list_rules(void)
 			break;
 		}
=20
-		if (bsde_rule_to_string(&rule, charstr, BUFSIZ) =3D=3D -1)
+		if (bsde_rule_to_string(&rule, charstr, UGIDFW_BUFSIZ) =3D=3D -1)
 			warnx("unable to translate rule %d to string", i);
 		else
 			printf("%d %s\n", i, charstr);
@@ -134,7 +136,7 @@ list_rules(void)
 void
 set_rule(int argc, char *argv[])
 {
-	char errstr[BUFSIZ];
+	char errstr[UGIDFW_BUFSIZ];
 	struct mac_bsdextended_rule rule;
 	long value;
 	int error, rulenum;
@@ -152,13 +154,13 @@ set_rule(int argc, char *argv[])
=20
 	rulenum =3D value;
=20
-	error =3D bsde_parse_rule(argc - 1, argv + 1, &rule, BUFSIZ, errstr);
+	error =3D bsde_parse_rule(argc - 1, argv + 1, &rule, UGIDFW_BUFSIZ, errst=
r);
 	if (error) {
 		warnx("%s", errstr);
 		return;
 	}
=20
-	error =3D bsde_set_rule(rulenum, &rule, BUFSIZ, errstr);
+	error =3D bsde_set_rule(rulenum, &rule, UGIDFW_BUFSIZ, errstr);
 	if (error) {
 		warnx("%s", errstr);
 		return;
@@ -168,7 +170,7 @@ set_rule(int argc, char *argv[])
 void
 remove_rule(int argc, char *argv[])
 {
-	char errstr[BUFSIZ];
+	char errstr[UGIDFW_BUFSIZ];
 	long value;
 	int error, rulenum;
 	char *endp;
@@ -185,7 +187,7 @@ remove_rule(int argc, char *argv[])
=20
 	rulenum =3D value;
=20
-	error =3D bsde_delete_rule(rulenum, BUFSIZ, errstr);
+	error =3D bsde_delete_rule(rulenum, UGIDFW_BUFSIZ, errstr);
 	if (error)
 		warnx("%s", errstr);
 }

--yRA+Bmk8aPhU85Qt--

--S5HS5MvDw4DmbRmb
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2

iQIcBAEBAgAGBQJTptwkAAoJEGqEZY9SRW7uV/UP/jDGqcEHj+MZomqbnyG+Hs4q
sArIbDgKsXMrYkx/H1QbiV/+iIRGboiTcmetqkIg1kdkLjhWoQMrOJRVXu75x486
MTVGhFr2KvCRroaJsYN57F/GwwFYG5DVL9CzdPikax1O/JzyHtulpMP1ZKVz/g3r
ARcZpSxVO+IRDkK0O69HeJgduWA7dTdiR9rwGd5XY++Xart9JKMj4V0N+Gzx9UXA
7XhaL5y4o6Z+AlpploqAwuxMMQ/3CP2jIpFjJ06UeIvYdC6IzNL9y9r5GYIwmS7b
q03kO0R6fEpViIhsVtKqif+hZJQ7vThASSy9UVd3YB4MRtRFVo/yW/WRByVU5Hsh
nyObacX4qTYrXaK8xA8zmhOk+QRGMeS+ixs0fjuVhSCRAhDe3+3Tcr81hQf+VV4K
1q4GFRaN62jDXtuoxgkCzpy3bLSaBFuGdS0kzlubB08/MSC0ZVlIE44dHUt9enXs
EBNgHCuOBwF1iKu7qaiiNE2vDmBUNnQ+VBlytZH1nXCO46AlbdTJ2atC0JZO7Wk7
9rsWlvSd6aCKFazahxxmqNyaysO11VAgtYipnFaelGvicY6DLK4bb/ynhMl5oFf8
JDsq55cQI+XC/IPDSZkjDK0/gP1t2loAsbuv7y+R+g5bGJB/4rj3yEDf/T2UJ0VJ
DHhPn+4cJ6nhZqy64CAR
=KU2A
-----END PGP SIGNATURE-----

--S5HS5MvDw4DmbRmb--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20140622133740.GD1824>