Print this page
7029 want per-process exploit mitigation features (secflags)
7030 want basic address space layout randomization (aslr)
7031 noexec_user_stack should be a secflag
7032 want a means to forbid mappings around NULL.

@@ -50,10 +50,11 @@
 #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,10 +167,17 @@
 /* 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
+ */
+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,10 +326,24 @@
                 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.
+                 */
+                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,16 +795,5 @@
         }
         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)));
-}