summaryrefslogtreecommitdiff
path: root/usr/src/lib/libproc/common
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libproc/common')
-rw-r--r--usr/src/lib/libproc/common/Pcontrol.c75
-rw-r--r--usr/src/lib/libproc/common/Pcontrol.h2
-rw-r--r--usr/src/lib/libproc/common/Pcore.c51
-rw-r--r--usr/src/lib/libproc/common/Pgcore.c17
-rw-r--r--usr/src/lib/libproc/common/Pidle.c1
-rw-r--r--usr/src/lib/libproc/common/Putil.c3
-rw-r--r--usr/src/lib/libproc/common/libproc.h6
-rw-r--r--usr/src/lib/libproc/common/mapfile-vers3
-rw-r--r--usr/src/lib/libproc/common/proc_get_info.c22
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)
{