Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 11 Jul 2014 19:26:23 -0400
From:      Shawn Webb <lattera@gmail.com>
To:        freebsd-arch@freebsd.org
Subject:   [RFC] ASLR Whitepaper and Candidate Final Patch
Message-ID:  <20140711232623.GG41807@pwnie.vrt.sourcefire.com>

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

--++alDQ2ROsODg1x+
Content-Type: multipart/mixed; boundary="vkEkAx9hr54EJ73W"
Content-Disposition: inline


--vkEkAx9hr54EJ73W
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hey All,

Oliver Pinter and I have been working hard on our ASLR implementation.
We're now in the final stages of development and would like to get
feedback from the community. I've attached to this email a small
whitepaper that details our implementation and the accompanying patch.

There is one part of the patch that I wrote that is quite an ugly hack
and would like to get some feedback on. I added a little hack to
sys_mmap() to apply ASLR to calls to mmap(2) when MAP_32BIT is
specified. I'd like to remove that ugly hack to something a bit more
beautiful, so if anyone has any suggestions, I'm all ears.

Other than that ugly hack, the code adheres to FreeBSD's style(9)
standards. I believe we have an awesome implementation, one I've
personally been using without issue for months.

I'm looking forward to your comments and questions. I've CC'd the PaX
team. Please keep them CC'd in your replies.

Thank you very much,

Shawn Webb
CC: PaX Team
CC: Oliver Pinter
CC: des@freebsd.org
CC: alc@rice.edu
CC: bdrewery@freebsd.org

--vkEkAx9hr54EJ73W
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="2014-07-10_aslr_whitepaper.txt"
Content-Transfer-Encoding: quoted-printable

Introducing ASLR For FreeBSD
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
Shawn Webb <lattera@gmail.com>
Oliver Pinter <oliver.pntr@gmail.com>
10 July 2014
http://www.hardenedbsd.org/

[ 1. Introduction ]
Security in FreeBSD's is based primarily in policy-based technologies. Exis=
ting
tools such as jails, Capsicum, vnet/vimage, and the MAC framework, can make
FreeBSD-based systems quite resilient against attacks. FreeBSD lacks basic
low-level exploit mitigation, such as Address Space Layout Randomization
(ASLR)[1]. ASLR randomizes the address space layout of an application, maki=
ng
exploitation difficult for an attacker. This paper and the associated
implementation aim  to provide a secure, robust, extensible, and easily-man=
aged
form of ASLR fit for production use within FreeBSD.

[ 2. History ]
On 14 May 2013, Oliver Pinter published to GitHub an initial patch[2]. His =
work
was inspired by Elad Efrat's work in NetBSD. The patch was submitted to Fre=
eBSD
as a bug report on 24 Aug 2013[3]. Independently of Oliver's work, on 30 Jun
2014, Shawn Webb posted on his tech blog that he was interested in implemen=
ting
ASLR for FreeBSD[4]. Oliver found the post and suggested that he and Shawn =
work
together. On 08 Jun 2014, preparatory work was committed to FreeBSD, adding
Position-Independent Executable (PIE) support in base[5].  On 07 Apr 2014,
SoldierX[6] agreed to sponsor the project and donated a sparc64 box and a
beaglebone black to Shawn Webb. This hardware is used for testing and debug=
ging
ASLR on those platforms.

[ 3. General Overview ]
ASLR is enabled by default for all architectures and controlled by the PAX_=
ASLR
kernel option. This means ASLR will be applied to all supported application=
s.
If a user wishes to disable ASLR for a given application, the user must for=
ce
that application to opt-out (detailed later).

Another kernel option, PAX_SYSCTLS, exposes additional tunables (via sysctl=
),
allowing ASLR behavior control without requiring a reboot. By default, the
sysctl security.pax.aslr.status can only be changed at boot time via
/boot/loader.conf. Enabling the PAX_SYSCTLS kernel option allows a root user
to modify security.pax.aslr.status. See Appendix B for a list of the tunabl=
es.

ASLR tunables are per-jail and each jail inherits its parent jail's setting=
s.
Having per-jail tunables allows more flexibility in shared-hosting
environments. This structure also allows a user to selectively disable ASLR
for applications that misbehave. ASLR-disabled applications will still have
policy-based security applied to it by virtue of being jailed.

The mac_bsdextended(4) MAC module and its corresponding ugidfw(8) applicati=
on
have been modified to allow a user to enable or disable ASLR for specific
applications. The filesys object specification has been modified to pass the
inode along with the filesystem id when the new paxflags option is specifie=
d.
The paxflags option is optionally placed at the end of the rule. An upper-c=
ase
"A" argument to the option signifies ASLR is enabled for the application an=
d a
lower-case "a" signifies ASLR is disabled for the application. Sample ugidf=
w(8)
rules are in Appendix C.

[ 4. Implementation Details ]
A new sysinit subroutine ID, SI_SUB_PAX, initializes all ASLR system variab=
les.=20
Upon system boot, tunables from /boot/loader.conf are checked for validity.=
 Any
invalid values, generate a warning message to the console and the tunable is
set to a sensible default.

For the sake of performance, the ASLR system relies on per-process deltas
rather than calling arc4random(3) for each mapping. When a process calls
execve(2), the ASLR system is initialized. Deltas are randomly generated for
the execution base, mmap(2), and stack addresses. Only the execution base of
applications compiled as PIEs are randomized. The execution base of non-PIE
applications are not modified. The mappings of shared objects are randomized
for both PIE and non-PIE applications.

The deltas are used as a hint to the Virtual Memory (VM) system. The VM sys=
tem
may modify the hint to make a better fit for superpages and other alignment
constraints.

The delta applied to the PIE execbase is different than the delta applied to
the base address of shared objects. In the Executable and Linkable File (EL=
F)
image handler, the execution base of PIE applications is randomized by addi=
ng
the delta controlled by security.pax.aslr.exec_len tunable  to et_dyn_addr,
which is initialized to be ET_DYN_LOAD_ADDR (an architecture-dependent macr=
o).
The base address of shared objects loaded by the runtime linker are randomi=
zed
by applying the delta controlled by the security.pax.aslr.mmap_len tunable =
in
sys_mmap().

Stack randomization is implemented using a stack gap[7]. On executable image
activation, the stack delta is computed and then subtracted from the top of
the stack.

[ 5. Further Enhancements ]

The existing gap-based stack randomization is not optimal. Mapping-base sta=
ck
randomization is more robust, but hard-coded kernel structures and addresse=
s,
especially PS_STRINGS, will need to be modified. The required changes to
PS_STRINGS are major and will likely touch userland along with the kernel.

The original PaX implementation, from which the FreeBSD implementation is
inspired, uses a special ELF process header which requires modification of
executable files. The authors of the FreeBSD implementation have deliberate=
ly
chosen to go a different route based on mac_bsdextended(4)/ugidfw(8). Suppo=
rt
for filesystem extended attributes will be added at a later time.

FreeBSD's virtual Dynamic Shared Object (vDSO) implementation, an efficient
technique for calling kernel code from userland, uses hardcoded,
non-randomized addresses. The vDSO implementation should be reworked to be =
at
a randomized address, providing the address as an auxiliary vector passed to
the image via the stack.

[ 6. Known Issues ]

ASLR does not function properly on 32bit ARM. When a process fork(2)s and c=
alls
execve(2) and the child process exits, the parent process crashes upon
receiving the SIGCHLD signal. No matter which application crashed, the pc
register ends up being 0xc0000000. The ktrace(1) facility proved that the
application crashed upon receiving the SIGCHLD signal.

[ Appendix A - References ]
[1]: http://pax.grsecurity.net/docs/aslr.txt
[2]: https://github.com/opntr/freebsd-patches-2013-tavasz/blob/master/r2499=
52%2BASLR/0001-PaX-ASLR-mmap-and-basic-stack-randomization.patch
[3]: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D181497
[4]: http://0xfeedface.org/blog/lattera/2013-06-29/long-term-plans
[5]: http://svnweb.freebsd.org/base?view=3Drevision&revision=3D267233
[6]: https://www.soldierx.com/
[7]: http://www.openbsd.org/papers/auug04/mgp00005.html

[ Appendix B - ASLR Tunables ]

NOTE: All tunables can only be changed during boot-time via /boot/loader.co=
nf
unless the kernel has been compiled with PAX_SYSCTLS.

security.pax.aslr.status (integer):
	Description:
		Toggle system-wide ASLR protection.
	Values:
		0 - ASLR disabled system-wide. Individual applications may NOT opt in.
		1 - ASLR disabled by default. Individual applications may opt in.
		2 - ASLR enabled by default. Individual applications may opt out.
		3 - ASLR enabled system-wide. Individual applications may NOT opt out.
	Default: 2

security.pax.aslr.debug (integer):
	Description:
		Toggle debugging output.
	Values:
		0 - Debug output disabled.
		1 - Basic debug output enabled.
		2 - Verbose debug output enabled.
	Default: 0

security.pax.aslr.mmap_len (integer):
	Description:
		Set the number of bits to be randomized for mmap(2) calls.
	Values:
		For 32bit systems, minimum of 8, maximum of 16.
		For 64bit systems, minimum of 16, maximum of 32.
	Default:
		For 32bit systems, 8.
		For 64bit systems, 21.

security.pax.aslr.stack_len (integer):
	Description:
		Set the number of bits to be randomized for the stack.
	Values:
		For 32bit systems, minimum of 6, maximum of 12.
		For 64bit systems, minimum of 12, maximum of 21.
	Default:
		For 32bit systems, 6.
		For 64bit systems, 16.

security.pax.aslr.exec_len (integer):
	Description:
		Set the number of bits to be randomized for the PIE exec base.
	Values:
		For 32bit systems, minimum of 6, maximum of 12.
		For 64bit systems, minimum of 12, maximum of 21.
	Default:
		For 32bit systems, 6.
		For 64bit systems, 21.

[ Appendix C - Sample ugidfw(8) rules ]

When security.pax.aslr.status is set to 2 (require applications to opt-out):

ugidfw add subject uid shawn object filesys /bin/ls mode rx paxflags a
   - This adds a rule to disable ASLR for /bin/ls for the user shawn.

ugidfw add subject uid 0:65535 object filesys /bin/ls mode rx paxflags a
   - This adds a rule to disable ASLR for /bin/ls for all users.

When security.pax.aslr.status is set to 1 (require applications to opt-in):

ugidfw add subject uid shawn object filesys /bin/ls mode rx paxflags A
   - This adds a rule to enable ASLR for /bin/ls for the user shawn.

ugidfw add subject uid 0:65535 object filesys /bin/ls mode rx paxflags A
   - This adds a rule to enable ASLR for /bin/ls for all users.

[ Appendix D - Files Modified/Created in 11-CURRENT ]
lib/libugidfw/ugidfw.c
lib/libugidfw/ugidfw.h
release/Makefile
sys/amd64/amd64/elf_machdep.c
sys/amd64/include/vmparam.h
sys/amd64/linux32/linux32_sysvec.c
sys/arm/arm/elf_machdep.c
sys/compat/freebsd32/freebsd32_misc.c
sys/compat/ia32/ia32_sysvec.c
sys/conf/NOTES
sys/conf/files
sys/conf/options
sys/i386/i386/elf_machdep.c
sys/i386/ibcs2/ibcs2_sysvec.c
sys/i386/linux/linux_sysvec.c
sys/kern/imgact_aout.c
sys/kern/imgact_elf.c
sys/kern/init_main.c
sys/kern/kern_exec.c
sys/kern/kern_fork.c
sys/kern/kern_jail.c
sys/kern/kern_pax.c
sys/kern/kern_pax_aslr.c
sys/kern/kern_pax_log.c
sys/kern/kern_sig.c
sys/mips/mips/elf_machdep.c
sys/mips/mips/freebsd32_machdep.c
sys/powerpc/powerpc/elf32_machdep.c
sys/powerpc/powerpc/elf64_machdep.c
sys/security/mac_bsdextended/mac_bsdextended.c
sys/security/mac_bsdextended/mac_bsdextended.h
sys/security/mac_bsdextended/ugidfw_internal.h
sys/security/mac_bsdextended/ugidfw_system.c
sys/security/mac_bsdextended/ugidfw_vnode.c
sys/sparc64/sparc64/elf_machdep.c
sys/sys/imgact.h
sys/sys/jail.h
sys/sys/kernel.h
sys/sys/pax.h
sys/sys/proc.h
sys/sys/sysent.h
sys/vm/vm_map.c
sys/vm/vm_map.h
sys/vm/vm_mmap.c
usr.sbin/ugidfw/ugidfw.c

--vkEkAx9hr54EJ73W
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="2014-07-10_aslr.patch"
Content-Transfer-Encoding: quoted-printable

diff --git a/lib/libugidfw/ugidfw.c b/lib/libugidfw/ugidfw.c
index 0dc423d..070cd0e 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
@@ -195,7 +200,7 @@ bsde_rule_to_string(struct mac_bsdextended_rule *rule, =
char *buf, size_t buflen)
 			cur +=3D len;
 		}
 		if (rule->mbr_subject.mbs_flags & MBS_PRISON_DEFINED) {
-			len =3D snprintf(cur, left, "jailid %d ",=20
+			len =3D snprintf(cur, left, "jailid %d ",
 			    rule->mbr_subject.mbs_prison);
 			if (len < 0 || len > left)
 				goto truncated;
@@ -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 ",=20
-			    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;
@@ -759,17 +796,22 @@ bsde_parse_type(char *spec, int *type, size_t buflen,=
 char *errstr)
 			len =3D snprintf(errstr, buflen, "Unknown type code: %c",
 			    spec[i]);
 			return (-1);
-		}=20
+		}
 	}
=20
 	return (0);
 }
=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;
@@ -984,7 +1046,42 @@ bsde_parse_mode(int argc, char *argv[], mode_t *mode,=
 size_t buflen,
 			len =3D snprintf(errstr, buflen, "Unknown mode letter: %c",
 			    argv[0][i]);
 			return (-1);
-		}=20
+		}
+	}
+
+	return (0);
+}
+
+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);
@@ -997,6 +1094,7 @@ bsde_parse_rule(int argc, char *argv[], struct mac_bsd=
extended_rule *rule,
 	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 815a9b7..e92453f 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);
@@ -2766,6 +2771,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 770bbbf..67ad330 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);
@@ -136,6 +141,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 6959425..bd6af74 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -2986,3 +2986,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 64101d1..71f8c1a 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -2908,6 +2908,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 8ec07e0..180f169 100644
--- a/sys/conf/options
+++ b/sys/conf/options
@@ -920,6 +920,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/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 6342119..fe2976d 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
@@ -653,16 +659,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;
@@ -787,16 +793,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;
@@ -817,6 +814,21 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *i=
mgp)
 	error =3D exec_new_vmspace(imgp, sv);
 	imgp->proc->p_sysent =3D sv;
=20
+	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 489096b..81a451f 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>
@@ -93,6 +94,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");
@@ -402,6 +407,11 @@ do_execve(td, args, mac_p)
 	imgp->pagesizes =3D 0;
 	imgp->pagesizeslen =3D 0;
 	imgp->stack_prot =3D 0;
+	imgp->pax_flags =3D 0;
+
+#if defined(PAX_MPROTECT) || defined(PAX_ASLR)
+	pax_elf(imgp, 0);
+#endif
=20
 #ifdef MAC
 	error =3D mac_execve_enter(imgp, mac_p);
@@ -1065,6 +1075,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) {
@@ -1099,6 +1113,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);
 }
@@ -1258,6 +1275,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 8135afb..9577013 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..37d7da1
--- /dev/null
+++ b/sys/kern/kern_pax_aslr.c
@@ -0,0 +1,680 @@
+/*-
+ * 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;
+
+	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);
+
+		*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 377fd25..f6b6173 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>
@@ -116,7 +124,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)
@@ -128,8 +135,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
@@ -226,7 +238,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;
@@ -304,6 +316,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)
@@ -412,6 +428,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.
@@ -424,7 +445,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
@@ -440,7 +461,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) {
@@ -453,7 +474,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;
@@ -463,7 +484,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,
+    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 0f1c256..83585b8 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 b5108e2..e39bbd0 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 1ae7189..c2b6a4d 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_RWTUN, &old_mlock, 0,
     "Do not apply RLIMIT_MEMLOCK on mlockall");
@@ -202,6 +207,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;
@@ -212,6 +220,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;
@@ -294,6 +305,12 @@ sys_mmap(td, uap)
 		 * do not bother moving the mapping past the heap (since
 		 * the heap is usually above 2GB).
 		 */
+#ifdef PAX_ASLR
+		/* Ugly hack for adding ASLR to 32bit mappings */
+		pax_aslr_mmap(td, &addr, orig_addr, flags);
+		if (addr !=3D orig_addr)
+			addr =3D trunc_page(addr&0x0fffffff);
+#endif
 		if (addr + size > MAP_32BIT_MAX_ADDR)
 			addr =3D 0;
 #endif
@@ -307,6 +324,9 @@ sys_mmap(td, uap)
 		 * location.
 		 */
 		PROC_LOCK(td->td_proc);
+#ifdef PAX_ASLR
+		pax_aslr_mmap(td, &addr, orig_addr, flags);
+#endif
 		if (addr =3D=3D 0 ||
 		    (addr >=3D round_page((vm_offset_t)vms->vm_taddr) &&
 		    addr < round_page((vm_offset_t)vms->vm_daddr +
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);
 }

--vkEkAx9hr54EJ73W--

--++alDQ2ROsODg1x+
Content-Type: application/pgp-signature

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

iQIcBAEBAgAGBQJTwHKfAAoJEGqEZY9SRW7uHrIP/iA/Xsl2+S+/rFp9inDbijaZ
g1Ow9SYqpxwLapWpgJzhnZdVPONsd9U4Y0Jm4088bsTB1LMAlodNmTq6a8jvmsNA
uCkMjj6VmUbk5zT+BS1Xl3KvGvSbGGY/1ji2b+JTMP7siF7Xr+qGTaYPOIN0a0Po
ppkHJMIU0XjSOfFFH8v71DOz65vW5q8oN4E+/n8cZOSGjYdyyyL1ccytQG1RTlUc
frzGl9R+GXqqH8/MBkksZuNo3VjAizmRmAO2BbkAPzQjwVI9CilBRK69PQvrGw7R
NL4ohkPr6fNdNXFg2J8v0opC/qRo9JSD4YTT8q2BEGER3g/9iqK7/lMzh2Hpo/0G
jKSO+ZafZpglD3/n9dXGLABxTDzd/7rhk6S6N2/aAmRvh97KcIbJny6qRJAcb301
QGRqG8vogMlEfAVVBSkcaZxdFXeGBNdoq++Xo7CZb393I6rCCfw5HBZI5+QseMbA
mR6wRosvLtUaLb/9kN3am9ee8DmCH9VTFdTM5IvqWkrpINiBOZxMRVeyKipbREaN
StWmGcgbVbp8d3jMlf5ZAcH1jlYcPIF9OiUkHjEFnfgCQxsigJ6W6TFqdcNyEKAt
Tyn5FyAeVEGj078CuGbn7pcIRr0Yh0ZCd39Jq0DFNzSvR8SVhAkcsFyoH5akQ6gN
muoLiT5A6IcIvq+vIy7e
=8Lwc
-----END PGP SIGNATURE-----

--++alDQ2ROsODg1x+--



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