diff options
author | Richard Lowe <richlowe@richlowe.net> | 2014-04-16 02:39:14 +0100 |
---|---|---|
committer | Richard Lowe <richlowe@richlowe.net> | 2016-10-15 12:02:16 -0400 |
commit | d2a70789f056fc6c9ce3ab047b52126d80b0e3da (patch) | |
tree | bcf5eedbc5aeec80cac59ea37052e3b87108c253 /usr/src/uts/common/os/grow.c | |
parent | 8ab1c3f559468e655c4eb8acce993320403dd72b (diff) | |
download | illumos-joyent-d2a70789f056fc6c9ce3ab047b52126d80b0e3da.tar.gz |
7029 want per-process exploit mitigation features (secflags)
7030 want basic address space layout randomization (ASLR)
7031 noexec_user_stack should be a security-flag
7032 want a means to forbid mappings around NULL
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
Reviewed by: Patrick Mooney <pmooney@joyent.com>
Approved by: Dan McDonald <danmcd@omniti.com>
Diffstat (limited to 'usr/src/uts/common/os/grow.c')
-rw-r--r-- | usr/src/uts/common/os/grow.c | 47 |
1 files changed, 40 insertions, 7 deletions
diff --git a/usr/src/uts/common/os/grow.c b/usr/src/uts/common/os/grow.c index f5e92cfd94..647bca2542 100644 --- a/usr/src/uts/common/os/grow.c +++ b/usr/src/uts/common/os/grow.c @@ -62,10 +62,16 @@ int use_brk_lpg = 1; int use_stk_lpg = 1; +/* + * If set, we will not randomize mappings where the 'addr' argument is + * non-NULL and not an alignment. + */ +int aslr_respect_mmap_hint = 1; + static int brk_lpg(caddr_t nva); static int grow_lpg(caddr_t sp); -int +intptr_t brk(caddr_t nva) { int error; @@ -77,6 +83,17 @@ brk(caddr_t nva) * and p_brkpageszc. */ as_rangelock(p->p_as); + + /* + * As a special case to aid the implementation of sbrk(3C), if given a + * new brk of 0, return the current brk. We'll hide this in brk(3C). + */ + if (nva == 0) { + intptr_t base = (intptr_t)(p->p_brkbase + p->p_brksize); + as_rangeunlock(p->p_as); + return (base); + } + if (use_brk_lpg && (p->p_flag & SAUTOLPG) != 0) { error = brk_lpg(nva); } else { @@ -490,10 +507,10 @@ grow_internal(caddr_t sp, uint_t growszc) } /* - * Find address for user to map. - * If MAP_FIXED is not specified, we can pick any address we want, but we will - * first try the value in *addrp if it is non-NULL. Thus this is implementing - * a way to try and get a preferred address. + * Find address for user to map. If MAP_FIXED is not specified, we can pick + * any address we want, but we will first try the value in *addrp if it is + * non-NULL and _MAP_RANDOMIZE is not set. Thus this is implementing a way to + * try and get a preferred address. */ int choose_addr(struct as *as, caddr_t *addrp, size_t len, offset_t off, @@ -506,7 +523,8 @@ choose_addr(struct as *as, caddr_t *addrp, size_t len, offset_t off, if (flags & MAP_FIXED) { (void) as_unmap(as, *addrp, len); return (0); - } else if (basep != NULL && ((flags & MAP_ALIGN) == 0) && + } else if (basep != NULL && + ((flags & (MAP_ALIGN | _MAP_RANDOMIZE)) == 0) && !as_gap(as, len, &basep, &lenp, 0, *addrp)) { /* User supplied address was available */ *addrp = basep; @@ -587,6 +605,9 @@ zmap(struct as *as, caddr_t *addrp, size_t len, uint_t uprot, int flags, return (as_map(as, *addrp, len, segvn_create, &vn_a)); } +#define RANDOMIZABLE_MAPPING(addr, flags) (((flags & MAP_FIXED) == 0) && \ + !(((flags & MAP_ALIGN) == 0) && (addr != 0) && aslr_respect_mmap_hint)) + static int smmap_common(caddr_t *addrp, size_t len, int prot, int flags, struct file *fp, offset_t pos) @@ -612,6 +633,19 @@ smmap_common(caddr_t *addrp, size_t len, return (EINVAL); } + if ((flags & (MAP_FIXED | _MAP_RANDOMIZE)) == + (MAP_FIXED | _MAP_RANDOMIZE)) { + return (EINVAL); + } + + /* + * If it's not a fixed allocation and mmap ASLR is enabled, randomize + * it. + */ + if (RANDOMIZABLE_MAPPING(*addrp, flags) && + secflag_enabled(curproc, PROC_SEC_ASLR)) + flags |= _MAP_RANDOMIZE; + #if defined(__sparc) /* * See if this is an "old mmap call". If so, remember this @@ -630,7 +664,6 @@ smmap_common(caddr_t *addrp, size_t len, if (flags & MAP_ALIGN) { - if (flags & MAP_FIXED) return (EINVAL); |