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

*** 57,66 **** --- 57,67 ---- #include <sys/exechdr.h> #include <sys/debug.h> #include <sys/vmsystm.h> #include <sys/swap.h> #include <sys/dumphdr.h> + #include <sys/random.h> #include <vm/hat.h> #include <vm/as.h> #include <vm/seg.h> #include <vm/seg_kp.h>
*** 635,644 **** --- 636,652 ---- { return (0); } /* + * 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 the highest available below userlimit. * * Every mapping will have a redzone of a single page on either side of
*** 750,759 **** --- 758,768 ---- ASSERT(ISP2(align_amount)); ASSERT(align_amount == 0 || align_amount >= PAGESIZE); off = off & (align_amount - 1); + /* * Look for a large enough hole starting below userlimit. * After finding it, use the upper part. */ if (as_gap_aligned(as, len, &base, &slen, AH_HI, NULL, align_amount,
*** 777,786 **** --- 786,812 ---- addr += (uintptr_t)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 - 1)) == ((uintptr_t)(off))); *addrp = addr;
*** 3924,3939 **** */ void dcache_flushall() {} - size_t - exec_get_spslew(void) - { - return (0); - } - /* * Allocate a memory page. The argument 'seed' can be any pseudo-random * number to vary where the pages come from. This is quite a hacked up * method -- it works for now, but really needs to be fixed up a bit. * --- 3950,3959 ----