FreeBSD Bugzilla – Attachment 153731 Details for
Bug 181497
[kernel] [patch] Add ASLR feature to kernel
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
New ASLR Patch
2015-03-01-aslr.patch (text/plain), 72.29 KB, created by
Shawn Webb
on 2015-03-03 21:11:10 UTC
(
hide
)
Description:
New ASLR Patch
Filename:
MIME Type:
Creator:
Shawn Webb
Created:
2015-03-03 21:11:10 UTC
Size:
72.29 KB
patch
obsolete
>Index: share/man/man4/Makefile >=================================================================== >--- share/man/man4/Makefile >+++ share/man/man4/Makefile >@@ -51,6 +51,7 @@ > ${_aout.4} \ > ${_apic.4} \ > arcmsr.4 \ >+ aslr.4 \ > ${_asmc.4} \ > ata.4 \ > ath.4 \ >Index: share/man/man4/aslr.4 >=================================================================== >--- /dev/null >+++ share/man/man4/aslr.4 >@@ -0,0 +1,276 @@ >+.\"- >+.\" Copyright (c) 2014,2015 Shawn Webb <shawn.webb@hardenedbsd.org> >+.\" 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 PURPOSE >+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS 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 USE, 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$ >+.\" >+.Dd February 21, 2015 >+.Dt ASLR 4 >+.Os >+.Sh NAME >+.Nm aslr >+.Nd Address Space Layout Randomization >+.Sh SYNOPSIS >+.In sys/types.h >+.In sys/pax.h >+.Pp >+In the kernel configuration file: >+.Cd "options PAX_ASLR" >+.Sh DESCRIPTION >+.Ss Introduction >+Security in >+.Fx >+is based primarily in policy-based technologies. >+Existing tools such as >+.Xr jail 4 , >+.Xr capsicum 4 , >+.Xr VNET 9 , and the >+.Xr mac 4 >+framework can make >+.Fx Ns -based systems quite resilient against >+attacks. >+FreeBSD lacks basic low-level exploit mitigation, such as Address >+Space Layout Randomization (ASLR). >+ASLR Randomizes the address space layout of an application, making >+exploitation difficult for an attacker. >+This manual page and the associated implementation aim to >+provide a secure, robust, extensible, and easily-managed form of ASLR >+fit for production use in >+.Fx Ns . >+.Ss General Overview >+When compiled with the PAX_ASLR option, systems will have ASLR >+enabled. >+For systems with that kernel option enabled, if a user wants >+to disable ASLR for a given application, the user must force that >+application to opt-out. >+HardenedBSD has a special application called secadm for opting >+applications in to or out of exploit mitigation features such as ASLR. >+.Pp >+Another kernel option, >+.Cd PAX_SYSCTLS , >+exposes additional >+.Xr sysctl 8 >+tunables, allowing ASLR behavior control without requiring a reboot. >+By default, the sysctl hardening.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 >+hardening.pax.aslr.status. >+See Appendix A for a list of all the tunables. >+.Pp >+ASLR tunables are per-jail and each jail inherits its parent jail's >+settings. >+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. >+.Ss Implementation Details >+A new sysinit subroutine ID, SI_SUB_PAX, initializes ASLR system >+variables. >+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. >+.Pp >+For the sake of performance, the ASLR system relies on per-process >+deltas rather than calling >+.Xr arc4random 3 >+for each mapping. >+When a process calls >+.Xr execve 2 >+.Ns , the ASLR deltas are initialized. >+Deltas are randomly generated for the execution base, >+.Xr mmap 2 >+.Ns , and stack addresses. >+Only the execution base of applications compiled as Position >+Independent Executables (PIEs) is randomized. >+The execution base of non-PIE applications is not modified. >+The mappings of shared objects are randomized for both PIE and non-PIE >+applications. >+.Pp >+The deltas are used as a hint to the Virtual Memory (VM) system. >+The VM system may modify the hint to make a better fit for superpages >+and other alignment constraints. >+.Pp >+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 (ELF) image handler, the >+execution base of PIE applications is randomized by adding the delta >+controlled by the hardening.pax.aslr.exec_len tunable to et_dyn_addr, >+which is initialized to be ET_DYN_LOAD_ADDR (an architecture- >+dependent macro). >+The base address of shared objects loaded by the dynamic linker are >+randomized by applying the delta controlled by the >+hardening.pax.aslr.mmap_len tunable in >+.Fn sys_mmap >+.Ns . >+Stack randomization is implemented using a stack gap. >+On executable image activation, the stack delta is computed and >+subtracted from the top of the stack. >+.Ss APPENDIX A >+NOTE: All tunables can only be changed during boot-time via >+.Fa /boot/loader.conf >+unless the kernel has been compiled with >+.Cd PAX_SYSCTLS >+.Ns . >+.Bl -bullet >+.It >+hardening.pax.aslr.status >+.Bl -dash -compact >+.It >+Type: integer >+.It >+Description: Toggle system-wide ASLR protection. >+.It >+Values: >+.br >+0 - ASLR disabled system-wide. Individual applications may >+.Em NOT >+opt in. >+.br >+1 - ASLR disabled but applications may opt in. >+.br >+2 - ASLR enabled and applications may opt out. >+.br >+3 - ASLR enabled for all applications. Applications may not opt out. >+.It >+Default: 2 >+.El >+.It >+hardening.pax.aslr.exec_len >+.Bl -dash -compact >+.It >+Type: integer >+.It >+Description: Set the number of bits to be randomized for the PIE >+execbase. >+.It >+Values: >+.br >+For 32-bit systems, minimum of 8, maximum of 21. For 64-bit systems, >+minimum of 16, maximum of 42. >+.It >+Default: For 32-bit systems: 14. For 64-bit systems: 16. >+.El >+.It >+hardening.pax.aslr.mmap_len >+.Bl -dash -compact >+.It >+Type: integer >+.It >+Description: Set the number of bits to be randomized for >+.Xr mmap 2 >+calls. >+.It >+Values: >+.br >+For 32-bit systems, minimum of 8, maximum of 21. For 64-bit systems, >+minimum of 16, maximum of 42. >+.It >+Default: For 32-bit systems: 14. For 64-bit systems: 21. >+.El >+.It >+hardening.pax.aslr.stack_len >+.Bl -dash -compact >+.It >+Type: integer >+.It >+Description: Set the number of bits to be randomized for the stack. >+.It >+Values: >+.br >+For 32-bit systems, minimum of 8, maximum of 21. For 64-bit systems, >+minimum of 16, maximum of 42. >+.It >+Default: For 32-bit systems: 8. For 64-bit systems: 16. >+.El >+.El >+.Sh SEE ALSO >+.Xr mmap 2 , >+.Xr elf 3 , >+.Xr mac 4 >+.Rs >+.%T "PaX ASLR" >+.%U http://pax.grsecurity.net/docs/aslr.txt >+.Re >+.Rs >+.%T "FreeBSD ASLR Bug Report" >+.%U https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=181497 >+.Re >+.Rs >+.%T "HardenedBSD" >+.%U http://hardenedbsd.org/ >+.Re >+.Rs >+.%T "secadm" >+.%U https://github.com/HardenedBSD/secadm >+.Re >+.Sh HISTORY >+On 14 May 2013, Oliver Pinter published to GitHub an initial patch to >+implement ASLR. >+His work was inspired by Elad Efrat's work in NetBSD. >+The patch was submitted to FreeBSD as a bug report on 24 Aug 2013. >+Independenty of Oliver's work, Shawn Webb posted to his tech blog that >+he was interested in implementing ASLR for FreeBSD. >+Oliver found his post and suggested that he and Shawn work together. >+On June 08, 2014, preparatory work was committed to FreeBSD, adding >+Position-Independent Executable (PIE) support in base. PIE support >+was removed sometime later. >+On 07 Apr 2014, SoldierX agreed to sponsor the project and donated a >+sparc64 machine and a BeagleBone Black to Shawn Webb. This hardware >+is used for testing and debugging ASLR. >+ASLR was first introduced in HardenedBSD and later upstreamed to >+.Fx 11.0-CURRENT. >+.Sh AUTHORS >+This manual page was written by >+.An -nosplit >+.An Shawn Webb . >+The ASLR implementation was written by >+.An Oliver Pinter and >+.An Shawn Webb . >+.Sh BUGS >+The existing gap-based stack randomization is not optimal. >+Mapping-base stack randomization is more robust, but hard-coded kernel >+structures and addresses, especially >+.Va PS_STRINGS >+, will need to be >+modified. >+The required changes to >+.Va PS_STRINGS >+are major and will likely touch >+userland along with the kernel. >+ >+The original PaX implementation, from which the >+.Fx >+implementation is inspired, uses a special ELF process header which >+requires modification of executable files. >+The authors of the >+.Fx >+implementation have deliberately chosen to go a different route based >+on the >+.Xr mac 4 >+framework. >+Support for filesystem extended attributes will be added at a later >+time. >Index: sys/amd64/amd64/elf_machdep.c >=================================================================== >--- sys/amd64/amd64/elf_machdep.c >+++ sys/amd64/amd64/elf_machdep.c >@@ -26,12 +26,15 @@ > #include <sys/cdefs.h> > __FBSDID("$FreeBSD$"); > >+#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> >+#include <sys/pax.h> > #include <sys/proc.h> > #include <sys/sysent.h> > #include <sys/imgact_elf.h> >@@ -82,6 +85,9 @@ > .sv_shared_page_base = SHAREDPAGE, > .sv_shared_page_len = PAGE_SIZE, > .sv_schedtail = NULL, >+#ifdef PAX_ASLR >+ .sv_pax_aslr_init = pax_aslr_init_vmspace, >+#endif > }; > INIT_SYSENTVEC(elf64_sysvec, &elf64_freebsd_sysvec); > >Index: sys/amd64/conf/GENERIC >=================================================================== >--- sys/amd64/conf/GENERIC >+++ sys/amd64/conf/GENERIC >@@ -69,6 +69,8 @@ > options CAPABILITY_MODE # Capsicum capability mode > options CAPABILITIES # Capsicum capabilities > options MAC # TrustedBSD MAC Framework >+#options PAX_ASLR # Address Space Layout Randomization >+#options PAX_SYSCTLS # Run-time settings for PAX and Hardening > options KDTRACE_FRAME # Ensure frames are compiled in > options KDTRACE_HOOKS # Kernel DTrace hooks > options DDB_CTF # Kernel ELF linker loads CTF data >Index: sys/amd64/include/vmparam.h >=================================================================== >--- sys/amd64/include/vmparam.h >+++ sys/amd64/include/vmparam.h >@@ -178,7 +178,8 @@ > #define VM_MAXUSER_ADDRESS UVADDR(NUPML4E, 0, 0, 0) > > #define SHAREDPAGE (VM_MAXUSER_ADDRESS - PAGE_SIZE) >-#define USRSTACK SHAREDPAGE >+#define SHAREDPAGE_GUARD (4 * PAGE_SIZE) >+#define USRSTACK (SHAREDPAGE - SHAREDPAGE_GUARD) > > #define VM_MAX_ADDRESS UPT_MAX_ADDRESS > #define VM_MIN_ADDRESS (0) >Index: sys/amd64/linux32/linux32_sysvec.c >=================================================================== >--- sys/amd64/linux32/linux32_sysvec.c >+++ sys/amd64/linux32/linux32_sysvec.c >@@ -33,6 +33,7 @@ > #include <sys/cdefs.h> > __FBSDID("$FreeBSD$"); > #include "opt_compat.h" >+#include "opt_pax.h" > > #ifndef COMPAT_FREEBSD32 > #error "Unable to compile Linux-emulator due to missing COMPAT_FREEBSD32 option!" >@@ -51,6 +52,7 @@ > #include <sys/malloc.h> > #include <sys/module.h> > #include <sys/mutex.h> >+#include <sys/pax.h> > #include <sys/proc.h> > #include <sys/resourcevar.h> > #include <sys/signalvar.h> >@@ -1037,6 +1039,9 @@ > .sv_shared_page_base = LINUX32_SHAREDPAGE, > .sv_shared_page_len = PAGE_SIZE, > .sv_schedtail = linux_schedtail, >+#ifdef PAX_ASLR >+ .sv_pax_aslr_init = pax_aslr_init_vmspace32, >+#endif > }; > INIT_SYSENTVEC(elf_sysvec, &elf_linux_sysvec); > >Index: sys/arm/arm/elf_machdep.c >=================================================================== >--- sys/arm/arm/elf_machdep.c >+++ sys/arm/arm/elf_machdep.c >@@ -26,14 +26,17 @@ > #include <sys/cdefs.h> > __FBSDID("$FreeBSD$"); > >+#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> > #include <sys/sysent.h> > #include <sys/imgact_elf.h> >+#include <sys/pax.h> > #include <sys/proc.h> > #include <sys/syscall.h> > #include <sys/signalvar.h> >@@ -81,6 +84,9 @@ > .sv_fetch_syscall_args = cpu_fetch_syscall_args, > .sv_syscallnames = syscallnames, > .sv_schedtail = NULL, >+#ifdef PAX_ASLR >+ .sv_pax_aslr_init = pax_aslr_init_vmspace, >+#endif > }; > > static Elf32_Brandinfo freebsd_brand_info = { >Index: sys/arm/arm/machdep.c >=================================================================== >--- sys/arm/arm/machdep.c >+++ sys/arm/arm/machdep.c >@@ -47,6 +47,7 @@ > #include "opt_platform.h" > #include "opt_sched.h" > #include "opt_timer.h" >+#include "opt_pax.h" > > #include <sys/cdefs.h> > __FBSDID("$FreeBSD$"); >@@ -116,6 +117,10 @@ > #include <ddb/ddb.h> > #endif > >+#ifdef PAX_ASLR >+#include <sys/pax.h> >+#endif >+ > #ifdef DEBUG > #define debugf(fmt, args...) printf(fmt, ##args) > #else >@@ -281,6 +286,9 @@ > tf->tf_pc = (register_t)catcher; > tf->tf_usr_sp = (register_t)fp; > tf->tf_usr_lr = (register_t)(PS_STRINGS - *(p->p_sysent->sv_szsigcode)); >+#ifdef PAX_ASLR >+ pax_aslr_stack(p, &tf->tf_usr_lr); >+#endif > > CTR3(KTR_SIG, "sendsig: return td=%p pc=%#x sp=%#x", td, tf->tf_usr_lr, > tf->tf_usr_sp); >Index: sys/compat/freebsd32/freebsd32_misc.c >=================================================================== >--- sys/compat/freebsd32/freebsd32_misc.c >+++ sys/compat/freebsd32/freebsd32_misc.c >@@ -30,6 +30,7 @@ > #include "opt_compat.h" > #include "opt_inet.h" > #include "opt_inet6.h" >+#include "opt_pax.h" > > #define __ELF_WORD_SIZE 32 > >@@ -55,6 +56,7 @@ > #include <sys/mount.h> > #include <sys/mutex.h> > #include <sys/namei.h> >+#include <sys/pax.h> > #include <sys/proc.h> > #include <sys/procctl.h> > #include <sys/reboot.h> >@@ -2801,6 +2803,10 @@ > szsigcode = 0; > destp = (uintptr_t)arginfo; > >+#ifdef PAX_ASLR >+ pax_aslr_stack(imgp->proc, &destp); >+#endif >+ > /* > * install sigcode > */ >Index: sys/compat/ia32/ia32_sysvec.c >=================================================================== >--- sys/compat/ia32/ia32_sysvec.c >+++ sys/compat/ia32/ia32_sysvec.c >@@ -29,6 +29,7 @@ > __FBSDID("$FreeBSD$"); > > #include "opt_compat.h" >+#include "opt_pax.h" > > #define __ELF_WORD_SIZE 32 > >@@ -43,6 +44,7 @@ > #include <sys/mman.h> > #include <sys/namei.h> > #include <sys/pioctl.h> >+#include <sys/pax.h> > #include <sys/proc.h> > #include <sys/procfs.h> > #include <sys/resourcevar.h> >@@ -136,6 +138,9 @@ > .sv_shared_page_base = FREEBSD32_SHAREDPAGE, > .sv_shared_page_len = PAGE_SIZE, > .sv_schedtail = NULL, >+#ifdef PAX_ASLR >+ .sv_pax_aslr_init = pax_aslr_init_vmspace32, >+#endif > }; > INIT_SYSENTVEC(elf_ia32_sysvec, &ia32_freebsd_sysvec); > >Index: sys/conf/NOTES >=================================================================== >--- sys/conf/NOTES >+++ sys/conf/NOTES >@@ -2983,3 +2983,7 @@ > > # Module to enable execution of application via emulators like QEMU > options IMAGACT_BINMISC >+ >+# Address Space Layout Randomization (ASLR) >+options PAX_ASLR # Address Space Layout Randomization >+options PAX_SYSCTLS # Run-time settings for PAX and Hardening >Index: sys/conf/files >=================================================================== >--- sys/conf/files >+++ sys/conf/files >@@ -3024,6 +3024,8 @@ > 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_physio.c standard > kern/kern_pmc.c standard > kern/kern_poll.c optional device_polling >Index: sys/conf/options >=================================================================== >--- sys/conf/options >+++ sys/conf/options >@@ -931,6 +931,10 @@ > # Resource Limits > RCTL opt_global.h > >+# PaX - hardening options >+PAX_ASLR opt_pax.h >+PAX_SYSCTLS opt_pax.h >+ > # Random number generator(s) > RANDOM_YARROW opt_random.h > RANDOM_FORTUNA opt_random.h >Index: sys/i386/i386/elf_machdep.c >=================================================================== >--- sys/i386/i386/elf_machdep.c >+++ sys/i386/i386/elf_machdep.c >@@ -27,13 +27,15 @@ > __FBSDID("$FreeBSD$"); > > #include "opt_cpu.h" >+#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> >+#include <sys/pax.h> > #include <sys/proc.h> > #include <sys/sysent.h> > #include <sys/imgact_elf.h> >@@ -88,6 +90,9 @@ > .sv_shared_page_base = SHAREDPAGE, > .sv_shared_page_len = PAGE_SIZE, > .sv_schedtail = NULL, >+#ifdef PAX_ASLR >+ .sv_pax_aslr_init = pax_aslr_init_vmspace, >+#endif > }; > INIT_SYSENTVEC(elf32_sysvec, &elf32_freebsd_sysvec); > >Index: sys/i386/ibcs2/ibcs2_sysvec.c >=================================================================== >--- sys/i386/ibcs2/ibcs2_sysvec.c >+++ sys/i386/ibcs2/ibcs2_sysvec.c >@@ -31,6 +31,8 @@ > #include <sys/cdefs.h> > __FBSDID("$FreeBSD$"); > >+#include "opt_pax.h" >+ > #include <sys/param.h> > #include <sys/kernel.h> > #include <sys/systm.h> >@@ -40,6 +42,7 @@ > #include <sys/module.h> > #include <sys/sysent.h> > #include <sys/signalvar.h> >+#include <sys/pax.h> > #include <sys/proc.h> > #include <sys/sx.h> > >@@ -89,6 +92,9 @@ > .sv_fetch_syscall_args = cpu_fetch_syscall_args, > .sv_syscallnames = NULL, > .sv_schedtail = NULL, >+#ifdef PAX_ASLR >+ .sv_pax_aslr_init = pax_aslr_init_vmspace, >+#endif > }; > > static int >Index: sys/i386/linux/linux_sysvec.c >=================================================================== >--- sys/i386/linux/linux_sysvec.c >+++ sys/i386/linux/linux_sysvec.c >@@ -29,6 +29,8 @@ > #include <sys/cdefs.h> > __FBSDID("$FreeBSD$"); > >+#include "opt_pax.h" >+ > #include <sys/param.h> > #include <sys/systm.h> > #include <sys/exec.h> >@@ -41,6 +43,7 @@ > #include <sys/malloc.h> > #include <sys/module.h> > #include <sys/mutex.h> >+#include <sys/pax.h> > #include <sys/proc.h> > #include <sys/signalvar.h> > #include <sys/syscallsubr.h> >@@ -973,6 +976,9 @@ > .sv_shared_page_base = LINUX_SHAREDPAGE, > .sv_shared_page_len = PAGE_SIZE, > .sv_schedtail = linux_schedtail, >+#ifdef PAX_ASLR >+ .sv_pax_aslr_init = pax_aslr_init_vmspace, >+#endif > }; > INIT_SYSENTVEC(aout_sysvec, &linux_sysvec); > >@@ -1011,6 +1017,9 @@ > .sv_shared_page_base = LINUX_SHAREDPAGE, > .sv_shared_page_len = PAGE_SIZE, > .sv_schedtail = linux_schedtail, >+#ifdef PAX_ASLR >+ .sv_pax_aslr_init = pax_aslr_init_vmspace, >+#endif > }; > INIT_SYSENTVEC(elf_sysvec, &elf_linux_sysvec); > >Index: sys/kern/imgact_aout.c >=================================================================== >--- sys/kern/imgact_aout.c >+++ sys/kern/imgact_aout.c >@@ -27,6 +27,8 @@ > #include <sys/cdefs.h> > __FBSDID("$FreeBSD$"); > >+#include "opt_pax.h" >+ > #include <sys/param.h> > #include <sys/exec.h> > #include <sys/imgact.h> >@@ -36,6 +38,7 @@ > #include <sys/lock.h> > #include <sys/malloc.h> > #include <sys/mutex.h> >+#include <sys/pax.h> > #include <sys/proc.h> > #include <sys/racct.h> > #include <sys/resourcevar.h> >@@ -99,6 +102,9 @@ > .sv_fetch_syscall_args = cpu_fetch_syscall_args, > .sv_syscallnames = syscallnames, > .sv_schedtail = NULL, >+#ifdef PAX_ASLR >+ .sv_pax_aslr_init = pax_aslr_init_vmspace, >+#endif > }; > > #elif defined(__amd64__) >@@ -143,6 +149,9 @@ > .sv_set_syscall_retval = ia32_set_syscall_retval, > .sv_fetch_syscall_args = ia32_fetch_syscall_args, > .sv_syscallnames = freebsd32_syscallnames, >+#ifdef PAX_ASLR >+ .sv_pax_aslr_init = pax_aslr_init_vmspace32, >+#endif > }; > #else > #error "Port me" >Index: sys/kern/imgact_elf.c >=================================================================== >--- sys/kern/imgact_elf.c >+++ sys/kern/imgact_elf.c >@@ -34,6 +34,7 @@ > #include "opt_capsicum.h" > #include "opt_compat.h" > #include "opt_core.h" >+#include "opt_pax.h" > > #include <sys/param.h> > #include <sys/capsicum.h> >@@ -49,6 +50,7 @@ > #include <sys/mman.h> > #include <sys/namei.h> > #include <sys/pioctl.h> >+#include <sys/pax.h> > #include <sys/proc.h> > #include <sys/procfs.h> > #include <sys/racct.h> >@@ -801,16 +803,7 @@ > if (hdr->e_type == ET_DYN) { > if ((brand_info->flags & BI_CAN_EXEC_DYN) == 0) > return (ENOEXEC); >- /* >- * Honour the base load address from the dso if it is >- * non-zero for some reason. >- */ >- if (baddr == 0) >- et_dyn_addr = ET_DYN_LOAD_ADDR; >- else >- et_dyn_addr = 0; >- } else >- et_dyn_addr = 0; >+ } > sv = brand_info->sysvec; > if (interp != NULL && brand_info->interp_newpath != NULL) > newinterp = brand_info->interp_newpath; >@@ -831,6 +824,20 @@ > error = exec_new_vmspace(imgp, sv); > imgp->proc->p_sysent = sv; > >+ et_dyn_addr = 0; >+ if (hdr->e_type == ET_DYN) { >+ /* >+ * Honour the base load address from the dso if it is >+ * non-zero for some reason. >+ */ >+ if (baddr == 0) { >+ et_dyn_addr = ET_DYN_LOAD_ADDR; >+#ifdef PAX_ASLR >+ pax_aslr_execbase(imgp->proc, &et_dyn_addr); >+#endif >+ } >+ } >+ > vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY); > if (error) > return (error); >Index: sys/kern/init_main.c >=================================================================== >--- sys/kern/init_main.c >+++ sys/kern/init_main.c >@@ -46,6 +46,7 @@ > > #include "opt_ddb.h" > #include "opt_init_path.h" >+#include "opt_pax.h" > #include "opt_verbose_sysinit.h" > > #include <sys/param.h> >@@ -61,6 +62,7 @@ > #include <sys/mutex.h> > #include <sys/syscallsubr.h> > #include <sys/sysctl.h> >+#include <sys/pax.h> > #include <sys/proc.h> > #include <sys/racct.h> > #include <sys/resourcevar.h> >@@ -411,6 +413,7 @@ > .sv_fetch_syscall_args = null_fetch_syscall_args, > .sv_syscallnames = NULL, > .sv_schedtail = NULL, >+ .sv_pax_aslr_init = NULL, > }; > > /* >@@ -477,6 +480,9 @@ > p->p_flag = P_SYSTEM | P_INMEM; > p->p_flag2 = 0; > p->p_state = PRS_NORMAL; >+#if defined(PAX_ASLR) >+ p->p_pax = PAX_NOTE_ALL_DISABLED; >+#endif > knlist_init_mtx(&p->p_klist, &p->p_mtx); > STAILQ_INIT(&p->p_ktr); > p->p_nice = NZERO; >@@ -494,6 +500,9 @@ > td->td_flags = TDF_INMEM; > td->td_pflags = TDP_KTHREAD; > td->td_cpuset = cpuset_thread0(); >+#if defined(PAX_ASLR) >+ td->td_pax = PAX_NOTE_ALL_DISABLED; >+#endif > prison0_init(); > p->p_peers = 0; > p->p_leader = p; >Index: sys/kern/kern_exec.c >=================================================================== >--- sys/kern/kern_exec.c >+++ sys/kern/kern_exec.c >@@ -30,6 +30,7 @@ > #include "opt_capsicum.h" > #include "opt_hwpmc_hooks.h" > #include "opt_ktrace.h" >+#include "opt_pax.h" > #include "opt_vm.h" > > #include <sys/param.h> >@@ -50,6 +51,7 @@ > #include <sys/imgact_elf.h> > #include <sys/wait.h> > #include <sys/malloc.h> >+#include <sys/pax.h> > #include <sys/priv.h> > #include <sys/proc.h> > #include <sys/pioctl.h> >@@ -65,6 +67,7 @@ > #include <sys/sysctl.h> > #include <sys/vnode.h> > #include <sys/stat.h> >+#include <sys/jail.h> > #ifdef KTRACE > #include <sys/ktrace.h> > #endif >@@ -130,6 +133,10 @@ > SYSCTL_INT(_security_bsd, OID_AUTO, map_at_zero, CTLFLAG_RWTUN, &map_at_zero, 0, > "Permit processes to map an object at virtual address 0."); > >+#ifdef PAX_ASLR >+static int exec_check_aslr(struct image_params *imgp); >+#endif >+ > static int > sysctl_kern_ps_strings(SYSCTL_HANDLER_ARGS) > { >@@ -383,6 +390,7 @@ > imgp->proc = p; > imgp->attr = &attr; > imgp->args = args; >+ imgp->pax_flags = 0; > > #ifdef MAC > error = mac_execve_enter(imgp, mac_p); >@@ -1045,6 +1053,10 @@ > map = &vmspace->vm_map; > } > >+#ifdef PAX_ASLR >+ pax_aslr_init(imgp); >+#endif >+ > /* Map a shared page */ > obj = sv->sv_shared_page_obj; > if (obj != NULL) { >@@ -1079,6 +1091,9 @@ > */ > vmspace->vm_ssize = sgrowsiz >> PAGE_SHIFT; > vmspace->vm_maxsaddr = (char *)sv->sv_usrstack - ssiz; >+#ifdef PAX_ASLR >+ pax_aslr_stack_fixup(imgp->proc); >+#endif > > return (0); > } >@@ -1246,6 +1261,9 @@ > szsigcode = *(p->p_sysent->sv_szsigcode); > } > destp = (uintptr_t)arginfo; >+#ifdef PAX_ASLR >+ pax_aslr_stack(p, &destp); >+#endif > > /* > * install sigcode >@@ -1366,6 +1384,38 @@ > return (stack_base); > } > >+#ifdef PAX_ASLR >+/* >+ * If we've disabled ASLR via ptrace, do not allow execution of >+ * setuid/setgid binaries. >+ */ >+static int >+exec_check_aslr(struct image_params *imgp) >+{ >+ struct proc *p = imgp->proc; >+ struct ucred *oldcred = p->p_ucred; >+ struct vattr *attr = imgp->attr; >+ int error, credential_changing; >+ >+ credential_changing = 0; >+ credential_changing |= (attr->va_mode & S_ISUID) && oldcred->cr_uid != >+ attr->va_uid; >+ credential_changing |= (attr->va_mode & S_ISGID) && oldcred->cr_gid != >+ attr->va_gid; >+ >+ if (credential_changing) { >+ if ((p->p_paxdebug & PAX_NOTE_NOASLR) == PAX_NOTE_NOASLR) { >+ if (pax_aslr_active(imgp->proc)) >+ return (EPERM); >+ } >+ } >+ >+ error = pax_elf(imgp, p->p_paxdebug); >+ return (error); >+} >+#endif /* PAX_ASLR */ >+ >+ > /* > * Check permissions of file to execute. > * Called with imgp->vp locked. >@@ -1387,6 +1437,12 @@ > if (error) > return (error); > >+#if defined(PAX_ASLR) >+ error = exec_check_aslr(imgp); >+ if (error) >+ return (error); >+#endif >+ > #ifdef MAC > error = mac_vnode_check_exec(td->td_ucred, imgp->vp, imgp); > if (error) >Index: sys/kern/kern_fork.c >=================================================================== >--- sys/kern/kern_fork.c >+++ sys/kern/kern_fork.c >@@ -473,6 +473,7 @@ > __rangeof(struct thread, td_startcopy, td_endcopy)); > > bcopy(&p2->p_comm, &td2->td_name, sizeof(td2->td_name)); >+ td2->td_pax = p2->p_pax; > td2->td_sigstk = td->td_sigstk; > td2->td_flags = TDF_INMEM; > td2->td_lend_user_pri = PRI_MAX; >Index: sys/kern/kern_jail.c >=================================================================== >--- sys/kern/kern_jail.c >+++ sys/kern/kern_jail.c >@@ -33,6 +33,7 @@ > #include "opt_ddb.h" > #include "opt_inet.h" > #include "opt_inet6.h" >+#include "opt_pax.h" > > #include <sys/param.h> > #include <sys/types.h> >@@ -42,6 +43,7 @@ > #include <sys/sysproto.h> > #include <sys/malloc.h> > #include <sys/osd.h> >+#include <sys/pax.h> > #include <sys/priv.h> > #include <sys/proc.h> > #include <sys/taskqueue.h> >@@ -250,6 +252,10 @@ > prison0.pr_cpuset = cpuset_ref(thread0.td_cpuset); > prison0.pr_osreldate = osreldate; > strlcpy(prison0.pr_osrelease, osrelease, sizeof(prison0.pr_osrelease)); >+ >+#ifdef PAX_ASLR >+ pax_init_prison(&prison0); >+#endif > } > > #ifdef INET >@@ -1362,6 +1368,10 @@ > goto done_releroot; > } > >+#ifdef PAX_ASLR >+ pax_init_prison(pr); >+#endif >+ > mtx_lock(&pr->pr_mtx); > /* > * New prisons do not yet have a reference, because we do not >Index: sys/kern/kern_pax.c >=================================================================== >--- /dev/null >+++ sys/kern/kern_pax.c >@@ -0,0 +1,209 @@ >+/*- >+ * Copyright (c) 2006 Elad Efrat <elad@NetBSD.org> >+ * Copyright (c) 2013-2015, by Oliver Pinter <oliver.pinter@hardenedbsd.org> >+ * Copyright (c) 2014-2015, by Shawn Webb <shawn.webb@hardenedbsd.org> >+ * 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 WARRANTIES >+ * 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 USE, >+ * 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$ >+ * >+ * HardenedBSD-version: 2fba75c32739bd7f7c80163ec88e3655c3130753 >+ * HardenedBSD-version: v16 >+ * >+ */ >+ >+#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/sx.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> >+ >+static int pax_validate_flags(uint32_t flags); >+static int pax_check_conflicting_modes(uint32_t mode); >+ >+SYSCTL_NODE(_security, OID_AUTO, pax, CTLFLAG_RD, 0, >+ "PaX (exploit mitigation) features."); >+ >+const char *pax_status_str[] = { >+ [PAX_FEATURE_DISABLED] = "disabled", >+ [PAX_FEATURE_OPTIN] = "opt-in", >+ [PAX_FEATURE_OPTOUT] = "opt-out", >+ [PAX_FEATURE_FORCE_ENABLED] = "force enabled", >+ [PAX_FEATURE_UNKNOWN_STATUS] = "UNKNOWN -> changed to \"force enabled\"" >+}; >+ >+const char *pax_status_simple_str[] = { >+ [PAX_FEATURE_SIMPLE_DISABLED] = "disabled", >+ [PAX_FEATURE_SIMPLE_ENABLED] = "enabled" >+}; >+ >+struct prison * >+pax_get_prison(struct proc *p) >+{ >+ >+ /* p can be NULL with kernel threads, so use prison0 */ >+ if (p == NULL || p->p_ucred == NULL) >+ return (&prison0); >+ >+ return (p->p_ucred->cr_prison); >+} >+ >+struct prison * >+pax_get_prison_td(struct thread *td) >+{ >+ >+ if (td == NULL || td->td_ucred == NULL) >+ return (&prison0); >+ >+ return (td->td_ucred->cr_prison); >+} >+ >+void >+pax_get_flags(struct proc *p, uint32_t *flags) >+{ >+ >+ *flags = p->p_pax; >+} >+ >+void >+pax_get_flags_td(struct thread *td, uint32_t *flags) >+{ >+ >+ *flags = td->td_pax; >+} >+ >+static int >+pax_validate_flags(uint32_t flags) >+{ >+ >+ if ((flags & ~PAX_NOTE_ALL) != 0) >+ return (1); >+ >+ return (0); >+} >+ >+static int >+pax_check_conflicting_modes(uint32_t mode) >+{ >+ >+ if (((mode & PAX_NOTE_ALL_ENABLED) & ((mode & PAX_NOTE_ALL_DISABLED) >> 1)) != 0) >+ return (1); >+ >+ return (0); >+} >+ >+int >+pax_elf(struct image_params *imgp, uint32_t mode) >+{ >+ uint32_t flags, flags_aslr; >+ >+ flags = mode; >+ flags_aslr = 0; >+ >+ if (pax_validate_flags(flags) != 0) { >+ printf("%s: unknown paxflags: %x\n", __func__, flags); >+ return (ENOEXEC); >+ } >+ >+ if (pax_check_conflicting_modes(mode) != 0) { >+ /* >+ * indicate flags inconsistencies in dmesg and in user terminal >+ */ >+ printf("%s: inconsistent paxflags: %x\n", __func__, flags); >+ return (ENOEXEC); >+ } >+ >+#ifdef PAX_ASLR >+ flags_aslr = pax_aslr_setup_flags(imgp, mode); >+#endif >+ >+ flags = flags_aslr; >+ >+ CTR3(KTR_PAX, "%s : flags = %x mode = %x", >+ __func__, flags, mode); >+ >+ imgp->proc->p_pax = flags; >+ >+ return (0); >+} >+ >+ >+/* >+ * print out PaX settings on boot time, and validate some of them >+ */ >+static void >+pax_sysinit(void) >+{ >+ if (bootverbose) >+ printf("pax: initialize and check PaX and HardeneBSD features.\n"); >+} >+SYSINIT(pax, SI_SUB_PAX, SI_ORDER_FIRST, pax_sysinit, NULL); >+ >+void >+pax_init_prison(struct prison *pr) >+{ >+ >+ CTR2(KTR_PAX, "%s: Setting prison %s PaX variables\n", >+ __func__, pr->pr_name); >+ >+ pax_aslr_init_prison(pr); >+#ifdef COMPAT_FREEBSD32 >+ pax_aslr_init_prison32(pr); >+#endif >+} >Index: sys/kern/kern_pax_aslr.c >=================================================================== >--- /dev/null >+++ sys/kern/kern_pax_aslr.c >@@ -0,0 +1,878 @@ >+/*- >+ * Copyright (c) 2006 Elad Efrat <elad@NetBSD.org> >+ * Copyright (c) 2013-2015, by Oliver Pinter <oliver.pinter@hardenedbsd.org> >+ * Copyright (c) 2014-2015, by Shawn Webb <shawn.webb@hardenedbsd.org> >+ * 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 WARRANTIES >+ * 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 USE, >+ * 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$ >+ * >+ * HardenedBSD-version: 2fba75c32739bd7f7c80163ec88e3655c3130753 >+ * HardenedBSD-version: v16 >+ * >+ */ >+ >+#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/ktr.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/pax.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> >+ >+#ifndef PAX_ASLR_DELTA >+#define PAX_ASLR_DELTA(delta, lsb, len) \ >+ (((delta) & ((1UL << (len)) - 1)) << (lsb)) >+#endif /* PAX_ASLR_DELTA */ >+ >+/* >+ * generic ASLR values >+ * >+ * MMAP | 32 bit | 64 bit | compat | >+ * +-------+--------+--------+--------+ >+ * | MIN | 8 bit | 16 bit | 8 bit | >+ * +-------+--------+--------+--------+ >+ * | DEF | 14 bit | 21 bit | 14 bit | >+ * +-------+--------+--------+--------+ >+ * | MAX | 21 bit | 42 bit | 21 bit | >+ * +-------+--------+--------+--------+ >+ * >+ * STACK | 32 bit | 64 bit | 32 bit | >+ * +-------+--------+--------+--------+ >+ * | MIN | 8 bit | 16 bit | 8 bit | >+ * +-------+--------+--------+--------+ >+ * | DEF | 8 bit | 16 bit | 8 bit | >+ * +-------+--------+--------+--------+ >+ * | MAX | 21 bit | 42 bit | 21 bit | >+ * +-------+--------+--------+--------+ >+ * >+ * EXEC | 32 bit | 64 bit | 32 bit | >+ * +-------+--------+--------+--------+ >+ * | MIN | 8 bit | 16 bit | 8 bit | >+ * +-------+--------+--------+--------+ >+ * | DEF | 14 bit | 16 bit | 14 bit | >+ * +-------+--------+--------+--------+ >+ * | MAX | 21 bit | 42 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) / 3) >+#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) / 4) >+#endif /* PAX_ASLR_DELTA_STACK_MAX_LEN */ >+ >+#ifndef PAX_ASLR_DELTA_STACK_MAX_LEN >+#define PAX_ASLR_DELTA_STACK_MAX_LEN (((sizeof(void *) * NBBY) * 2) / 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) / 4) >+#endif /* PAX_ASLR_DELTA_EXEC_MIN_LEN */ >+ >+#ifndef PAX_ASLR_DELTA_EXEC_MAX_LEN >+#define PAX_ASLR_DELTA_EXEC_MAX_LEN (((sizeof(void *) * NBBY) * 2) / 3) >+#endif /* PAX_ASLR_DELTA_EXEC_MAX_LEN */ >+ >+/* >+ * ASLR default values for native host >+ */ >+#ifdef __LP64__ >+#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 16 >+#endif /* PAX_ASLR_DELTA_EXEC_DEF_LEN */ >+#else /* ! __LP64__ */ >+#ifndef PAX_ASLR_DELTA_MMAP_DEF_LEN >+#define PAX_ASLR_DELTA_MMAP_DEF_LEN 14 >+#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 14 >+#endif /* PAX_ASLR_DELTA_EXEC_DEF_LEN */ >+#endif /* __LP64__ */ >+ >+/* >+ * ASLR values for COMPAT_FREEBSD32, COMPAT_LINUX and MAP_32BIT >+ */ >+#if defined(COMPAT_LINUX) || defined(COMPAT_FREEBSD32) || defined(MAP_32BIT) >+#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) / 3) >+#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) / 4) >+#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) * 2) / 3) >+#endif /* PAX_ASLR_COMPAT_DELTA_STACK_MAX_LEN */ >+ >+#ifndef PAX_ASLR_COMPAT_DELTA_EXEC_LSB >+#define PAX_ASLR_COMPAT_DELTA_EXEC_LSB PAGE_SHIFT >+#endif /* PAX_ASLR_COMPAT_DELTA_EXEC_LSB */ >+ >+#ifndef PAX_ASLR_COMPAT_DELTA_EXEC_MIN_LEN >+#define PAX_ASLR_COMPAT_DELTA_EXEC_MIN_LEN ((sizeof(int) * NBBY) / 4) >+#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) * 2) / 3) >+#endif /* PAX_ASLR_COMPAT_DELTA_EXEC_MAX_LEN */ >+#endif >+ >+FEATURE(aslr, "Address Space Layout Randomization."); >+ >+static int pax_aslr_status = PAX_FEATURE_OPTOUT; >+static int pax_aslr_mmap_len = PAX_ASLR_DELTA_MMAP_DEF_LEN; >+static int pax_aslr_stack_len = PAX_ASLR_DELTA_STACK_DEF_LEN; >+static int pax_aslr_exec_len = PAX_ASLR_DELTA_EXEC_DEF_LEN; >+ >+#ifdef COMPAT_FREEBSD32 >+static int pax_aslr_compat_status = PAX_FEATURE_OPTOUT; >+static int pax_aslr_compat_mmap_len = PAX_ASLR_COMPAT_DELTA_MMAP_MIN_LEN; >+static int pax_aslr_compat_stack_len = PAX_ASLR_COMPAT_DELTA_STACK_MIN_LEN; >+static int pax_aslr_compat_exec_len = PAX_ASLR_COMPAT_DELTA_EXEC_MIN_LEN; >+#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.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_len", &pax_aslr_compat_mmap_len); >+TUNABLE_INT("security.pax.aslr.compat.stack_len", &pax_aslr_compat_stack_len); >+TUNABLE_INT("security.pax.aslr.compat.exec_len", &pax_aslr_compat_exec_len); >+#endif >+ >+#ifdef PAX_SYSCTLS >+SYSCTL_DECL(_security_pax); >+ >+/* >+ * sysctls >+ */ >+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_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, 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,21] 64 bit: [16,42]"); >+ >+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: [8,21] 64 bit: [16,42]"); >+ >+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: [8,21] 64 bit: [16,42]"); >+ >+static int >+sysctl_pax_aslr_status(SYSCTL_HANDLER_ARGS) >+{ >+ struct prison *pr; >+ int err, val; >+ >+ pr = pax_get_prison_td(req->td); >+ >+ val = pr->pr_hardening.hr_pax_aslr_status; >+ err = sysctl_handle_int(oidp, &val, sizeof(int), req); >+ if (err || (req->newptr == NULL)) >+ return (err); >+ >+ switch (val) { >+ case PAX_FEATURE_DISABLED: >+ case PAX_FEATURE_OPTIN: >+ case PAX_FEATURE_OPTOUT: >+ case PAX_FEATURE_FORCE_ENABLED: >+ if (pr == &prison0) >+ pax_aslr_status = val; >+ >+ pr->pr_hardening.hr_pax_aslr_status = val; >+ break; >+ default: >+ return (EINVAL); >+ } >+ >+ return (0); >+} >+ >+static int >+sysctl_pax_aslr_mmap(SYSCTL_HANDLER_ARGS) >+{ >+ struct prison *pr; >+ int err, val; >+ >+ pr = pax_get_prison_td(req->td); >+ >+ val = pr->pr_hardening.hr_pax_aslr_mmap_len; >+ err = 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 == &prison0) >+ pax_aslr_mmap_len = val; >+ >+ pr->pr_hardening.hr_pax_aslr_mmap_len = val; >+ >+ return (0); >+} >+ >+static int >+sysctl_pax_aslr_stack(SYSCTL_HANDLER_ARGS) >+{ >+ struct prison *pr; >+ int err, val; >+ >+ pr = pax_get_prison_td(req->td); >+ >+ val = pr->pr_hardening.hr_pax_aslr_stack_len; >+ err = 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 == &prison0) >+ pax_aslr_stack_len = val; >+ >+ pr->pr_hardening.hr_pax_aslr_stack_len = val; >+ >+ return (0); >+} >+ >+static int >+sysctl_pax_aslr_exec(SYSCTL_HANDLER_ARGS) >+{ >+ struct prison *pr; >+ int err, val; >+ >+ pr = pax_get_prison_td(req->td); >+ >+ val = pr->pr_hardening.hr_pax_aslr_exec_len; >+ err = sysctl_handle_int(oidp, &val, sizeof(int), req); >+ if (err || (req->newptr == NULL)) >+ return (err); >+ >+ if (val < PAX_ASLR_DELTA_EXEC_MIN_LEN || >+ val > PAX_ASLR_DELTA_EXEC_MAX_LEN) >+ return (EINVAL); >+ >+ if (pr == &prison0) >+ pax_aslr_exec_len = val; >+ >+ pr->pr_hardening.hr_pax_aslr_exec_len = val; >+ >+ 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: [8,16]"); >+ >+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: [8,16]"); >+ >+static int >+sysctl_pax_aslr_compat_status(SYSCTL_HANDLER_ARGS) >+{ >+ struct prison *pr; >+ int err, val; >+ >+ pr = pax_get_prison_td(req->td); >+ >+ val = pr->pr_hardening.hr_pax_aslr_compat_status; >+ err = sysctl_handle_int(oidp, &val, sizeof(int), req); >+ if (err || (req->newptr == NULL)) >+ return (err); >+ >+ switch (val) { >+ case PAX_FEATURE_DISABLED: >+ case PAX_FEATURE_OPTIN: >+ case PAX_FEATURE_OPTOUT: >+ case PAX_FEATURE_FORCE_ENABLED: >+ if (pr == &prison0) >+ pax_aslr_compat_status = val; >+ >+ pr->pr_hardening.hr_pax_aslr_compat_status = val; >+ break; >+ default: >+ return (EINVAL); >+ } >+ >+ return (0); >+} >+ >+static int >+sysctl_pax_aslr_compat_mmap(SYSCTL_HANDLER_ARGS) >+{ >+ struct prison *pr; >+ int err, val; >+ >+ pr = pax_get_prison_td(req->td); >+ >+ val = pr->pr_hardening.hr_pax_aslr_compat_mmap_len; >+ err = 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 == &prison0) >+ pax_aslr_compat_mmap_len = val; >+ >+ pr->pr_hardening.hr_pax_aslr_compat_mmap_len = val; >+ >+ return (0); >+} >+ >+static int >+sysctl_pax_aslr_compat_stack(SYSCTL_HANDLER_ARGS) >+{ >+ struct prison *pr; >+ int err, val; >+ >+ pr = pax_get_prison_td(req->td); >+ >+ val = pr->pr_hardening.hr_pax_aslr_compat_stack_len; >+ err = 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 == &prison0) >+ pax_aslr_compat_stack_len = val; >+ >+ pr->pr_hardening.hr_pax_aslr_compat_stack_len = val; >+ >+ return (0); >+} >+ >+static int >+sysctl_pax_aslr_compat_exec(SYSCTL_HANDLER_ARGS) >+{ >+ struct prison *pr; >+ int err, val; >+ >+ pr = pax_get_prison_td(req->td); >+ >+ val = pr->pr_hardening.hr_pax_aslr_compat_exec_len; >+ err = 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 == &prison0) >+ pax_aslr_compat_exec_len = val; >+ >+ pr->pr_hardening.hr_pax_aslr_compat_exec_len = val; >+ >+ return (0); >+} >+ >+#endif /* COMPAT_FREEBSD32 */ >+#endif /* PAX_SYSCTLS */ >+ >+ >+/* >+ * ASLR functions >+ */ >+ >+static void >+pax_aslr_sysinit(void) >+{ >+ >+ switch (pax_aslr_status) { >+ case PAX_FEATURE_DISABLED: >+ case PAX_FEATURE_OPTIN: >+ case PAX_FEATURE_OPTOUT: >+ case PAX_FEATURE_FORCE_ENABLED: >+ break; >+ default: >+ printf("warning: invalid settings in loader.conf:" >+ " (pax_aslr_status = %d)\n", pax_aslr_status); >+ pax_aslr_status = PAX_FEATURE_FORCE_ENABLED; >+ break; >+ } >+ if (bootverbose) { >+ printf("PAX ASLR status: %s\n", pax_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); >+ } >+} >+SYSINIT(pax_aslr, SI_SUB_PAX, SI_ORDER_SECOND, pax_aslr_sysinit, NULL); >+ >+int >+pax_aslr_active(struct proc *p) >+{ >+ uint32_t flags; >+ >+ pax_get_flags(p, &flags); >+ >+ CTR3(KTR_PAX, "%s: pid = %d p_pax = %x", >+ __func__, p->p_pid, flags); >+ >+ if ((flags & PAX_NOTE_ASLR) == PAX_NOTE_ASLR) >+ return (true); >+ >+ if ((flags & PAX_NOTE_NOASLR) == PAX_NOTE_NOASLR) >+ return (false); >+ >+ return (true); >+} >+ >+void >+pax_aslr_init_vmspace(struct proc *p) >+{ >+ struct prison *pr; >+ struct vmspace *vm; >+ unsigned long rand_buf; >+ >+ vm = p->p_vmspace; >+ >+ pr = pax_get_prison(p); >+ arc4rand(&rand_buf, sizeof(rand_buf), 0); >+ vm->vm_aslr_delta_mmap = PAX_ASLR_DELTA(rand_buf, >+ PAX_ASLR_DELTA_MMAP_LSB, >+ pr->pr_hardening.hr_pax_aslr_mmap_len); >+ >+ arc4rand(&rand_buf, sizeof(rand_buf), 0); >+ vm->vm_aslr_delta_stack = PAX_ASLR_DELTA(rand_buf, >+ PAX_ASLR_DELTA_STACK_LSB, >+ pr->pr_hardening.hr_pax_aslr_stack_len); >+ vm->vm_aslr_delta_stack = ALIGN(vm->vm_aslr_delta_stack); >+ >+ arc4rand(&rand_buf, sizeof(rand_buf), 0); >+ vm->vm_aslr_delta_exec = PAX_ASLR_DELTA(rand_buf, >+ PAX_ASLR_DELTA_EXEC_LSB, >+ pr->pr_hardening.hr_pax_aslr_exec_len); >+ >+ CTR2(KTR_PAX, "%s: vm_aslr_delta_mmap=%p\n", >+ __func__, (void *)vm->vm_aslr_delta_mmap); >+ CTR2(KTR_PAX, "%s: vm_aslr_delta_stack=%p\n", >+ __func__, (void *)vm->vm_aslr_delta_stack); >+ CTR2(KTR_PAX, "%s: vm_aslr_delta_exec=%p\n", >+ __func__, (void *)vm->vm_aslr_delta_exec); >+} >+ >+#ifdef COMPAT_FREEBSD32 >+static void >+pax_compat_aslr_sysinit(void) >+{ >+ >+ switch (pax_aslr_compat_status) { >+ case PAX_FEATURE_DISABLED: >+ case PAX_FEATURE_OPTIN: >+ case PAX_FEATURE_OPTOUT: >+ case PAX_FEATURE_FORCE_ENABLED: >+ break; >+ default: >+ printf("warning: invalid settings in loader.conf! " >+ "(pax_aslr_compat_status = %d)\n", pax_aslr_compat_status); >+ pax_aslr_compat_status = PAX_FEATURE_FORCE_ENABLED; >+ break; >+ } >+ if (bootverbose) { >+ printf("PAX ASLR (compat) status: %s\n", pax_status_str[pax_aslr_compat_status]); >+ 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_len); >+ printf("PAX ASLR (compat) stack: %d bit\n", pax_aslr_compat_stack_len); >+ } >+} >+SYSINIT(pax_compat_aslr, SI_SUB_PAX, SI_ORDER_SECOND, pax_compat_aslr_sysinit, NULL); >+ >+void >+pax_aslr_init_vmspace32(struct proc *p) >+{ >+ struct prison *pr; >+ struct vmspace *vm; >+ long rand_buf; >+ >+ vm = p->p_vmspace; >+ >+ pr = pax_get_prison(p); >+ arc4rand(&rand_buf, sizeof(rand_buf), 0); >+ vm->vm_aslr_delta_mmap = PAX_ASLR_DELTA(rand_buf, >+ PAX_ASLR_COMPAT_DELTA_MMAP_LSB, >+ pr->pr_hardening.hr_pax_aslr_compat_mmap_len); >+ >+ arc4rand(&rand_buf, sizeof(rand_buf), 0); >+ vm->vm_aslr_delta_stack = PAX_ASLR_DELTA(rand_buf, >+ PAX_ASLR_COMPAT_DELTA_STACK_LSB, >+ pr->pr_hardening.hr_pax_aslr_compat_stack_len); >+ vm->vm_aslr_delta_stack = ALIGN(vm->vm_aslr_delta_stack); >+ >+ arc4rand(&rand_buf, sizeof(rand_buf), 0); >+ vm->vm_aslr_delta_exec = PAX_ASLR_DELTA(rand_buf, >+ PAX_ASLR_COMPAT_DELTA_EXEC_LSB, >+ pr->pr_hardening.hr_pax_aslr_compat_exec_len); >+ >+ CTR2(KTR_PAX, "%s: vm_aslr_delta_mmap=%p\n", >+ __func__, (void *)vm->vm_aslr_delta_mmap); >+ CTR2(KTR_PAX, "%s: vm_aslr_delta_stack=%p\n", >+ __func__, (void *)vm->vm_aslr_delta_stack); >+ CTR2(KTR_PAX, "%s: vm_aslr_delta_exec=%p\n", >+ __func__, (void *)vm->vm_aslr_delta_exec); >+} >+#endif >+ >+void >+pax_aslr_init(struct image_params *imgp) >+{ >+ struct proc *p; >+ >+ p = imgp->proc; >+ >+ if (!pax_aslr_active(p)) >+ return; >+ >+ if (imgp->sysent->sv_pax_aslr_init != NULL) >+ imgp->sysent->sv_pax_aslr_init(p); >+} >+ >+void >+pax_aslr_init_prison(struct prison *pr) >+{ >+ struct prison *pr_p; >+ >+ CTR2(KTR_PAX, "%s: Setting prison %s PaX variables\n", >+ __func__, pr->pr_name); >+ >+ if (pr == &prison0) { >+ /* prison0 has no parent, use globals */ >+ pr->pr_hardening.hr_pax_aslr_status = pax_aslr_status; >+ pr->pr_hardening.hr_pax_aslr_mmap_len = >+ pax_aslr_mmap_len; >+ pr->pr_hardening.hr_pax_aslr_stack_len = >+ pax_aslr_stack_len; >+ pr->pr_hardening.hr_pax_aslr_exec_len = >+ pax_aslr_exec_len; >+ } else { >+ KASSERT(pr->pr_parent != NULL, >+ ("%s: pr->pr_parent == NULL", __func__)); >+ pr_p = pr->pr_parent; >+ >+ pr->pr_hardening.hr_pax_aslr_status = >+ pr_p->pr_hardening.hr_pax_aslr_status; >+ pr->pr_hardening.hr_pax_aslr_mmap_len = >+ pr_p->pr_hardening.hr_pax_aslr_mmap_len; >+ pr->pr_hardening.hr_pax_aslr_stack_len = >+ pr_p->pr_hardening.hr_pax_aslr_stack_len; >+ pr->pr_hardening.hr_pax_aslr_exec_len = >+ pr_p->pr_hardening.hr_pax_aslr_exec_len; >+ } >+} >+ >+#ifdef COMPAT_FREEBSD32 >+void >+pax_aslr_init_prison32(struct prison *pr) >+{ >+ struct prison *pr_p; >+ >+ CTR2(KTR_PAX, "%s: Setting prison %s PaX variables\n", >+ __func__, pr->pr_name); >+ >+ if (pr == &prison0) { >+ /* prison0 has no parent, use globals */ >+ >+ pr->pr_hardening.hr_pax_aslr_compat_status = >+ pax_aslr_compat_status; >+ pr->pr_hardening.hr_pax_aslr_compat_mmap_len = >+ pax_aslr_compat_mmap_len; >+ pr->pr_hardening.hr_pax_aslr_compat_stack_len = >+ pax_aslr_compat_stack_len; >+ pr->pr_hardening.hr_pax_aslr_compat_exec_len = >+ pax_aslr_compat_exec_len; >+ } else { >+ KASSERT(pr->pr_parent != NULL, >+ ("%s: pr->pr_parent == NULL", __func__)); >+ pr_p = pr->pr_parent; >+ >+ pr->pr_hardening.hr_pax_aslr_compat_status = >+ pr_p->pr_hardening.hr_pax_aslr_compat_status; >+ pr->pr_hardening.hr_pax_aslr_compat_mmap_len = >+ pr_p->pr_hardening.hr_pax_aslr_compat_mmap_len; >+ pr->pr_hardening.hr_pax_aslr_compat_stack_len = >+ pr_p->pr_hardening.hr_pax_aslr_compat_stack_len; >+ pr->pr_hardening.hr_pax_aslr_compat_exec_len = >+ pr_p->pr_hardening.hr_pax_aslr_compat_exec_len; >+ } >+} >+#endif /* COMPAT_FREEBSD32 */ >+ >+void >+pax_aslr_mmap(struct proc *p, vm_offset_t *addr, vm_offset_t orig_addr, int flags) >+{ >+ >+ if (!pax_aslr_active(p)) >+ return; >+ >+ if (!(flags & MAP_FIXED) && ((orig_addr == 0) || !(flags & MAP_ANON))) { >+ CTR4(KTR_PAX, "%s: applying to %p orig_addr=%p flags=%x\n", >+ __func__, (void *)*addr, (void *)orig_addr, flags); >+ >+#ifdef MAP_32BIT >+ if (flags & MAP_32BIT) { >+ int len_32bit; >+ >+#ifdef COMPAT_FREEBSD32 >+ len_32bit = pax_aslr_compat_mmap_len; >+#else >+ len_32bit = PAX_ASLR_COMPAT_DELTA_MMAP_MIN_LEN; >+#endif >+ *addr += PAX_ASLR_DELTA(arc4random(), >+ PAX_ASLR_COMPAT_DELTA_MMAP_LSB, >+ len_32bit); >+ } else >+#endif /* MAP_32BIT */ >+ *addr += p->p_vmspace->vm_aslr_delta_mmap; >+ CTR2(KTR_PAX, "%s: result %p\n", __func__, (void *)*addr); >+ } else >+ CTR4(KTR_PAX, "%s: not applying to %p orig_addr=%p flags=%x\n", >+ __func__, (void *)*addr, (void *)orig_addr, flags); >+} >+ >+void >+pax_aslr_stack(struct proc *p, uintptr_t *addr) >+{ >+ uintptr_t orig_addr; >+ >+ if (!pax_aslr_active(p)) >+ return; >+ >+ orig_addr = *addr; >+ *addr -= p->p_vmspace->vm_aslr_delta_stack; >+ CTR3(KTR_PAX, "%s: orig_addr=%p, new_addr=%p\n", >+ __func__, (void *)orig_addr, (void *)*addr); >+} >+ >+void >+pax_aslr_stack_fixup(struct proc *p) >+{ >+ >+ if (!pax_aslr_active(p)) >+ return; >+ >+ p->p_vmspace->vm_maxsaddr -= p->p_vmspace->vm_aslr_delta_stack; >+} >+ >+void >+pax_aslr_execbase(struct proc *p, u_long *et_dyn_addr) >+{ >+ >+ if (!pax_aslr_active(p)) >+ return; >+ >+ *et_dyn_addr += p->p_vmspace->vm_aslr_delta_exec; >+} >+ >+uint32_t >+pax_aslr_setup_flags(struct image_params *imgp, uint32_t mode) >+{ >+ struct prison *pr; >+ uint32_t flags, status; >+ >+ flags = 0; >+ status = 0; >+ >+ pr = pax_get_prison(imgp->proc); >+ status = pr->pr_hardening.hr_pax_aslr_status; >+ >+ if (status == PAX_FEATURE_DISABLED) { >+ flags &= ~PAX_NOTE_ASLR; >+ flags |= PAX_NOTE_NOASLR; >+ >+ return (flags); >+ } >+ >+ if (status == PAX_FEATURE_FORCE_ENABLED) { >+ flags |= PAX_NOTE_ASLR; >+ flags &= ~PAX_NOTE_NOASLR; >+ >+ return (flags); >+ } >+ >+ if (status == PAX_FEATURE_OPTIN) { >+ if (mode & PAX_NOTE_ASLR) { >+ flags |= PAX_NOTE_ASLR; >+ flags &= ~PAX_NOTE_NOASLR; >+ } else { >+ flags &= ~PAX_NOTE_ASLR; >+ flags |= PAX_NOTE_NOASLR; >+ } >+ >+ return (flags); >+ } >+ >+ if (status == PAX_FEATURE_OPTOUT) { >+ if (mode & PAX_NOTE_NOASLR) { >+ flags &= ~PAX_NOTE_ASLR; >+ flags |= PAX_NOTE_NOASLR; >+ } else { >+ flags |= PAX_NOTE_ASLR; >+ flags &= ~PAX_NOTE_NOASLR; >+ } >+ >+ return (flags); >+ } >+ >+ /* >+ * unknown status, force ASLR >+ */ >+ flags |= PAX_NOTE_ASLR; >+ flags &= ~PAX_NOTE_NOASLR; >+ >+ return (flags); >+} >+ >Index: sys/kern/kern_thr.c >=================================================================== >--- sys/kern/kern_thr.c >+++ sys/kern/kern_thr.c >@@ -254,6 +254,7 @@ > td->td_proc->p_flag |= P_HADTHREADS; > thread_link(newtd, p); > bcopy(p->p_comm, newtd->td_name, sizeof(newtd->td_name)); >+ newtd->td_pax = p->p_pax; > thread_lock(td); > /* let the scheduler know about these things. */ > sched_fork_thread(td, newtd); >Index: sys/kern/sys_process.c >=================================================================== >--- sys/kern/sys_process.c >+++ sys/kern/sys_process.c >@@ -33,14 +33,16 @@ > __FBSDID("$FreeBSD$"); > > #include "opt_compat.h" >+#include "opt_pax.h" > > #include <sys/param.h> > #include <sys/systm.h> > #include <sys/lock.h> > #include <sys/mutex.h> > #include <sys/syscallsubr.h> > #include <sys/sysent.h> > #include <sys/sysproto.h> >+#include <sys/pax.h> > #include <sys/priv.h> > #include <sys/proc.h> > #include <sys/vnode.h> >@@ -651,6 +653,9 @@ > > /* Lock proctree before locking the process. */ > switch (req) { >+#ifdef PAX_ASLR >+ case PT_PAX: >+#endif > case PT_TRACE_ME: > case PT_ATTACH: > case PT_STEP: >@@ -668,7 +673,7 @@ > } > > write = 0; >- if (req == PT_TRACE_ME) { >+ if (req == PT_TRACE_ME || req == PT_PAX) { > p = td->td_proc; > PROC_LOCK(p); > } else { >@@ -735,6 +740,15 @@ > * Permissions check > */ > switch (req) { >+ case PT_PAX: >+ /* securelevel should be 0 to allow this */ >+ if ((data & PAX_NOTE_NOASLR) == PAX_NOTE_NOASLR) { >+ if (securelevel_gt(p->p_ucred, 0) != 0) { >+ error = EPERM; >+ goto fail; >+ } >+ } >+ break; > case PT_TRACE_ME: > /* Always legal. */ > break; >@@ -820,6 +834,9 @@ > td->td_retval[0] = 0; > > switch (req) { >+ case PT_PAX: >+ p->p_paxdebug = data; >+ break; > case PT_TRACE_ME: > /* set my trace flag and "owner" so it can read/write me */ > p->p_flag |= P_TRACED; >Index: sys/mips/mips/elf_machdep.c >=================================================================== >--- sys/mips/mips/elf_machdep.c >+++ sys/mips/mips/elf_machdep.c >@@ -28,14 +28,17 @@ > #include <sys/cdefs.h> > __FBSDID("$FreeBSD$"); > >+#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> > #include <sys/sysent.h> > #include <sys/imgact_elf.h> >+#include <sys/pax.h> > #include <sys/proc.h> > #include <sys/syscall.h> > #include <sys/signalvar.h> >@@ -83,6 +86,9 @@ > .sv_fetch_syscall_args = cpu_fetch_syscall_args, > .sv_syscallnames = syscallnames, > .sv_schedtail = NULL, >+#ifdef PAX_ASLR >+ .sv_pax_aslr_init = pax_aslr_init_vmspace, >+#endif > }; > > static Elf64_Brandinfo freebsd_brand_info = { >@@ -139,6 +145,9 @@ > .sv_fetch_syscall_args = cpu_fetch_syscall_args, > .sv_syscallnames = syscallnames, > .sv_schedtail = NULL, >+#ifdef PAX_ASLR >+ .sv_pax_aslr_init = pax_aslr_init_vmspace32, >+#endif > }; > > static Elf32_Brandinfo freebsd_brand_info = { >Index: sys/mips/mips/freebsd32_machdep.c >=================================================================== >--- sys/mips/mips/freebsd32_machdep.c >+++ sys/mips/mips/freebsd32_machdep.c >@@ -31,6 +31,7 @@ > */ > > #include "opt_compat.h" >+#include "opt_pax.h" > > #define __ELF_WORD_SIZE 32 > >@@ -45,6 +46,7 @@ > #include <sys/proc.h> > #include <sys/namei.h> > #include <sys/fcntl.h> >+#include <sys/pax.h> > #include <sys/sysent.h> > #include <sys/imgact_elf.h> > #include <sys/syscall.h> >@@ -106,6 +108,9 @@ > .sv_fetch_syscall_args = cpu_fetch_syscall_args, > .sv_syscallnames = freebsd32_syscallnames, > .sv_schedtail = NULL, >+#ifdef PAX_ASLR >+ .sv_pax_aslr_init = pax_aslr_init_vmspace32, >+#endif > }; > INIT_SYSENTVEC(elf32_sysvec, &elf32_freebsd_sysvec); > >Index: sys/powerpc/powerpc/elf32_machdep.c >=================================================================== >--- sys/powerpc/powerpc/elf32_machdep.c >+++ sys/powerpc/powerpc/elf32_machdep.c >@@ -25,6 +25,8 @@ > * $FreeBSD$ > */ > >+#include "opt_pax.h" >+ > #include <sys/param.h> > #include <sys/kernel.h> > #include <sys/systm.h> >@@ -34,6 +36,7 @@ > #include <sys/exec.h> > #include <sys/imgact.h> > #include <sys/malloc.h> >+#include <sys/pax.h> > #include <sys/proc.h> > #include <sys/namei.h> > #include <sys/fcntl.h> >@@ -108,6 +111,9 @@ > .sv_shared_page_base = FREEBSD32_SHAREDPAGE, > .sv_shared_page_len = PAGE_SIZE, > .sv_schedtail = NULL, >+#ifdef PAX_ASLR >+ .sv_pax_aslr_init = pax_aslr_init_vmspace32, >+#endif > }; > INIT_SYSENTVEC(elf32_sysvec, &elf32_freebsd_sysvec); > >Index: sys/powerpc/powerpc/elf64_machdep.c >=================================================================== >--- sys/powerpc/powerpc/elf64_machdep.c >+++ sys/powerpc/powerpc/elf64_machdep.c >@@ -25,12 +25,15 @@ > * $FreeBSD$ > */ > >+#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/malloc.h> >+#include <sys/pax.h> > #include <sys/proc.h> > #include <sys/namei.h> > #include <sys/fcntl.h> >@@ -84,6 +87,9 @@ > .sv_shared_page_base = SHAREDPAGE, > .sv_shared_page_len = PAGE_SIZE, > .sv_schedtail = NULL, >+#ifdef PAX_ASLR >+ .sv_pax_aslr_init = pax_aslr_init_vmspace, >+#endif > }; > INIT_SYSENTVEC(elf64_sysvec, &elf64_freebsd_sysvec); > >Index: sys/sparc64/sparc64/elf_machdep.c >=================================================================== >--- sys/sparc64/sparc64/elf_machdep.c >+++ sys/sparc64/sparc64/elf_machdep.c >@@ -34,12 +34,15 @@ > #include <sys/cdefs.h> > __FBSDID("$FreeBSD$"); > >+#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> >+#include <sys/pax.h> > #include <sys/proc.h> > #include <sys/sysent.h> > #include <sys/imgact_elf.h> >@@ -87,6 +90,9 @@ > .sv_fetch_syscall_args = cpu_fetch_syscall_args, > .sv_syscallnames = syscallnames, > .sv_schedtail = NULL, >+#ifdef PAX_ASLR >+ .sv_pax_aslr_init = pax_aslr_init_vmspace, >+#endif > }; > > static Elf64_Brandinfo freebsd_brand_info = { >Index: sys/sys/imgact.h >=================================================================== >--- sys/sys/imgact.h >+++ sys/sys/imgact.h >@@ -80,6 +80,7 @@ > unsigned long pagesizes; > int pagesizeslen; > vm_prot_t stack_prot; >+ int pax_flags; > }; > > #ifdef _KERNEL >Index: sys/sys/jail.h >=================================================================== >--- sys/sys/jail.h >+++ sys/sys/jail.h >@@ -30,6 +30,10 @@ > #ifndef _SYS_JAIL_H_ > #define _SYS_JAIL_H_ > >+#if defined(_KERNEL) || defined(_WANT_PRISON) >+#include <sys/pax.h> >+#endif >+ > #ifdef _KERNEL > struct jail_v0 { > u_int32_t version; >@@ -186,6 +190,7 @@ > char pr_hostname[MAXHOSTNAMELEN]; /* (p) jail hostname */ > char pr_domainname[MAXHOSTNAMELEN]; /* (p) jail domainname */ > char pr_hostuuid[HOSTUUIDLEN]; /* (p) jail hostuuid */ >+ struct hardening_features pr_hardening; /* (p) PaX-inspired hardening features */ > char pr_osrelease[OSRELEASELEN]; /* (c) kern.osrelease value */ > }; > >Index: sys/sys/kernel.h >=================================================================== >--- sys/sys/kernel.h >+++ sys/sys/kernel.h >@@ -102,6 +102,7 @@ > SI_SUB_WITNESS = 0x1A80000, /* witness initialization */ > SI_SUB_MTX_POOL_DYNAMIC = 0x1AC0000, /* dynamic mutex pool */ > SI_SUB_LOCK = 0x1B00000, /* various locks */ >+ SI_SUB_PAX = 0x1B80000, /* pax setup */ > SI_SUB_EVENTHANDLER = 0x1C00000, /* eventhandler init */ > SI_SUB_VNET_PRELINK = 0x1E00000, /* vnet init before modules */ > SI_SUB_KLD = 0x2000000, /* KLD and module setup */ >Index: sys/sys/ktr_class.h >=================================================================== >--- sys/sys/ktr_class.h >+++ sys/sys/ktr_class.h >@@ -71,7 +71,8 @@ > #define KTR_INET6 0x10000000 /* IPv6 stack */ > #define KTR_SCHED 0x20000000 /* Machine parsed sched info. */ > #define KTR_BUF 0x40000000 /* Buffer cache */ >-#define KTR_ALL 0x7fffffff >+#define KTR_PAX 0x80000000 /* PaX */ >+#define KTR_ALL 0xffffffff > > /* KTR trace classes to compile in */ > #ifdef KTR >Index: sys/sys/pax.h >=================================================================== >--- /dev/null >+++ sys/sys/pax.h >@@ -0,0 +1,118 @@ >+/*- >+ * Copyright (c) 2006 Elad Efrat <elad@NetBSD.org> >+ * Copyright (c) 2013-2015, by Oliver Pinter <oliver.pinter@hardenedbsd.org> >+ * Copyright (c) 2014-2015, by Shawn Webb <shawn.webb@hardenedbsd.org> >+ * 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 WARRANTIES >+ * 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 USE, >+ * 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$ >+ * >+ * HardenedBSD-version: 2fba75c32739bd7f7c80163ec88e3655c3130753 >+ * HardenedBSD-version: v16 >+ * >+ */ >+ >+#ifndef __SYS_PAX_H >+#define __SYS_PAX_H >+ >+#if defined(_KERNEL) || defined(_WANT_PRISON) >+struct hardening_features { >+ int hr_pax_aslr_status; /* (p) PaX ASLR enabled */ >+ int hr_pax_aslr_mmap_len; /* (p) Number of bits randomized with mmap */ >+ int hr_pax_aslr_stack_len; /* (p) Number of bits randomized with stack */ >+ int hr_pax_aslr_exec_len; /* (p) Number of bits randomized with the execbase */ >+ int hr_pax_aslr_compat_status; /* (p) PaX ASLR enabled (compat32) */ >+ int hr_pax_aslr_compat_mmap_len; /* (p) Number of bits randomized with mmap (compat32) */ >+ int hr_pax_aslr_compat_stack_len; /* (p) Number of bits randomized with stack (compat32) */ >+ int hr_pax_aslr_compat_exec_len; /* (p) Number of bits randomized with the execbase (compat32) */ >+}; >+#endif >+ >+#ifdef _KERNEL >+struct image_params; >+struct prison; >+struct thread; >+struct proc; >+struct vnode; >+struct vm_offset_t; >+ >+/* >+ * used in sysctl handler >+ */ >+#define PAX_FEATURE_DISABLED 0 >+#define PAX_FEATURE_OPTIN 1 >+#define PAX_FEATURE_OPTOUT 2 >+#define PAX_FEATURE_FORCE_ENABLED 3 >+#define PAX_FEATURE_UNKNOWN_STATUS 4 >+ >+extern const char *pax_status_str[]; >+ >+#define PAX_FEATURE_SIMPLE_DISABLED 0 >+#define PAX_FEATURE_SIMPLE_ENABLED 1 >+ >+extern const char *pax_status_simple_str[]; >+ >+/* >+ * generic pax functions >+ */ >+int pax_elf(struct image_params *, uint32_t); >+void pax_get_flags(struct proc *p, uint32_t *flags); >+void pax_get_flags_td(struct thread *td, uint32_t *flags); >+struct prison *pax_get_prison(struct proc *p); >+struct prison *pax_get_prison_td(struct thread *td); >+void pax_init_prison(struct prison *pr); >+ >+/* >+ * ASLR related functions >+ */ >+int pax_aslr_active(struct proc *p); >+void pax_aslr_init_vmspace(struct proc *p); >+void pax_aslr_init_vmspace32(struct proc *p); >+#ifdef PAX_ASLR >+void pax_aslr_init_prison(struct prison *pr); >+void pax_aslr_init_prison32(struct prison *pr); >+#else >+#define pax_aslr_init_prison(pr) do {} while (0) >+#define pax_aslr_init_prison32(pr) do {} while (0) >+#endif >+void pax_aslr_init(struct image_params *imgp); >+void pax_aslr_execbase(struct proc *p, u_long *et_dyn_addr); >+void pax_aslr_mmap(struct proc *p, vm_offset_t *addr, >+ vm_offset_t orig_addr, int flags); >+uint32_t pax_aslr_setup_flags(struct image_params *imgp, uint32_t mode); >+void pax_aslr_stack(struct proc *p, uintptr_t *addr); >+void pax_aslr_stack_fixup(struct proc *p); >+#endif /* _KERNEL */ >+ >+/* >+ * keep this values, to keep compatibility with HardenedBSD >+ */ >+#define PAX_NOTE_ASLR 0x00000040 >+#define PAX_NOTE_NOASLR 0x00000080 >+ >+#define PAX_NOTE_ALL_ENABLED (PAX_NOTE_ASLR) >+#define PAX_NOTE_ALL_DISABLED (PAX_NOTE_NOASLR) >+#define PAX_NOTE_ALL (PAX_NOTE_ALL_ENABLED | PAX_NOTE_ALL_DISABLED) >+ >+#endif /* __SYS_PAX_H */ >Index: sys/sys/proc.h >=================================================================== >--- sys/sys/proc.h >+++ sys/sys/proc.h >@@ -288,6 +288,7 @@ > u_char td_pri_class; /* (t) Scheduling class. */ > u_char td_user_pri; /* (t) User pri from estcpu and nice. */ > u_char td_base_user_pri; /* (t) Base user pri */ >+ uint32_t td_pax; /* (b) cached PaX settings from process */ > #define td_endcopy td_pcb > > /* >@@ -578,6 +579,8 @@ > pid_t p_reapsubtree; /* (e) Pid of the direct child of the > reaper which spawned > our subtree. */ >+ u_int p_pax; /* (b) PaX is enabled to this process */ >+ u_int p_paxdebug; /* (b) PaX flags set via PTrace */ > /* End area that is copied on creation. */ > #define p_endcopy p_xstat > >Index: sys/sys/ptrace.h >=================================================================== >--- sys/sys/ptrace.h >+++ sys/sys/ptrace.h >@@ -76,6 +76,7 @@ > #define PT_VM_ENTRY 41 /* Get VM map (entry) */ > > #define PT_FIRSTMACH 64 /* for machine-specific requests */ >+#define PT_PAX 65 /* Toggle PaX-inspired hardening features */ > #include <machine/ptrace.h> /* machine-specific requests, if any */ > > struct ptrace_io_desc { >Index: sys/sys/sysent.h >=================================================================== >--- sys/sys/sysent.h >+++ sys/sys/sysent.h >@@ -38,6 +38,7 @@ > struct sysent; > struct thread; > struct ksiginfo; >+struct proc; > > typedef int sy_call_t(struct thread *, void *); > >@@ -136,6 +137,7 @@ > uint32_t sv_timekeep_gen; > void *sv_shared_page_obj; > void (*sv_schedtail)(struct thread *); >+ void (*sv_pax_aslr_init)(struct proc *p); > }; > > #define SV_ILP32 0x000100 >Index: sys/vm/vm_map.h >=================================================================== >--- sys/vm/vm_map.h >+++ sys/vm/vm_map.h >@@ -241,6 +241,9 @@ > 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_offset_t vm_aslr_delta_mmap; /* mmap() random delta for ASLR */ >+ vm_offset_t vm_aslr_delta_stack; /* stack random delta for ASLR */ >+ vm_offset_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 >Index: sys/vm/vm_map.c >=================================================================== >--- sys/vm/vm_map.c >+++ sys/vm/vm_map.c >@@ -65,6 +65,8 @@ > #include <sys/cdefs.h> > __FBSDID("$FreeBSD$"); > >+#include "opt_pax.h" >+ > #include <sys/param.h> > #include <sys/systm.h> > #include <sys/kernel.h> >@@ -297,6 +299,12 @@ > vm->vm_taddr = 0; > vm->vm_daddr = 0; > vm->vm_maxsaddr = 0; >+#ifdef PAX_ASLR >+ vm->vm_aslr_delta_mmap = 0; >+ vm->vm_aslr_delta_stack = 0; >+ vm->vm_aslr_delta_exec = 0; >+#endif >+ > return (vm); > } > >@@ -3260,6 +3268,11 @@ > vm2->vm_taddr = vm1->vm_taddr; > vm2->vm_daddr = vm1->vm_daddr; > vm2->vm_maxsaddr = vm1->vm_maxsaddr; >+#ifdef PAX_ASLR >+ vm2->vm_aslr_delta_exec = vm1->vm_aslr_delta_exec; >+ vm2->vm_aslr_delta_mmap = vm1->vm_aslr_delta_mmap; >+ vm2->vm_aslr_delta_stack = vm1->vm_aslr_delta_stack; >+#endif > vm_map_lock(old_map); > if (old_map->busy) > vm_map_wait_busy(old_map); >Index: sys/vm/vm_mmap.c >=================================================================== >--- sys/vm/vm_mmap.c >+++ sys/vm/vm_mmap.c >@@ -45,6 +45,7 @@ > > #include "opt_compat.h" > #include "opt_hwpmc_hooks.h" >+#include "opt_pax.h" > > #include <sys/param.h> > #include <sys/systm.h> >@@ -54,6 +55,7 @@ > #include <sys/mutex.h> > #include <sys/sysproto.h> > #include <sys/filedesc.h> >+#include <sys/pax.h> > #include <sys/priv.h> > #include <sys/proc.h> > #include <sys/procctl.h> >@@ -439,6 +441,9 @@ > td->td_fpop = fp; > maxprot &= cap_maxprot; > >+#ifdef PAX_ASLR >+ pax_aslr_mmap(td->td_proc, &addr, (vm_offset_t)uap->addr, flags); >+#endif > /* This relies on VM_PROT_* matching PROT_*. */ > error = vm_mmap(&vms->vm_map, &addr, size, prot, maxprot, > flags, handle_type, handle, pos);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 181497
:
136322
|
136323
|
136324
|
136325
|
136326
|
136327
|
136328
| 153731