Print this page
uts: Allow for address space randomisation.
Randomise the base addresses of shared objects, non-fixed mappings, the
stack and the heap. Introduce a service, svc:/system/process-security,
and a tool psecflags(1) to control and observe it
*** 50,59 ****
--- 50,60 ----
#include <sys/machsystm.h>
#include <vm/seg_kmem.h>
#include <sys/stack.h>
#include <sys/atomic.h>
#include <sys/promif.h>
+ #include <sys/random.h>
uint_t page_colors = 0;
uint_t page_colors_mask = 0;
uint_t page_coloring_shift = 0;
int consistent_coloring;
*** 166,175 ****
--- 167,183 ----
/* Boot-time allocated buffer to pre-populate the contig_mem_arena */
static size_t contig_mem_prealloc_size;
static void *contig_mem_prealloc_buf;
/*
+ * The maximum amount a randomized mapping will be slewed. We should perhaps
+ * arrange things so these tunables can be separate for mmap, mmapobj, and
+ * ld.so
+ */
+ volatile size_t aslr_max_map_skew = 256 * 1024 * 1024; /* 256MB */
+
+ /*
* map_addr_proc() is the routine called when the system is to
* choose an address for the user. We will pick an address
* range which is just below the current stack limit. The
* algorithm used for cache consistency on machines with virtual
* address caches is such that offset 0 in the vnode is always
*** 318,327 ****
--- 326,352 ----
addr += (long)off;
if (addr > as_addr) {
addr -= align_amount;
}
+ /*
+ * If randomization is requested, slew the allocation
+ * backwards, within the same gap, by a random amount.
+ *
+ * XXX: This will fall over in processes like Java, which
+ * commonly have a great many small mappings.
+ */
+ if (flags & _MAP_RANDOMIZE) {
+ uint32_t slew;
+
+ (void) random_get_pseudo_bytes((uint8_t *)&slew,
+ sizeof (slew));
+
+ slew = slew % MIN(aslr_max_map_skew, (addr - base));
+ addr -= P2ALIGN(slew, align_amount);
+ }
+
ASSERT(addr > base);
ASSERT(addr + len < base + slen);
ASSERT(((uintptr_t)addr & (align_amount - 1l)) ==
((uintptr_t)(off)));
*addrp = addr;
*** 773,788 ****
}
alloc_base += contig_mem_prealloc_size;
return (alloc_base);
}
-
- static uint_t sp_color_stride = 16;
- static uint_t sp_color_mask = 0x1f;
- static uint_t sp_current_color = (uint_t)-1;
-
- size_t
- exec_get_spslew(void)
- {
- uint_t spcolor = atomic_inc_32_nv(&sp_current_color);
- return ((size_t)((spcolor & sp_color_mask) * SA(sp_color_stride)));
- }
--- 798,802 ----