freebsd-skq/sys/vm
kib 08849e56ba Implement Address Space Layout Randomization (ASLR)
With this change, randomization can be enabled for all non-fixed
mappings.  It means that the base address for the mapping is selected
with a guaranteed amount of entropy (bits). If the mapping was
requested to be superpage aligned, the randomization honours the
superpage attributes.

Although the value of ASLR is diminshing over time as exploit authors
work out simple ASLR bypass techniques, it elimintates the trivial
exploitation of certain vulnerabilities, at least in theory.  This
implementation is relatively small and happens at the correct
architectural level.  Also, it is not expected to introduce
regressions in existing cases when turned off (default for now), or
cause any significant maintaince burden.

The randomization is done on a best-effort basis - that is, the
allocator falls back to a first fit strategy if fragmentation prevents
entropy injection.  It is trivial to implement a strong mode where
failure to guarantee the requested amount of entropy results in
mapping request failure, but I do not consider that to be usable.

I have not fine-tuned the amount of entropy injected right now. It is
only a quantitive change that will not change the implementation.  The
current amount is controlled by aslr_pages_rnd.

To not spoil coalescing optimizations, to reduce the page table
fragmentation inherent to ASLR, and to keep the transient superpage
promotion for the malloced memory, locality clustering is implemented
for anonymous private mappings, which are automatically grouped until
fragmentation kicks in.  The initial location for the anon group range
is, of course, randomized.  This is controlled by vm.cluster_anon,
enabled by default.

The default mode keeps the sbrk area unpopulated by other mappings,
but this can be turned off, which gives much more breathing bits on
architectures with small address space, such as i386.  This is tied
with the question of following an application's hint about the mmap(2)
base address. Testing shows that ignoring the hint does not affect the
function of common applications, but I would expect more demanding
code could break. By default sbrk is preserved and mmap hints are
satisfied, which can be changed by using the
kern.elf{32,64}.aslr.honor_sbrk sysctl.

ASLR is enabled on per-ABI basis, and currently it is only allowed on
FreeBSD native i386 and amd64 (including compat 32bit) ABIs.  Support
for additional architectures will be added after further testing.

Both per-process and per-image controls are implemented:
- procctl(2) adds PROC_ASLR_CTL/PROC_ASLR_STATUS;
- NT_FREEBSD_FCTL_ASLR_DISABLE feature control note bit makes it possible
  to force ASLR off for the given binary.  (A tool to edit the feature
  control note is in development.)
Global controls are:
- kern.elf{32,64}.aslr.enable - for non-fixed mappings done by mmap(2);
- kern.elf{32,64}.aslr.pie_enable - for PIE image activation mappings;
- kern.elf{32,64}.aslr.honor_sbrk - allow to use sbrk area for mmap(2);
- vm.cluster_anon - enables anon mapping clustering.

PR:	208580 (exp runs)
Exp-runs done by:	antoine
Reviewed by:	markj (previous version)
Discussed with:	emaste
Tested by:	pho
MFC after:	1 month
Sponsored by:	The FreeBSD Foundation
Differential revision:	https://reviews.freebsd.org/D5603
2019-02-10 17:19:45 +00:00
..
_vm_radix.h
default_pager.c
device_pager.c Change the vm_ooffset_t type to unsigned. 2018-12-02 13:16:46 +00:00
memguard.c
memguard.h
phys_pager.c
pmap.h Add pmap_is_valid_memattr(9). 2018-08-01 18:45:51 +00:00
redzone.c
redzone.h
sg_pager.c Change the vm_ooffset_t type to unsigned. 2018-12-02 13:16:46 +00:00
swap_pager.c Allocate pager bufs from UMA instead of 80-ish mutex protected linked list. 2019-01-15 01:02:16 +00:00
swap_pager.h
uma_core.c Now that there is only one way to allocate a slab, remove uz_slab method. 2019-02-07 03:55:05 +00:00
uma_dbg.c Fix compilation failures on different arches that have vm_machdep.c not 2019-01-15 19:33:47 +00:00
uma_dbg.h
uma_int.h Now that there is only one way to allocate a slab, remove uz_slab method. 2019-02-07 03:55:05 +00:00
uma.h o Move zone limit from keg level up to zone level. This means that now 2019-01-15 00:02:06 +00:00
vm_domainset.c Add a !NUMA definition for vm_domainset_iter_policy_ref_init(). 2018-10-24 17:09:20 +00:00
vm_domainset.h Refactor domainset iterators for use by malloc(9) and UMA. 2018-10-23 16:35:58 +00:00
vm_extern.h Add malloc_domainset(9) and _domainset variants to other allocator KPIs. 2018-10-30 18:26:34 +00:00
vm_fault.c Eliminate typically pointless calls to vm_fault_prefault() on soft, copy- 2018-10-27 17:49:46 +00:00
vm_glue.c Refactor domainset iterators for use by malloc(9) and UMA. 2018-10-23 16:35:58 +00:00
vm_init.c Do not reserve KVA for paging bufs in vm_ksubmap_init(), since now 2019-01-16 20:14:16 +00:00
vm_kern.c contigmalloc: handle M_EXEC. 2019-02-07 02:00:23 +00:00
vm_kern.h Do not reserve KVA for paging bufs in vm_ksubmap_init(), since now 2019-01-16 20:14:16 +00:00
vm_map.c Implement Address Space Layout Randomization (ASLR) 2019-02-10 17:19:45 +00:00
vm_map.h Implement Address Space Layout Randomization (ASLR) 2019-02-10 17:19:45 +00:00
vm_meter.c Add a per-pagequeue pdpages counter. 2018-08-23 21:03:45 +00:00
vm_mmap.c i386: honor kern.elf32.read_exec for ommap(2) and break(2), as already 2019-02-09 03:56:48 +00:00
vm_object.c Include path for tmpfs objects in vm.objects sysctl 2018-11-30 04:59:43 +00:00
vm_object.h Change the vm_ooffset_t type to unsigned. 2018-12-02 13:16:46 +00:00
vm_page.c Allow vm_page_free_prep() to dequeue pages without the page lock. 2019-02-03 18:43:20 +00:00
vm_page.h Allow vm_page_free_prep() to dequeue pages without the page lock. 2019-02-03 18:43:20 +00:00
vm_pageout.c Initialize last_target in the laundry thread control loop. 2018-11-06 02:52:54 +00:00
vm_pageout.h linuxkpi: Use pageproc instead of vmproc 2018-11-21 04:34:18 +00:00
vm_pagequeue.h Allow empty NUMA memory domains to support Threadripper2 2018-10-01 14:14:21 +00:00
vm_pager.c Do not reserve KVA for paging bufs in vm_ksubmap_init(), since now 2019-01-16 20:14:16 +00:00
vm_pager.h
vm_param.h
vm_phys.c MI VM: Make it possible to set size of superpage at boot instead of compile time. 2019-01-18 13:35:06 +00:00
vm_phys.h MI VM: Make it possible to set size of superpage at boot instead of compile time. 2019-01-18 13:35:06 +00:00
vm_radix.c vm: stop passing M_ZERO when allocating radix nodes 2018-06-24 13:08:05 +00:00
vm_radix.h
vm_reserv.c MI VM: Make it possible to set size of superpage at boot instead of compile time. 2019-01-18 13:35:06 +00:00
vm_reserv.h
vm_swapout_dummy.c
vm_swapout.c linuxkpi: Use pageproc instead of vmproc 2018-11-21 04:34:18 +00:00
vm_unix.c i386: honor kern.elf32.read_exec for ommap(2) and break(2), as already 2019-02-09 03:56:48 +00:00
vm.h
vnode_pager.c Allocate pager bufs from UMA instead of 80-ish mutex protected linked list. 2019-01-15 01:02:16 +00:00
vnode_pager.h