diff options
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) { |