summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/os/grow.c
diff options
context:
space:
mode:
authorRichard Lowe <richlowe@richlowe.net>2014-04-16 02:39:14 +0100
committerRichard Lowe <richlowe@richlowe.net>2016-10-15 12:02:16 -0400
commitd2a70789f056fc6c9ce3ab047b52126d80b0e3da (patch)
treebcf5eedbc5aeec80cac59ea37052e3b87108c253 /usr/src/uts/common/os/grow.c
parent8ab1c3f559468e655c4eb8acce993320403dd72b (diff)
downloadillumos-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.c47
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);