Print this page
*** 19,29 ****
* CDDL HEADER END
*/
/*
* Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
! * Copyright (c) 2018, Joyent, Inc.
* Copyright (c) 2017 by Delphix. All rights reserved.
* Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
* Copyright 2022 MNX Cloud, Inc.
* Copyright 2023 Oxide Computer Company
*/
--- 19,29 ----
* CDDL HEADER END
*/
/*
* Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
! * Copyright 2019 Joyent, Inc.
* Copyright (c) 2017 by Delphix. All rights reserved.
* Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
* Copyright 2022 MNX Cloud, Inc.
* Copyright 2023 Oxide Computer Company
*/
*** 169,180 ****
"path" },
{ PR_CTDIR, 27 * sizeof (prdirent_t), sizeof (prdirent_t),
"contracts" },
{ PR_SECFLAGS, 28 * sizeof (prdirent_t), sizeof (prdirent_t),
"secflags" },
#if defined(__x86)
! { PR_LDT, 29 * sizeof (prdirent_t), sizeof (prdirent_t),
"ldt" },
#endif
};
#define NPIDDIRFILES (sizeof (piddir) / sizeof (piddir[0]) - 2)
--- 169,184 ----
"path" },
{ PR_CTDIR, 27 * sizeof (prdirent_t), sizeof (prdirent_t),
"contracts" },
{ PR_SECFLAGS, 28 * sizeof (prdirent_t), sizeof (prdirent_t),
"secflags" },
+ { PR_ARGV, 29 * sizeof (prdirent_t), sizeof (prdirent_t),
+ "argv" },
+ { PR_CMDLINE, 30 * sizeof (prdirent_t), sizeof (prdirent_t),
+ "cmdline" },
#if defined(__x86)
! { PR_LDT, 31 * sizeof (prdirent_t), sizeof (prdirent_t),
"ldt" },
#endif
};
#define NPIDDIRFILES (sizeof (piddir) / sizeof (piddir[0]) - 2)
*** 591,600 ****
--- 595,605 ----
pr_read_map(), pr_read_rmap(), pr_read_xmap(),
pr_read_cred(), pr_read_sigact(), pr_read_auxv(),
#if defined(__x86)
pr_read_ldt(),
#endif
+ pr_read_argv(), pr_read_cmdline(),
pr_read_usage(), pr_read_lusage(), pr_read_pagedata(),
pr_read_watch(), pr_read_lwpstatus(), pr_read_lwpsinfo(),
pr_read_lwpusage(), pr_read_lwpname(),
pr_read_xregs(), pr_read_priv(),
pr_read_spymaster(), pr_read_secflags(),
*** 621,630 ****
--- 626,637 ----
pr_read_sigact, /* /proc/<pid>/sigact */
pr_read_auxv, /* /proc/<pid>/auxv */
#if defined(__x86)
pr_read_ldt, /* /proc/<pid>/ldt */
#endif
+ pr_read_argv, /* /proc/<pid>/argv */
+ pr_read_cmdline, /* /proc/<pid>/cmdline */
pr_read_usage, /* /proc/<pid>/usage */
pr_read_lusage, /* /proc/<pid>/lusage */
pr_read_pagedata, /* /proc/<pid>/pagedata */
pr_read_watch, /* /proc/<pid>/watch */
pr_read_inval, /* /proc/<pid>/cwd */
*** 687,696 ****
--- 694,773 ----
return (error);
}
static int
+ pr_read_cmdline(prnode_t *pnp, uio_t *uiop)
+ {
+ char *args;
+ int error;
+ size_t asz = PRMAXARGVLEN, sz;
+
+ /*
+ * Allocate a scratch buffer for collection of the process arguments.
+ */
+ args = kmem_alloc(asz, KM_SLEEP);
+
+ ASSERT(pnp->pr_type == PR_CMDLINE);
+
+ if ((error = prlock(pnp, ZNO)) != 0) {
+ kmem_free(args, asz);
+ return (error);
+ }
+
+ if ((error = prreadcmdline(pnp->pr_common->prc_proc, args, asz,
+ &sz)) != 0) {
+ prunlock(pnp);
+ kmem_free(args, asz);
+ return (error);
+ }
+
+ prunlock(pnp);
+
+ error = pr_uioread(args, sz, uiop);
+
+ kmem_free(args, asz);
+
+ return (error);
+ }
+
+ static int
+ pr_read_argv(prnode_t *pnp, uio_t *uiop)
+ {
+ char *args;
+ int error;
+ size_t asz = PRMAXARGVLEN, sz;
+
+ /*
+ * Allocate a scratch buffer for collection of the process arguments.
+ */
+ args = kmem_alloc(asz, KM_SLEEP);
+
+ ASSERT(pnp->pr_type == PR_ARGV);
+
+ if ((error = prlock(pnp, ZNO)) != 0) {
+ kmem_free(args, asz);
+ return (error);
+ }
+
+ if ((error = prreadargv(pnp->pr_common->prc_proc, args, asz,
+ &sz)) != 0) {
+ prunlock(pnp);
+ kmem_free(args, asz);
+ return (error);
+ }
+
+ prunlock(pnp);
+
+ error = pr_uioread(args, sz, uiop);
+
+ kmem_free(args, asz);
+
+ return (error);
+ }
+
+ static int
pr_read_as(prnode_t *pnp, uio_t *uiop)
{
int error;
ASSERT(pnp->pr_type == PR_AS);
*** 1928,1937 ****
--- 2005,2016 ----
pr_read_sigact_32, /* /proc/<pid>/sigact */
pr_read_auxv_32, /* /proc/<pid>/auxv */
#if defined(__x86)
pr_read_ldt, /* /proc/<pid>/ldt */
#endif
+ pr_read_argv, /* /proc/<pid>/argv */
+ pr_read_cmdline, /* /proc/<pid>/cmdline */
pr_read_usage_32, /* /proc/<pid>/usage */
pr_read_lusage_32, /* /proc/<pid>/lusage */
pr_read_pagedata_32, /* /proc/<pid>/pagedata */
pr_read_watch_32, /* /proc/<pid>/watch */
pr_read_inval, /* /proc/<pid>/cwd */
*** 2856,2865 ****
--- 2935,3041 ----
#else
return (pr_read_function[pnp->pr_type](pnp, uiop, cr));
#endif
}
+ /*
+ * We make pr_write_psinfo_fname() somewhat simpler by asserting at compile
+ * time that PRFNSZ has the same definition as MAXCOMLEN.
+ */
+ #if PRFNSZ != MAXCOMLEN
+ #error PRFNSZ/MAXCOMLEN mismatch
+ #endif
+
+ static int
+ pr_write_psinfo_fname(prnode_t *pnp, uio_t *uiop)
+ {
+ char fname[PRFNSZ];
+ int offset = offsetof(psinfo_t, pr_fname), error;
+
+ #ifdef _SYSCALL32_IMPL
+ if (curproc->p_model != DATAMODEL_LP64)
+ offset = offsetof(psinfo32_t, pr_fname);
+ #endif
+
+ /*
+ * If this isn't a write to pr_fname (or if the size doesn't match
+ * PRFNSZ) return.
+ */
+ if (uiop->uio_offset != offset || uiop->uio_resid != PRFNSZ)
+ return (0);
+
+ if ((error = uiomove(fname, PRFNSZ, UIO_WRITE, uiop)) != 0)
+ return (error);
+
+ fname[PRFNSZ - 1] = '\0';
+
+ if ((error = prlock(pnp, ZNO)) != 0)
+ return (error);
+
+ bcopy(fname, pnp->pr_common->prc_proc->p_user.u_comm, PRFNSZ);
+
+ prunlock(pnp);
+
+ return (0);
+ }
+
+ /*
+ * We make pr_write_psinfo_psargs() somewhat simpler by asserting at compile
+ * time that PRARGSZ has the same definition as PSARGSZ.
+ */
+ #if PRARGSZ != PSARGSZ
+ #error PRARGSZ/PSARGSZ mismatch
+ #endif
+
+ static int
+ pr_write_psinfo_psargs(prnode_t *pnp, uio_t *uiop)
+ {
+ char psargs[PRARGSZ];
+ int offset = offsetof(psinfo_t, pr_psargs), error;
+
+ #ifdef _SYSCALL32_IMPL
+ if (curproc->p_model != DATAMODEL_LP64)
+ offset = offsetof(psinfo32_t, pr_psargs);
+ #endif
+
+ /*
+ * If this isn't a write to pr_psargs (or if the size doesn't match
+ * PRARGSZ) return.
+ */
+ if (uiop->uio_offset != offset || uiop->uio_resid != PRARGSZ)
+ return (0);
+
+ if ((error = uiomove(psargs, PRARGSZ, UIO_WRITE, uiop)) != 0)
+ return (error);
+
+ psargs[PRARGSZ - 1] = '\0';
+
+ if ((error = prlock(pnp, ZNO)) != 0)
+ return (error);
+
+ bcopy(psargs, pnp->pr_common->prc_proc->p_user.u_psargs, PRARGSZ);
+
+ prunlock(pnp);
+
+ return (0);
+ }
+
+ int
+ pr_write_psinfo(prnode_t *pnp, uio_t *uiop)
+ {
+ int error;
+
+ if ((error = pr_write_psinfo_fname(pnp, uiop)) != 0)
+ return (error);
+
+ if ((error = pr_write_psinfo_psargs(pnp, uiop)) != 0)
+ return (error);
+
+ return (0);
+ }
+
+
/* Note we intentionally don't handle partial writes/updates. */
static int
pr_write_lwpname(prnode_t *pnp, uio_t *uiop)
{
kthread_t *t = NULL;
*** 2982,2991 ****
--- 3158,3170 ----
*/
if (error == EINTR)
uiop->uio_resid = resid;
return (error);
+ case PR_PSINFO:
+ return (pr_write_psinfo(pnp, uiop));
+
case PR_LWPNAME:
return (pr_write_lwpname(pnp, uiop));
default:
return ((vp->v_type == VDIR)? EISDIR : EBADF);
*** 3311,3320 ****
--- 3490,3506 ----
PR_OBJSIZE(struct sigaction32, struct sigaction);
break;
case PR_AUXV:
vap->va_size = __KERN_NAUXV_IMPL * PR_OBJSIZE(auxv32_t, auxv_t);
break;
+ case PR_ARGV:
+ if ((p->p_flag & SSYS) || p->p_as == &kas) {
+ vap->va_size = PSARGSZ;
+ } else {
+ vap->va_size = PRMAXARGVLEN;
+ }
+ break;
#if defined(__x86)
case PR_LDT:
mutex_exit(&p->p_lock);
mutex_enter(&p->p_ldtlock);
vap->va_size = prnldt(p) * sizeof (struct ssd);
*** 3433,3442 ****
--- 3619,3629 ----
vap->va_size = 0;
break;
#endif
case PR_CTL:
case PR_LWPCTL:
+ case PR_CMDLINE:
default:
vap->va_size = 0;
break;
}
*** 3487,3496 ****
--- 3674,3685 ----
case PR_LWPDIR:
case PR_LWPIDDIR:
case PR_USAGE:
case PR_LUSAGE:
case PR_LWPUSAGE:
+ case PR_ARGV:
+ case PR_CMDLINE:
p = pr_p_lock(pnp);
mutex_exit(&pr_pidlock);
if (p == NULL)
return (ENOENT);
prunlock(pnp);
*** 3572,3581 ****
--- 3761,3772 ----
pr_lookup_notdir, /* /proc/<pid>/sigact */
pr_lookup_notdir, /* /proc/<pid>/auxv */
#if defined(__x86)
pr_lookup_notdir, /* /proc/<pid>/ldt */
#endif
+ pr_lookup_notdir, /* /proc/<pid>/argv */
+ pr_lookup_notdir, /* /proc/<pid>/cmdline */
pr_lookup_notdir, /* /proc/<pid>/usage */
pr_lookup_notdir, /* /proc/<pid>/lusage */
pr_lookup_notdir, /* /proc/<pid>/pagedata */
pr_lookup_notdir, /* /proc/<pid>/watch */
pr_lookup_notdir, /* /proc/<pid>/cwd */
*** 4902,4921 ****
case PR_PIDFILE:
case PR_LWPIDFILE:
pnp->pr_mode = 0600; /* read-write by owner only */
break;
case PR_LWPNAME:
pnp->pr_mode = 0644; /* readable by all + owner can write */
break;
- case PR_PSINFO:
case PR_LPSINFO:
case PR_LWPSINFO:
case PR_USAGE:
case PR_LUSAGE:
case PR_LWPUSAGE:
pnp->pr_mode = 0444; /* read-only by all */
break;
default:
pnp->pr_mode = 0400; /* read-only by owner only */
--- 5093,5114 ----
case PR_PIDFILE:
case PR_LWPIDFILE:
pnp->pr_mode = 0600; /* read-write by owner only */
break;
+ case PR_PSINFO:
case PR_LWPNAME:
pnp->pr_mode = 0644; /* readable by all + owner can write */
break;
case PR_LPSINFO:
case PR_LWPSINFO:
case PR_USAGE:
case PR_LUSAGE:
case PR_LWPUSAGE:
+ case PR_ARGV:
+ case PR_CMDLINE:
pnp->pr_mode = 0444; /* read-only by all */
break;
default:
pnp->pr_mode = 0400; /* read-only by owner only */
*** 5019,5028 ****
--- 5212,5223 ----
pr_readdir_notdir, /* /proc/<pid>/sigact */
pr_readdir_notdir, /* /proc/<pid>/auxv */
#if defined(__x86)
pr_readdir_notdir, /* /proc/<pid>/ldt */
#endif
+ pr_readdir_notdir, /* /proc/<pid>/argv */
+ pr_readdir_notdir, /* /proc/<pid>/cmdline */
pr_readdir_notdir, /* /proc/<pid>/usage */
pr_readdir_notdir, /* /proc/<pid>/lusage */
pr_readdir_notdir, /* /proc/<pid>/pagedata */
pr_readdir_notdir, /* /proc/<pid>/watch */
pr_readdir_notdir, /* /proc/<pid>/cwd */
*** 5172,5181 ****
--- 5367,5378 ----
switch (dirp->d_ino) {
case PR_PIDDIR:
case PR_PROCDIR:
case PR_PSINFO:
case PR_USAGE:
+ case PR_ARGV:
+ case PR_CMDLINE:
break;
default:
continue;
}
}