diff options
author | Jerry Jelinek <jerry.jelinek@joyent.com> | 2016-10-17 13:02:40 +0000 |
---|---|---|
committer | Jerry Jelinek <jerry.jelinek@joyent.com> | 2016-10-17 13:02:40 +0000 |
commit | 59a59b276f274cff7e883bcc3e10c162cfb3a263 (patch) | |
tree | 59b25df56be42eb7c8aae7cb02d6f1d39ec61b15 /usr/src/lib/libproc/common | |
parent | 8259b03da3b4ab815c3b6180f813fcfd57984470 (diff) | |
parent | d2a70789f056fc6c9ce3ab047b52126d80b0e3da (diff) | |
download | illumos-joyent-59a59b276f274cff7e883bcc3e10c162cfb3a263.tar.gz |
[illumos-gate merge]
commit d2a70789f056fc6c9ce3ab047b52126d80b0e3da
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
commit 8ab1c3f559468e655c4eb8acce993320403dd72b
7469 loader should use acpica provided by OS
commit a1964bdd47804c37e09db1a79c23937c9aeac165
7470 acpi build sometimes doesn't descend into SUBDIRS
commit abf99a006172ea5aab2246bda23f9d6d935bf1ad
7420 signalfd deadlock on pollwakeup
7421 panic in signalfd
Conflicts:
usr/src/cmd/sgs/libconv/common/corenote.c
usr/src/cmd/zonecfg/zonecfg.c
usr/src/cmd/zonecfg/zonecfg.h
usr/src/cmd/zonecfg/zonecfg_grammar.y
usr/src/cmd/zonecfg/zonecfg_lex.l
usr/src/head/libzonecfg.h
usr/src/lib/libzonecfg/common/libzonecfg.c
usr/src/man/man1m/zonecfg.1m
usr/src/man/man4/proc.4
usr/src/pkg/manifests/system-test-ostest.mf
usr/src/test/os-tests/tests/Makefile
usr/src/uts/common/exec/elf/elf.c
usr/src/uts/common/io/signalfd.c
usr/src/uts/common/os/sysent.c
usr/src/uts/common/os/zone.c
usr/src/uts/common/sys/proc.h
usr/src/uts/common/sys/zone.h
Diffstat (limited to 'usr/src/lib/libproc/common')
-rw-r--r-- | usr/src/lib/libproc/common/Pcontrol.c | 75 | ||||
-rw-r--r-- | usr/src/lib/libproc/common/Pcontrol.h | 2 | ||||
-rw-r--r-- | usr/src/lib/libproc/common/Pcore.c | 51 | ||||
-rw-r--r-- | usr/src/lib/libproc/common/Pgcore.c | 17 | ||||
-rw-r--r-- | usr/src/lib/libproc/common/Pidle.c | 1 | ||||
-rw-r--r-- | usr/src/lib/libproc/common/Putil.c | 3 | ||||
-rw-r--r-- | usr/src/lib/libproc/common/libproc.h | 6 | ||||
-rw-r--r-- | usr/src/lib/libproc/common/mapfile-vers | 3 | ||||
-rw-r--r-- | usr/src/lib/libproc/common/proc_get_info.c | 22 |
9 files changed, 158 insertions, 22 deletions
diff --git a/usr/src/lib/libproc/common/Pcontrol.c b/usr/src/lib/libproc/common/Pcontrol.c index f9b1d9755b..f18d4cefd8 100644 --- a/usr/src/lib/libproc/common/Pcontrol.c +++ b/usr/src/lib/libproc/common/Pcontrol.c @@ -54,6 +54,7 @@ #include <sys/syscall.h> #include <sys/sysmacros.h> #include <sys/systeminfo.h> +#include <sys/secflags.h> #include "libproc.h" #include "Pcontrol.h" @@ -176,6 +177,13 @@ Pcred_live(struct ps_prochandle *P, prcred_t *pcrp, int ngroups, void *data) return (proc_get_cred(P->pid, pcrp, ngroups)); } +/* ARGSUSED */ +static int +Psecflags_live(struct ps_prochandle *P, prsecflags_t **psf, void *data) +{ + return (proc_get_secflags(P->pid, psf)); +} + /*ARGSUSED*/ static int Ppriv_live(struct ps_prochandle *P, prpriv_t **pprv, void *data) @@ -326,6 +334,7 @@ static const ps_ops_t P_live_ops = { .pop_uname = Puname_live, .pop_zonename = Pzonename_live, .pop_execname = Pexecname_live, + .pop_secflags = Psecflags_live, #if defined(__i386) || defined(__amd64) .pop_ldt = Pldt_live #endif @@ -424,11 +433,11 @@ dupfd(int fd, int dfd) */ struct ps_prochandle * Pxcreate(const char *file, /* executable file name */ - char *const *argv, /* argument vector */ - char *const *envp, /* environment */ - int *perr, /* pointer to error return code */ - char *path, /* if non-null, holds exec path name on return */ - size_t len) /* size of the path buffer */ + char *const *argv, /* argument vector */ + char *const *envp, /* environment */ + int *perr, /* pointer to error return code */ + char *path, /* if non-null, holds exec path name on return */ + size_t len) /* size of the path buffer */ { char execpath[PATH_MAX]; char procname[PATH_MAX]; @@ -1299,6 +1308,28 @@ Pcred(struct ps_prochandle *P, prcred_t *pcrp, int ngroups) return (P->ops.pop_cred(P, pcrp, ngroups, P->data)); } +/* Return an allocated prsecflags_t */ +int +Psecflags(struct ps_prochandle *P, prsecflags_t **psf) +{ + int ret; + + if ((ret = P->ops.pop_secflags(P, psf, P->data)) == 0) { + if ((*psf)->pr_version != PRSECFLAGS_VERSION_1) { + errno = EINVAL; + return (-1); + } + } + + return (ret); +} + +void +Psecflags_free(prsecflags_t *psf) +{ + free(psf); +} + static prheader_t * Plstatus(struct ps_prochandle *P) { @@ -1804,8 +1835,8 @@ prdump(struct ps_prochandle *P) */ int Pstopstatus(struct ps_prochandle *P, - long request, /* PCNULL, PCDSTOP, PCSTOP, PCWSTOP */ - uint_t msec) /* if non-zero, timeout in milliseconds */ + long request, /* PCNULL, PCDSTOP, PCSTOP, PCWSTOP */ + uint_t msec) /* if non-zero, timeout in milliseconds */ { int ctlfd = (P->agentctlfd >= 0)? P->agentctlfd : P->ctlfd; long ctl[3]; @@ -2070,8 +2101,8 @@ Pputareg(struct ps_prochandle *P, int regno, prgreg_t reg) int Psetrun(struct ps_prochandle *P, - int sig, /* signal to pass to process */ - int flags) /* PRSTEP|PRSABORT|PRSTOP|PRCSIG|PRCFAULT */ + int sig, /* signal to pass to process */ + int flags) /* PRSTEP|PRSABORT|PRSTOP|PRCSIG|PRCFAULT */ { int ctlfd = (P->agentctlfd >= 0) ? P->agentctlfd : P->ctlfd; int sbits = (PR_DSTOP | PR_ISTOP | PR_ASLEEP); @@ -2146,18 +2177,18 @@ Psetrun(struct ps_prochandle *P, ssize_t Pread(struct ps_prochandle *P, - void *buf, /* caller's buffer */ - size_t nbyte, /* number of bytes to read */ - uintptr_t address) /* address in process */ + void *buf, /* caller's buffer */ + size_t nbyte, /* number of bytes to read */ + uintptr_t address) /* address in process */ { return (P->ops.pop_pread(P, buf, nbyte, address, P->data)); } ssize_t Pread_string(struct ps_prochandle *P, - char *buf, /* caller's buffer */ - size_t size, /* upper limit on bytes to read */ - uintptr_t addr) /* address in process */ + char *buf, /* caller's buffer */ + size_t size, /* upper limit on bytes to read */ + uintptr_t addr) /* address in process */ { enum { STRSZ = 40 }; char string[STRSZ + 1]; @@ -2193,9 +2224,9 @@ Pread_string(struct ps_prochandle *P, ssize_t Pwrite(struct ps_prochandle *P, - const void *buf, /* caller's buffer */ - size_t nbyte, /* number of bytes to write */ - uintptr_t address) /* address in process */ + const void *buf, /* caller's buffer */ + size_t nbyte, /* number of bytes to write */ + uintptr_t address) /* address in process */ { return (P->ops.pop_pwrite(P, buf, nbyte, address, P->data)); } @@ -3402,8 +3433,8 @@ Lsync(struct ps_lwphandle *L) */ static int Lstopstatus(struct ps_lwphandle *L, - long request, /* PCNULL, PCDSTOP, PCSTOP, PCWSTOP */ - uint_t msec) /* if non-zero, timeout in milliseconds */ + long request, /* PCNULL, PCDSTOP, PCSTOP, PCWSTOP */ + uint_t msec) /* if non-zero, timeout in milliseconds */ { int ctlfd = L->lwp_ctlfd; long ctl[3]; @@ -3603,8 +3634,8 @@ Lputareg(struct ps_lwphandle *L, int regno, prgreg_t reg) int Lsetrun(struct ps_lwphandle *L, - int sig, /* signal to pass to LWP */ - int flags) /* PRSTEP|PRSABORT|PRSTOP|PRCSIG|PRCFAULT */ + int sig, /* signal to pass to LWP */ + int flags) /* PRSTEP|PRSABORT|PRSTOP|PRCSIG|PRCFAULT */ { int ctlfd = L->lwp_ctlfd; int sbits = (PR_DSTOP | PR_ISTOP | PR_ASLEEP); diff --git a/usr/src/lib/libproc/common/Pcontrol.h b/usr/src/lib/libproc/common/Pcontrol.h index 5840409651..7e19e8777c 100644 --- a/usr/src/lib/libproc/common/Pcontrol.h +++ b/usr/src/lib/libproc/common/Pcontrol.h @@ -45,6 +45,7 @@ #include <libctf.h> #include <limits.h> #include <libproc.h> +#include <sys/secflags.h> #ifdef __cplusplus extern "C" { @@ -167,6 +168,7 @@ typedef struct core_info { /* information specific to core files */ void *core_privinfo; /* system privileges info from core file */ priv_impl_info_t *core_ppii; /* NOTE entry for core_privinfo */ char *core_zonename; /* zone name from core file */ + prsecflags_t *core_secflags; /* secflags from core file */ #if defined(__i386) || defined(__amd64) struct ssd *core_ldt; /* LDT entries from core file */ uint_t core_nldt; /* number of LDT entries in core file */ diff --git a/usr/src/lib/libproc/common/Pcore.c b/usr/src/lib/libproc/common/Pcore.c index dfa4cc6600..89c5ce47fa 100644 --- a/usr/src/lib/libproc/common/Pcore.c +++ b/usr/src/lib/libproc/common/Pcore.c @@ -159,6 +159,25 @@ Pcred_core(struct ps_prochandle *P, prcred_t *pcrp, int ngroups, void *data) /*ARGSUSED*/ static int +Psecflags_core(struct ps_prochandle *P, prsecflags_t **psf, void *data) +{ + core_info_t *core = data; + + if (core->core_secflags == NULL) { + errno = ENODATA; + return (-1); + } + + if ((*psf = calloc(1, sizeof (prsecflags_t))) == NULL) + return (-1); + + (void) memcpy(*psf, core->core_secflags, sizeof (prsecflags_t)); + + return (0); +} + +/*ARGSUSED*/ +static int Ppriv_core(struct ps_prochandle *P, prpriv_t **pprv, void *data) { core_info_t *core = data; @@ -222,6 +241,8 @@ Pfini_core(struct ps_prochandle *P, void *data) free(core->core_ppii); if (core->core_zonename != NULL) free(core->core_zonename); + if (core->core_secflags != NULL) + free(core->core_secflags); #ifdef __x86 if (core->core_ldt != NULL) free(core->core_ldt); @@ -308,6 +329,7 @@ static const ps_ops_t P_core_ops = { .pop_platform = Pplatform_core, .pop_uname = Puname_core, .pop_zonename = Pzonename_core, + .pop_secflags = Psecflags_core, #ifdef __x86 .pop_ldt = Pldt_core #endif @@ -746,6 +768,34 @@ note_platform(struct ps_prochandle *P, size_t nbytes) } static int +note_secflags(struct ps_prochandle *P, size_t nbytes) +{ + core_info_t *core = P->data; + prsecflags_t *psf; + + if (core->core_secflags != NULL) + return (0); /* Already seen */ + + if (sizeof (*psf) != nbytes) { + dprintf("Pgrab_core: NT_SECFLAGS changed size." + " Need to handle a version change?\n"); + return (-1); + } + + if (nbytes != 0 && ((psf = malloc(nbytes)) != NULL)) { + if (read(P->asfd, psf, nbytes) != nbytes) { + dprintf("Pgrab_core: failed to read NT_SECFLAGS\n"); + free(psf); + return (-1); + } + + core->core_secflags = psf; + } + + return (0); +} + +static int note_utsname(struct ps_prochandle *P, size_t nbytes) { core_info_t *core = P->data; @@ -1180,6 +1230,7 @@ static int (*nhdlrs[])(struct ps_prochandle *, size_t) = { note_zonename, /* 21 NT_ZONENAME */ note_fdinfo, /* 22 NT_FDINFO */ note_spymaster, /* 23 NT_SPYMASTER */ + note_secflags, /* 24 NT_SECFLAGS */ }; static void diff --git a/usr/src/lib/libproc/common/Pgcore.c b/usr/src/lib/libproc/common/Pgcore.c index b20ce2d12a..6ddf92ad2f 100644 --- a/usr/src/lib/libproc/common/Pgcore.c +++ b/usr/src/lib/libproc/common/Pgcore.c @@ -1418,6 +1418,22 @@ Pfgcore(struct ps_prochandle *P, int fd, core_content_t content) goto err; } + + { + prsecflags_t *psf = NULL; + + if (Psecflags(P, &psf) != 0) + goto err; + + if (write_note(fd, NT_SECFLAGS, psf, + sizeof (prsecflags_t), &doff) != 0) { + Psecflags_free(psf); + goto err; + } + + Psecflags_free(psf); + } + #if defined(__i386) || defined(__amd64) /* CSTYLED */ { @@ -1501,6 +1517,7 @@ err: */ (void) ftruncate64(fd, 0); free(pgc.pgc_chunk); + return (-1); } diff --git a/usr/src/lib/libproc/common/Pidle.c b/usr/src/lib/libproc/common/Pidle.c index c69bcaf860..db00268f9b 100644 --- a/usr/src/lib/libproc/common/Pidle.c +++ b/usr/src/lib/libproc/common/Pidle.c @@ -112,6 +112,7 @@ static const ps_ops_t P_idle_ops = { .pop_pwrite = Pwrite_idle, .pop_cred = (pop_cred_t)Pidle_int, .pop_priv = Ppriv_idle, + .pop_secflags = (pop_secflags_t)Pidle_int, .pop_psinfo = (pop_psinfo_t)Pidle_voidp, .pop_platform = (pop_platform_t)Pidle_voidp, .pop_uname = (pop_uname_t)Pidle_int, diff --git a/usr/src/lib/libproc/common/Putil.c b/usr/src/lib/libproc/common/Putil.c index f6f2aa862e..e42ac08de5 100644 --- a/usr/src/lib/libproc/common/Putil.c +++ b/usr/src/lib/libproc/common/Putil.c @@ -194,6 +194,7 @@ static const ps_ops_t P_default_ops = { .pop_uname = (pop_uname_t)Pdefault_int, .pop_zonename = (pop_zonename_t)Pdefault_voidp, .pop_execname = (pop_execname_t)Pdefault_voidp, + .pop_secflags = (pop_secflags_t)Pdefault_int, #if defined(__i386) || defined(__amd64) .pop_ldt = (pop_ldt_t)Pdefault_int #endif @@ -239,6 +240,8 @@ Pinit_ops(ps_ops_t *dst, const ps_ops_t *src) dst->pop_zonename = src->pop_zonename; if (src->pop_execname != NULL) dst->pop_execname = src->pop_execname; + if (src->pop_secflags != NULL) + dst->pop_secflags = src->pop_secflags; #if defined(__i386) || defined(__amd64) if (src->pop_ldt != NULL) dst->pop_ldt = src->pop_ldt; diff --git a/usr/src/lib/libproc/common/libproc.h b/usr/src/lib/libproc/common/libproc.h index de01309025..d74c08e828 100644 --- a/usr/src/lib/libproc/common/libproc.h +++ b/usr/src/lib/libproc/common/libproc.h @@ -55,6 +55,7 @@ #include <sys/socket.h> #include <sys/utsname.h> #include <sys/corectl.h> +#include <sys/secflags.h> #if defined(__i386) || defined(__amd64) #include <sys/sysi86.h> #endif @@ -192,6 +193,7 @@ typedef void (*pop_read_aux_t)(struct ps_prochandle *, auxv_t **, int *, typedef int (*pop_cred_t)(struct ps_prochandle *, prcred_t *, int, void *); typedef int (*pop_priv_t)(struct ps_prochandle *, prpriv_t **, void *); +typedef int (*pop_secflags_t)(struct ps_prochandle *, prsecflags_t **, void *); typedef const psinfo_t *(*pop_psinfo_t)(struct ps_prochandle *, psinfo_t *, void *); typedef void (*pop_status_t)(struct ps_prochandle *, pstatus_t *, void *); @@ -222,6 +224,7 @@ typedef struct ps_ops { pop_uname_t pop_uname; pop_zonename_t pop_zonename; pop_execname_t pop_execname; + pop_secflags_t pop_secflags; #if defined(__i386) || defined(__amd64) pop_ldt_t pop_ldt; #endif @@ -270,6 +273,8 @@ extern int Psetzoneid(struct ps_prochandle *, zoneid_t); extern int Pgetareg(struct ps_prochandle *, int, prgreg_t *); extern int Pputareg(struct ps_prochandle *, int, prgreg_t); extern int Psetrun(struct ps_prochandle *, int, int); +extern int Psecflags(struct ps_prochandle *, prsecflags_t **); +extern void Psecflags_free(prsecflags_t *); extern ssize_t Pread(struct ps_prochandle *, void *, size_t, uintptr_t); extern ssize_t Pread_string(struct ps_prochandle *, char *, size_t, uintptr_t); extern ssize_t Pwrite(struct ps_prochandle *, const void *, size_t, uintptr_t); @@ -696,6 +701,7 @@ extern prpriv_t *proc_get_priv(pid_t); extern void proc_free_priv(prpriv_t *); extern int proc_get_psinfo(pid_t, psinfo_t *); extern int proc_get_status(pid_t, pstatus_t *); +extern int proc_get_secflags(pid_t, prsecflags_t **); /* * Utility functions for debugging tools to convert numeric fault, diff --git a/usr/src/lib/libproc/common/mapfile-vers b/usr/src/lib/libproc/common/mapfile-vers index a79e9d74a2..b3f9df9d97 100644 --- a/usr/src/lib/libproc/common/mapfile-vers +++ b/usr/src/lib/libproc/common/mapfile-vers @@ -212,6 +212,7 @@ SYMBOL_VERSION SUNWprivate_1.1 { proc_get_cred; proc_get_priv; proc_get_psinfo; + proc_get_secflags; proc_get_status; proc_initstdio; proc_lwp_in_set; @@ -278,6 +279,8 @@ SYMBOL_VERSION SUNWprivate_1.1 { ps_ptread { FLAGS = NODYNSORT }; # Alias of ps_pread ps_ptwrite { FLAGS = NODYNSORT }; # Alias of ps_pwrite ps_pwrite; + Psecflags; + Psecflags_free; Pstack_iter; Pstate; Pstatus; diff --git a/usr/src/lib/libproc/common/proc_get_info.c b/usr/src/lib/libproc/common/proc_get_info.c index e0817c543f..19a84e060e 100644 --- a/usr/src/lib/libproc/common/proc_get_info.c +++ b/usr/src/lib/libproc/common/proc_get_info.c @@ -32,6 +32,7 @@ #include <fcntl.h> #include <string.h> #include <limits.h> +#include <sys/secflags.h> #include "Pcontrol.h" @@ -68,6 +69,27 @@ proc_get_cred(pid_t pid, prcred_t *credp, int ngroups) return (rv); } +int +proc_get_secflags(pid_t pid, prsecflags_t **psf) +{ + char fname[PATH_MAX]; + int fd; + int rv = -1; + + if ((*psf = calloc(1, sizeof (prsecflags_t))) == NULL) + return (-1); + + (void) snprintf(fname, sizeof (fname), "%s/%d/secflags", + procfs_path, (int)pid); + if ((fd = open(fname, O_RDONLY)) >= 0) { + if (read(fd, *psf, sizeof (prsecflags_t)) == + sizeof (prsecflags_t)) + rv = 0; + (void) close(fd); + } + return (rv); +} + void proc_free_priv(prpriv_t *prv) { |