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/syscall/psecflags.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/syscall/psecflags.c')
| -rw-r--r-- | usr/src/uts/common/syscall/psecflags.c | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/usr/src/uts/common/syscall/psecflags.c b/usr/src/uts/common/syscall/psecflags.c new file mode 100644 index 0000000000..08d923e76b --- /dev/null +++ b/usr/src/uts/common/syscall/psecflags.c @@ -0,0 +1,121 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* Copyright 2015, Richard Lowe. */ + +#include <sys/ddi.h> +#include <sys/errno.h> +#include <sys/policy.h> +#include <sys/proc.h> +#include <sys/procset.h> +#include <sys/systm.h> +#include <sys/types.h> +#include <c2/audit.h> + +struct psdargs { + psecflagwhich_t which; + const secflagdelta_t *delta; +}; + +void +secflags_apply_delta(secflagset_t *set, const secflagdelta_t *delta) +{ + if (delta->psd_ass_active) { + secflags_copy(set, &delta->psd_assign); + } else { + if (!secflags_isempty(delta->psd_add)) { + secflags_union(set, &delta->psd_add); + } + if (!secflags_isempty(delta->psd_rem)) { + secflags_difference(set, &delta->psd_rem); + } + } +} + + +static int +psecdo(proc_t *p, struct psdargs *args) +{ + secflagset_t *set; + int ret = 0; + + mutex_enter(&p->p_lock); + + if (secpolicy_psecflags(CRED(), p, curproc) != 0) { + ret = EPERM; + goto out; + } + + ASSERT(args->which != PSF_EFFECTIVE); + + if (!psecflags_validate_delta(&p->p_secflags, args->delta)) { + ret = EINVAL; + goto out; + } + + if (AU_AUDITING()) + audit_psecflags(p, args->which, args->delta); + + switch (args->which) { + case PSF_INHERIT: + set = &p->p_secflags.psf_inherit; + break; + case PSF_LOWER: + set = &p->p_secflags.psf_lower; + break; + case PSF_UPPER: + set = &p->p_secflags.psf_upper; + break; + } + + secflags_apply_delta(set, args->delta); + + /* + * Add any flag now in the lower that is not in the inheritable. + */ + secflags_union(&p->p_secflags.psf_inherit, &p->p_secflags.psf_lower); + +out: + mutex_exit(&p->p_lock); + return (ret); +} + +int +psecflags(procset_t *psp, psecflagwhich_t which, secflagdelta_t *ap) +{ + procset_t procset; + secflagdelta_t args; + int rv = 0; + struct psdargs psd = { + .which = which, + }; + + /* Can never change the effective flags */ + if (psd.which == PSF_EFFECTIVE) + return (EINVAL); + + if (copyin(psp, &procset, sizeof (procset)) != 0) + return (set_errno(EFAULT)); + + if (copyin(ap, &args, sizeof (secflagdelta_t)) != 0) + return (set_errno(EFAULT)); + + psd.delta = &args; + + /* secflags are per-process, procset must be in terms of processes */ + if ((procset.p_lidtype == P_LWPID) || + (procset.p_ridtype == P_LWPID)) + return (set_errno(EINVAL)); + + rv = dotoprocs(&procset, psecdo, (caddr_t)&psd); + + return (rv ? set_errno(rv) : 0); +} |
