4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2017, Joyent, Inc.
25 * Copyright (c) 2017 by Delphix. All rights reserved.
26 */
27
28 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
29 /* All Rights Reserved */
30
31 #include <sys/types.h>
32 #include <sys/param.h>
33 #include <sys/time.h>
34 #include <sys/cred.h>
35 #include <sys/policy.h>
36 #include <sys/debug.h>
37 #include <sys/dirent.h>
38 #include <sys/errno.h>
39 #include <sys/file.h>
40 #include <sys/inline.h>
41 #include <sys/kmem.h>
42 #include <sys/pathname.h>
43 #include <sys/proc.h>
44 #include <sys/brand.h>
47 #include <sys/sysmacros.h>
48 #include <sys/systm.h>
49 #include <sys/zone.h>
50 #include <sys/uio.h>
51 #include <sys/var.h>
52 #include <sys/mode.h>
53 #include <sys/poll.h>
54 #include <sys/user.h>
55 #include <sys/vfs.h>
56 #include <sys/vfs_opreg.h>
57 #include <sys/gfs.h>
58 #include <sys/vnode.h>
59 #include <sys/fault.h>
60 #include <sys/syscall.h>
61 #include <sys/procfs.h>
62 #include <sys/atomic.h>
63 #include <sys/cmn_err.h>
64 #include <sys/contract_impl.h>
65 #include <sys/ctfs.h>
66 #include <sys/avl.h>
67 #include <fs/fs_subr.h>
68 #include <vm/rm.h>
69 #include <vm/as.h>
70 #include <vm/seg.h>
71 #include <vm/seg_vn.h>
72 #include <vm/hat.h>
73 #include <fs/proc/prdata.h>
74 #if defined(__sparc)
75 #include <sys/regset.h>
76 #endif
77 #if defined(__x86)
78 #include <sys/sysi86.h>
79 #endif
80
81 /*
82 * Created by prinit.
83 */
84 vnodeops_t *prvnodeops;
85
86 /*
166 { PR_SECFLAGS, 27 * sizeof (prdirent_t), sizeof (prdirent_t),
167 "secflags" },
168 #if defined(__x86)
169 { PR_LDT, 28 * sizeof (prdirent_t), sizeof (prdirent_t),
170 "ldt" },
171 #endif
172 };
173
174 #define NPIDDIRFILES (sizeof (piddir) / sizeof (piddir[0]) - 2)
175
176 /*
177 * Contents of a /proc/<pid>/lwp/<lwpid> directory.
178 */
179 static prdirent_t lwpiddir[] = {
180 { PR_LWPIDDIR, 1 * sizeof (prdirent_t), sizeof (prdirent_t),
181 "." },
182 { PR_LWPDIR, 2 * sizeof (prdirent_t), sizeof (prdirent_t),
183 ".." },
184 { PR_LWPCTL, 3 * sizeof (prdirent_t), sizeof (prdirent_t),
185 "lwpctl" },
186 { PR_LWPSTATUS, 4 * sizeof (prdirent_t), sizeof (prdirent_t),
187 "lwpstatus" },
188 { PR_LWPSINFO, 5 * sizeof (prdirent_t), sizeof (prdirent_t),
189 "lwpsinfo" },
190 { PR_LWPUSAGE, 6 * sizeof (prdirent_t), sizeof (prdirent_t),
191 "lwpusage" },
192 { PR_XREGS, 7 * sizeof (prdirent_t), sizeof (prdirent_t),
193 "xregs" },
194 { PR_TMPLDIR, 8 * sizeof (prdirent_t), sizeof (prdirent_t),
195 "templates" },
196 { PR_SPYMASTER, 9 * sizeof (prdirent_t), sizeof (prdirent_t),
197 "spymaster" },
198 #if defined(__sparc)
199 { PR_GWINDOWS, 10 * sizeof (prdirent_t), sizeof (prdirent_t),
200 "gwindows" },
201 { PR_ASRS, 11 * sizeof (prdirent_t), sizeof (prdirent_t),
202 "asrs" },
203 #endif
204 };
205
206 #define NLWPIDDIRFILES (sizeof (lwpiddir) / sizeof (lwpiddir[0]) - 2)
207
208 /*
209 * Span of entries in the array files (lstatus, lpsinfo, lusage).
210 * We make the span larger than the size of the structure on purpose,
211 * to make sure that programs cannot use the structure size by mistake.
212 * Align _ILP32 structures at 8 bytes, _LP64 structures at 16 bytes.
213 */
214 #ifdef _LP64
215 #define LSPAN(type) (round16(sizeof (type)) + 16)
216 #define LSPAN32(type) (round8(sizeof (type)) + 8)
217 #else
218 #define LSPAN(type) (round8(sizeof (type)) + 8)
219 #endif
220
221 static void rebuild_objdir(struct as *);
570 else
571 allsetrun(p);
572 }
573
574 prunlock(pnp);
575 return (0);
576 }
577
578 /*
579 * Array of read functions, indexed by /proc file type.
580 */
581 static int pr_read_inval(), pr_read_as(), pr_read_status(),
582 pr_read_lstatus(), pr_read_psinfo(), pr_read_lpsinfo(),
583 pr_read_map(), pr_read_rmap(), pr_read_xmap(),
584 pr_read_cred(), pr_read_sigact(), pr_read_auxv(),
585 #if defined(__x86)
586 pr_read_ldt(),
587 #endif
588 pr_read_usage(), pr_read_lusage(), pr_read_pagedata(),
589 pr_read_watch(), pr_read_lwpstatus(), pr_read_lwpsinfo(),
590 pr_read_lwpusage(), pr_read_xregs(), pr_read_priv(),
591 pr_read_spymaster(), pr_read_secflags(),
592 #if defined(__sparc)
593 pr_read_gwindows(), pr_read_asrs(),
594 #endif
595 pr_read_piddir(), pr_read_pidfile(), pr_read_opagedata();
596
597 static int (*pr_read_function[PR_NFILES])() = {
598 pr_read_inval, /* /proc */
599 pr_read_inval, /* /proc/self */
600 pr_read_piddir, /* /proc/<pid> (old /proc read()) */
601 pr_read_as, /* /proc/<pid>/as */
602 pr_read_inval, /* /proc/<pid>/ctl */
603 pr_read_status, /* /proc/<pid>/status */
604 pr_read_lstatus, /* /proc/<pid>/lstatus */
605 pr_read_psinfo, /* /proc/<pid>/psinfo */
606 pr_read_lpsinfo, /* /proc/<pid>/lpsinfo */
607 pr_read_map, /* /proc/<pid>/map */
608 pr_read_rmap, /* /proc/<pid>/rmap */
609 pr_read_xmap, /* /proc/<pid>/xmap */
610 pr_read_cred, /* /proc/<pid>/cred */
611 pr_read_sigact, /* /proc/<pid>/sigact */
612 pr_read_auxv, /* /proc/<pid>/auxv */
613 #if defined(__x86)
614 pr_read_ldt, /* /proc/<pid>/ldt */
615 #endif
616 pr_read_usage, /* /proc/<pid>/usage */
617 pr_read_lusage, /* /proc/<pid>/lusage */
618 pr_read_pagedata, /* /proc/<pid>/pagedata */
619 pr_read_watch, /* /proc/<pid>/watch */
620 pr_read_inval, /* /proc/<pid>/cwd */
621 pr_read_inval, /* /proc/<pid>/root */
622 pr_read_inval, /* /proc/<pid>/fd */
623 pr_read_inval, /* /proc/<pid>/fd/nn */
624 pr_read_inval, /* /proc/<pid>/object */
625 pr_read_inval, /* /proc/<pid>/object/xxx */
626 pr_read_inval, /* /proc/<pid>/lwp */
627 pr_read_inval, /* /proc/<pid>/lwp/<lwpid> */
628 pr_read_inval, /* /proc/<pid>/lwp/<lwpid>/lwpctl */
629 pr_read_lwpstatus, /* /proc/<pid>/lwp/<lwpid>/lwpstatus */
630 pr_read_lwpsinfo, /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
631 pr_read_lwpusage, /* /proc/<pid>/lwp/<lwpid>/lwpusage */
632 pr_read_xregs, /* /proc/<pid>/lwp/<lwpid>/xregs */
633 pr_read_inval, /* /proc/<pid>/lwp/<lwpid>/templates */
634 pr_read_inval, /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
635 pr_read_spymaster, /* /proc/<pid>/lwp/<lwpid>/spymaster */
636 #if defined(__sparc)
637 pr_read_gwindows, /* /proc/<pid>/lwp/<lwpid>/gwindows */
638 pr_read_asrs, /* /proc/<pid>/lwp/<lwpid>/asrs */
639 #endif
640 pr_read_priv, /* /proc/<pid>/priv */
641 pr_read_inval, /* /proc/<pid>/path */
642 pr_read_inval, /* /proc/<pid>/path/xxx */
643 pr_read_inval, /* /proc/<pid>/contracts */
644 pr_read_inval, /* /proc/<pid>/contracts/<ctid> */
645 pr_read_secflags, /* /proc/<pid>/secflags */
646 pr_read_pidfile, /* old process file */
647 pr_read_pidfile, /* old lwp file */
648 pr_read_opagedata, /* old pagedata file */
1056 if (uiop->uio_offset >= sizeof (auxv)) {
1057 prunlock(pnp);
1058 return (0);
1059 }
1060
1061 p = pnp->pr_common->prc_proc;
1062 up = PTOU(p);
1063 bcopy(up->u_auxv, auxv, sizeof (auxv));
1064 prunlock(pnp);
1065
1066 return (pr_uioread(auxv, sizeof (auxv), uiop));
1067 }
1068
1069 #if defined(__x86)
1070 /*
1071 * XX64
1072 * This is almost certainly broken for the amd64 kernel, because
1073 * we have two kinds of LDT structures to export -- one for compatibility
1074 * mode, and one for long mode, sigh.
1075 *
1076 * For now lets just have a ldt of size 0 for 64-bit processes.
1077 */
1078 static int
1079 pr_read_ldt(prnode_t *pnp, uio_t *uiop)
1080 {
1081 proc_t *p;
1082 struct ssd *ssd;
1083 size_t size;
1084 int error;
1085
1086 ASSERT(pnp->pr_type == PR_LDT);
1087
1088 if ((error = prlock(pnp, ZNO)) != 0)
1089 return (error);
1090 p = pnp->pr_common->prc_proc;
1091
1092 mutex_exit(&p->p_lock);
1093 mutex_enter(&p->p_ldtlock);
1094 size = prnldt(p) * sizeof (struct ssd);
1095 if (uiop->uio_offset >= size) {
1096 mutex_exit(&p->p_ldtlock);
1521 if (uiop->uio_offset >= sizeof (prusage_t)) {
1522 prunlock(pnp);
1523 error = 0;
1524 goto out;
1525 }
1526
1527 pup->pr_tstamp = gethrtime();
1528 prgetusage(pnp->pr_common->prc_thread, pup);
1529
1530 prunlock(pnp);
1531
1532 prcvtusage(pup, upup);
1533
1534 error = pr_uioread(upup, sizeof (prusage_t), uiop);
1535 out:
1536 kmem_free(pup, sizeof (*pup));
1537 kmem_free(upup, sizeof (*upup));
1538 return (error);
1539 }
1540
1541 /* ARGSUSED */
1542 static int
1543 pr_read_xregs(prnode_t *pnp, uio_t *uiop)
1544 {
1545 #if defined(__sparc)
1546 proc_t *p;
1547 kthread_t *t;
1548 int error;
1549 char *xreg;
1550 size_t size;
1551
1552 ASSERT(pnp->pr_type == PR_XREGS);
1553
1554 xreg = kmem_zalloc(sizeof (prxregset_t), KM_SLEEP);
1555
1556 if ((error = prlock(pnp, ZNO)) != 0)
1557 goto out;
1558
1559 p = pnp->pr_common->prc_proc;
1560 t = pnp->pr_common->prc_thread;
1791 pr_read_xmap_32, /* /proc/<pid>/xmap */
1792 pr_read_cred, /* /proc/<pid>/cred */
1793 pr_read_sigact_32, /* /proc/<pid>/sigact */
1794 pr_read_auxv_32, /* /proc/<pid>/auxv */
1795 #if defined(__x86)
1796 pr_read_ldt, /* /proc/<pid>/ldt */
1797 #endif
1798 pr_read_usage_32, /* /proc/<pid>/usage */
1799 pr_read_lusage_32, /* /proc/<pid>/lusage */
1800 pr_read_pagedata_32, /* /proc/<pid>/pagedata */
1801 pr_read_watch_32, /* /proc/<pid>/watch */
1802 pr_read_inval, /* /proc/<pid>/cwd */
1803 pr_read_inval, /* /proc/<pid>/root */
1804 pr_read_inval, /* /proc/<pid>/fd */
1805 pr_read_inval, /* /proc/<pid>/fd/nn */
1806 pr_read_inval, /* /proc/<pid>/object */
1807 pr_read_inval, /* /proc/<pid>/object/xxx */
1808 pr_read_inval, /* /proc/<pid>/lwp */
1809 pr_read_inval, /* /proc/<pid>/lwp/<lwpid> */
1810 pr_read_inval, /* /proc/<pid>/lwp/<lwpid>/lwpctl */
1811 pr_read_lwpstatus_32, /* /proc/<pid>/lwp/<lwpid>/lwpstatus */
1812 pr_read_lwpsinfo_32, /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
1813 pr_read_lwpusage_32, /* /proc/<pid>/lwp/<lwpid>/lwpusage */
1814 pr_read_xregs, /* /proc/<pid>/lwp/<lwpid>/xregs */
1815 pr_read_inval, /* /proc/<pid>/lwp/<lwpid>/templates */
1816 pr_read_inval, /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
1817 pr_read_spymaster_32, /* /proc/<pid>/lwp/<lwpid>/spymaster */
1818 #if defined(__sparc)
1819 pr_read_gwindows_32, /* /proc/<pid>/lwp/<lwpid>/gwindows */
1820 pr_read_asrs, /* /proc/<pid>/lwp/<lwpid>/asrs */
1821 #endif
1822 pr_read_priv, /* /proc/<pid>/priv */
1823 pr_read_inval, /* /proc/<pid>/path */
1824 pr_read_inval, /* /proc/<pid>/path/xxx */
1825 pr_read_inval, /* /proc/<pid>/contracts */
1826 pr_read_inval, /* /proc/<pid>/contracts/<ctid> */
1827 pr_read_secflags, /* /proc/<pid>/secflags */
1828 pr_read_pidfile, /* old process file */
1829 pr_read_pidfile, /* old lwp file */
1830 pr_read_opagedata_32, /* old pagedata file */
2703 {
2704 prnode_t *pnp = VTOP(vp);
2705
2706 ASSERT(pnp->pr_type < PR_NFILES);
2707
2708 #ifdef _SYSCALL32_IMPL
2709 /*
2710 * What is read from the /proc files depends on the data
2711 * model of the caller. An LP64 process will see LP64
2712 * data. An ILP32 process will see ILP32 data.
2713 */
2714 if (curproc->p_model == DATAMODEL_LP64)
2715 return (pr_read_function[pnp->pr_type](pnp, uiop));
2716 else
2717 return (pr_read_function_32[pnp->pr_type](pnp, uiop));
2718 #else
2719 return (pr_read_function[pnp->pr_type](pnp, uiop));
2720 #endif
2721 }
2722
2723 /* ARGSUSED */
2724 static int
2725 prwrite(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *cr, caller_context_t *ct)
2726 {
2727 prnode_t *pnp = VTOP(vp);
2728 int old = 0;
2729 int error;
2730 ssize_t resid;
2731
2732 ASSERT(pnp->pr_type < PR_NFILES);
2733
2734 /*
2735 * Only a handful of /proc files are writable, enumerate them here.
2736 */
2737 switch (pnp->pr_type) {
2738 case PR_PIDDIR: /* directory write()s: visceral revulsion. */
2739 ASSERT(pnp->pr_pidfile != NULL);
2740 /* use the underlying PR_PIDFILE to write the process */
2741 vp = pnp->pr_pidfile;
2742 pnp = VTOP(vp);
2781 * Perform the action on the control file
2782 * by passing curthreads credentials
2783 * and not target process's credentials.
2784 */
2785 #ifdef _SYSCALL32_IMPL
2786 if (curproc->p_model == DATAMODEL_ILP32)
2787 error = prwritectl32(vp, uiop, CRED());
2788 else
2789 error = prwritectl(vp, uiop, CRED());
2790 #else
2791 error = prwritectl(vp, uiop, CRED());
2792 #endif
2793 /*
2794 * This hack makes sure that the EINTR is passed
2795 * all the way back to the caller's write() call.
2796 */
2797 if (error == EINTR)
2798 uiop->uio_resid = resid;
2799 return (error);
2800
2801 default:
2802 return ((vp->v_type == VDIR)? EISDIR : EBADF);
2803 }
2804 /* NOTREACHED */
2805 }
2806
2807 static int
2808 prgetattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr,
2809 caller_context_t *ct)
2810 {
2811 prnode_t *pnp = VTOP(vp);
2812 prnodetype_t type = pnp->pr_type;
2813 prcommon_t *pcp;
2814 proc_t *p;
2815 struct as *as;
2816 int error;
2817 vnode_t *rvp;
2818 timestruc_t now;
2819 extern uint_t nproc;
2820 int ngroups;
3341 pr_lookup_notdir, /* /proc/<pid>/xmap */
3342 pr_lookup_notdir, /* /proc/<pid>/cred */
3343 pr_lookup_notdir, /* /proc/<pid>/sigact */
3344 pr_lookup_notdir, /* /proc/<pid>/auxv */
3345 #if defined(__x86)
3346 pr_lookup_notdir, /* /proc/<pid>/ldt */
3347 #endif
3348 pr_lookup_notdir, /* /proc/<pid>/usage */
3349 pr_lookup_notdir, /* /proc/<pid>/lusage */
3350 pr_lookup_notdir, /* /proc/<pid>/pagedata */
3351 pr_lookup_notdir, /* /proc/<pid>/watch */
3352 pr_lookup_notdir, /* /proc/<pid>/cwd */
3353 pr_lookup_notdir, /* /proc/<pid>/root */
3354 pr_lookup_fddir, /* /proc/<pid>/fd */
3355 pr_lookup_notdir, /* /proc/<pid>/fd/nn */
3356 pr_lookup_objectdir, /* /proc/<pid>/object */
3357 pr_lookup_notdir, /* /proc/<pid>/object/xxx */
3358 pr_lookup_lwpdir, /* /proc/<pid>/lwp */
3359 pr_lookup_lwpiddir, /* /proc/<pid>/lwp/<lwpid> */
3360 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpctl */
3361 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpstatus */
3362 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
3363 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpusage */
3364 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/xregs */
3365 pr_lookup_tmpldir, /* /proc/<pid>/lwp/<lwpid>/templates */
3366 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
3367 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/spymaster */
3368 #if defined(__sparc)
3369 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/gwindows */
3370 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/asrs */
3371 #endif
3372 pr_lookup_notdir, /* /proc/<pid>/priv */
3373 pr_lookup_pathdir, /* /proc/<pid>/path */
3374 pr_lookup_notdir, /* /proc/<pid>/path/xxx */
3375 pr_lookup_ctdir, /* /proc/<pid>/contracts */
3376 pr_lookup_notdir, /* /proc/<pid>/contracts/<ctid> */
3377 pr_lookup_notdir, /* /proc/<pid>/secflags */
3378 pr_lookup_notdir, /* old process file */
3379 pr_lookup_notdir, /* old lwp file */
3380 pr_lookup_notdir, /* old pagedata file */
4604 case PR_LWPDIR:
4605 vp->v_type = VDIR;
4606 pnp->pr_mode = 0555; /* read-search by all */
4607 break;
4608
4609 case PR_AS:
4610 case PR_TMPL:
4611 pnp->pr_mode = 0600; /* read-write by owner only */
4612 break;
4613
4614 case PR_CTL:
4615 case PR_LWPCTL:
4616 pnp->pr_mode = 0200; /* write-only by owner only */
4617 break;
4618
4619 case PR_PIDFILE:
4620 case PR_LWPIDFILE:
4621 pnp->pr_mode = 0600; /* read-write by owner only */
4622 break;
4623
4624 case PR_PSINFO:
4625 case PR_LPSINFO:
4626 case PR_LWPSINFO:
4627 case PR_USAGE:
4628 case PR_LUSAGE:
4629 case PR_LWPUSAGE:
4630 pnp->pr_mode = 0444; /* read-only by all */
4631 break;
4632
4633 default:
4634 pnp->pr_mode = 0400; /* read-only by owner only */
4635 break;
4636 }
4637 vn_exists(vp);
4638 return (pnp);
4639 }
4640
4641 /*
4642 * Free the storage obtained from prgetnode().
4643 */
4728 pr_readdir_notdir, /* /proc/<pid>/xmap */
4729 pr_readdir_notdir, /* /proc/<pid>/cred */
4730 pr_readdir_notdir, /* /proc/<pid>/sigact */
4731 pr_readdir_notdir, /* /proc/<pid>/auxv */
4732 #if defined(__x86)
4733 pr_readdir_notdir, /* /proc/<pid>/ldt */
4734 #endif
4735 pr_readdir_notdir, /* /proc/<pid>/usage */
4736 pr_readdir_notdir, /* /proc/<pid>/lusage */
4737 pr_readdir_notdir, /* /proc/<pid>/pagedata */
4738 pr_readdir_notdir, /* /proc/<pid>/watch */
4739 pr_readdir_notdir, /* /proc/<pid>/cwd */
4740 pr_readdir_notdir, /* /proc/<pid>/root */
4741 pr_readdir_fddir, /* /proc/<pid>/fd */
4742 pr_readdir_notdir, /* /proc/<pid>/fd/nn */
4743 pr_readdir_objectdir, /* /proc/<pid>/object */
4744 pr_readdir_notdir, /* /proc/<pid>/object/xxx */
4745 pr_readdir_lwpdir, /* /proc/<pid>/lwp */
4746 pr_readdir_lwpiddir, /* /proc/<pid>/lwp/<lwpid> */
4747 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpctl */
4748 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpstatus */
4749 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
4750 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpusage */
4751 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/xregs */
4752 pr_readdir_tmpldir, /* /proc/<pid>/lwp/<lwpid>/templates */
4753 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
4754 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/spymaster */
4755 #if defined(__sparc)
4756 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/gwindows */
4757 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/asrs */
4758 #endif
4759 pr_readdir_notdir, /* /proc/<pid>/priv */
4760 pr_readdir_pathdir, /* /proc/<pid>/path */
4761 pr_readdir_notdir, /* /proc/<pid>/path/xxx */
4762 pr_readdir_ctdir, /* /proc/<pid>/contracts */
4763 pr_readdir_notdir, /* /proc/<pid>/contracts/<ctid> */
4764 pr_readdir_notdir, /* /proc/<pid>/secflags */
4765 pr_readdir_notdir, /* old process file */
4766 pr_readdir_notdir, /* old lwp file */
4767 pr_readdir_notdir, /* old pagedata file */
|
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2018, Joyent, Inc.
25 * Copyright (c) 2017 by Delphix. All rights reserved.
26 */
27
28 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
29 /* All Rights Reserved */
30
31 #include <sys/types.h>
32 #include <sys/param.h>
33 #include <sys/time.h>
34 #include <sys/cred.h>
35 #include <sys/policy.h>
36 #include <sys/debug.h>
37 #include <sys/dirent.h>
38 #include <sys/errno.h>
39 #include <sys/file.h>
40 #include <sys/inline.h>
41 #include <sys/kmem.h>
42 #include <sys/pathname.h>
43 #include <sys/proc.h>
44 #include <sys/brand.h>
47 #include <sys/sysmacros.h>
48 #include <sys/systm.h>
49 #include <sys/zone.h>
50 #include <sys/uio.h>
51 #include <sys/var.h>
52 #include <sys/mode.h>
53 #include <sys/poll.h>
54 #include <sys/user.h>
55 #include <sys/vfs.h>
56 #include <sys/vfs_opreg.h>
57 #include <sys/gfs.h>
58 #include <sys/vnode.h>
59 #include <sys/fault.h>
60 #include <sys/syscall.h>
61 #include <sys/procfs.h>
62 #include <sys/atomic.h>
63 #include <sys/cmn_err.h>
64 #include <sys/contract_impl.h>
65 #include <sys/ctfs.h>
66 #include <sys/avl.h>
67 #include <sys/ctype.h>
68 #include <fs/fs_subr.h>
69 #include <vm/rm.h>
70 #include <vm/as.h>
71 #include <vm/seg.h>
72 #include <vm/seg_vn.h>
73 #include <vm/hat.h>
74 #include <fs/proc/prdata.h>
75 #if defined(__sparc)
76 #include <sys/regset.h>
77 #endif
78 #if defined(__x86)
79 #include <sys/sysi86.h>
80 #endif
81
82 /*
83 * Created by prinit.
84 */
85 vnodeops_t *prvnodeops;
86
87 /*
167 { PR_SECFLAGS, 27 * sizeof (prdirent_t), sizeof (prdirent_t),
168 "secflags" },
169 #if defined(__x86)
170 { PR_LDT, 28 * sizeof (prdirent_t), sizeof (prdirent_t),
171 "ldt" },
172 #endif
173 };
174
175 #define NPIDDIRFILES (sizeof (piddir) / sizeof (piddir[0]) - 2)
176
177 /*
178 * Contents of a /proc/<pid>/lwp/<lwpid> directory.
179 */
180 static prdirent_t lwpiddir[] = {
181 { PR_LWPIDDIR, 1 * sizeof (prdirent_t), sizeof (prdirent_t),
182 "." },
183 { PR_LWPDIR, 2 * sizeof (prdirent_t), sizeof (prdirent_t),
184 ".." },
185 { PR_LWPCTL, 3 * sizeof (prdirent_t), sizeof (prdirent_t),
186 "lwpctl" },
187 { PR_LWPNAME, 4 * sizeof (prdirent_t), sizeof (prdirent_t),
188 "lwpname" },
189 { PR_LWPSTATUS, 5 * sizeof (prdirent_t), sizeof (prdirent_t),
190 "lwpstatus" },
191 { PR_LWPSINFO, 6 * sizeof (prdirent_t), sizeof (prdirent_t),
192 "lwpsinfo" },
193 { PR_LWPUSAGE, 7 * sizeof (prdirent_t), sizeof (prdirent_t),
194 "lwpusage" },
195 { PR_XREGS, 8 * sizeof (prdirent_t), sizeof (prdirent_t),
196 "xregs" },
197 { PR_TMPLDIR, 9 * sizeof (prdirent_t), sizeof (prdirent_t),
198 "templates" },
199 { PR_SPYMASTER, 10 * sizeof (prdirent_t), sizeof (prdirent_t),
200 "spymaster" },
201 #if defined(__sparc)
202 { PR_GWINDOWS, 11 * sizeof (prdirent_t), sizeof (prdirent_t),
203 "gwindows" },
204 { PR_ASRS, 12 * sizeof (prdirent_t), sizeof (prdirent_t),
205 "asrs" },
206 #endif
207 };
208
209 #define NLWPIDDIRFILES (sizeof (lwpiddir) / sizeof (lwpiddir[0]) - 2)
210
211 /*
212 * Span of entries in the array files (lstatus, lpsinfo, lusage).
213 * We make the span larger than the size of the structure on purpose,
214 * to make sure that programs cannot use the structure size by mistake.
215 * Align _ILP32 structures at 8 bytes, _LP64 structures at 16 bytes.
216 */
217 #ifdef _LP64
218 #define LSPAN(type) (round16(sizeof (type)) + 16)
219 #define LSPAN32(type) (round8(sizeof (type)) + 8)
220 #else
221 #define LSPAN(type) (round8(sizeof (type)) + 8)
222 #endif
223
224 static void rebuild_objdir(struct as *);
573 else
574 allsetrun(p);
575 }
576
577 prunlock(pnp);
578 return (0);
579 }
580
581 /*
582 * Array of read functions, indexed by /proc file type.
583 */
584 static int pr_read_inval(), pr_read_as(), pr_read_status(),
585 pr_read_lstatus(), pr_read_psinfo(), pr_read_lpsinfo(),
586 pr_read_map(), pr_read_rmap(), pr_read_xmap(),
587 pr_read_cred(), pr_read_sigact(), pr_read_auxv(),
588 #if defined(__x86)
589 pr_read_ldt(),
590 #endif
591 pr_read_usage(), pr_read_lusage(), pr_read_pagedata(),
592 pr_read_watch(), pr_read_lwpstatus(), pr_read_lwpsinfo(),
593 pr_read_lwpusage(), pr_read_lwpname(),
594 pr_read_xregs(), pr_read_priv(),
595 pr_read_spymaster(), pr_read_secflags(),
596 #if defined(__sparc)
597 pr_read_gwindows(), pr_read_asrs(),
598 #endif
599 pr_read_piddir(), pr_read_pidfile(), pr_read_opagedata();
600
601 static int (*pr_read_function[PR_NFILES])() = {
602 pr_read_inval, /* /proc */
603 pr_read_inval, /* /proc/self */
604 pr_read_piddir, /* /proc/<pid> (old /proc read()) */
605 pr_read_as, /* /proc/<pid>/as */
606 pr_read_inval, /* /proc/<pid>/ctl */
607 pr_read_status, /* /proc/<pid>/status */
608 pr_read_lstatus, /* /proc/<pid>/lstatus */
609 pr_read_psinfo, /* /proc/<pid>/psinfo */
610 pr_read_lpsinfo, /* /proc/<pid>/lpsinfo */
611 pr_read_map, /* /proc/<pid>/map */
612 pr_read_rmap, /* /proc/<pid>/rmap */
613 pr_read_xmap, /* /proc/<pid>/xmap */
614 pr_read_cred, /* /proc/<pid>/cred */
615 pr_read_sigact, /* /proc/<pid>/sigact */
616 pr_read_auxv, /* /proc/<pid>/auxv */
617 #if defined(__x86)
618 pr_read_ldt, /* /proc/<pid>/ldt */
619 #endif
620 pr_read_usage, /* /proc/<pid>/usage */
621 pr_read_lusage, /* /proc/<pid>/lusage */
622 pr_read_pagedata, /* /proc/<pid>/pagedata */
623 pr_read_watch, /* /proc/<pid>/watch */
624 pr_read_inval, /* /proc/<pid>/cwd */
625 pr_read_inval, /* /proc/<pid>/root */
626 pr_read_inval, /* /proc/<pid>/fd */
627 pr_read_inval, /* /proc/<pid>/fd/nn */
628 pr_read_inval, /* /proc/<pid>/object */
629 pr_read_inval, /* /proc/<pid>/object/xxx */
630 pr_read_inval, /* /proc/<pid>/lwp */
631 pr_read_inval, /* /proc/<pid>/lwp/<lwpid> */
632 pr_read_inval, /* /proc/<pid>/lwp/<lwpid>/lwpctl */
633 pr_read_lwpname, /* /proc/<pid>/lwp/<lwpid>/lwpname */
634 pr_read_lwpstatus, /* /proc/<pid>/lwp/<lwpid>/lwpstatus */
635 pr_read_lwpsinfo, /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
636 pr_read_lwpusage, /* /proc/<pid>/lwp/<lwpid>/lwpusage */
637 pr_read_xregs, /* /proc/<pid>/lwp/<lwpid>/xregs */
638 pr_read_inval, /* /proc/<pid>/lwp/<lwpid>/templates */
639 pr_read_inval, /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
640 pr_read_spymaster, /* /proc/<pid>/lwp/<lwpid>/spymaster */
641 #if defined(__sparc)
642 pr_read_gwindows, /* /proc/<pid>/lwp/<lwpid>/gwindows */
643 pr_read_asrs, /* /proc/<pid>/lwp/<lwpid>/asrs */
644 #endif
645 pr_read_priv, /* /proc/<pid>/priv */
646 pr_read_inval, /* /proc/<pid>/path */
647 pr_read_inval, /* /proc/<pid>/path/xxx */
648 pr_read_inval, /* /proc/<pid>/contracts */
649 pr_read_inval, /* /proc/<pid>/contracts/<ctid> */
650 pr_read_secflags, /* /proc/<pid>/secflags */
651 pr_read_pidfile, /* old process file */
652 pr_read_pidfile, /* old lwp file */
653 pr_read_opagedata, /* old pagedata file */
1061 if (uiop->uio_offset >= sizeof (auxv)) {
1062 prunlock(pnp);
1063 return (0);
1064 }
1065
1066 p = pnp->pr_common->prc_proc;
1067 up = PTOU(p);
1068 bcopy(up->u_auxv, auxv, sizeof (auxv));
1069 prunlock(pnp);
1070
1071 return (pr_uioread(auxv, sizeof (auxv), uiop));
1072 }
1073
1074 #if defined(__x86)
1075 /*
1076 * XX64
1077 * This is almost certainly broken for the amd64 kernel, because
1078 * we have two kinds of LDT structures to export -- one for compatibility
1079 * mode, and one for long mode, sigh.
1080 *
1081 * For now let's just have a ldt of size 0 for 64-bit processes.
1082 */
1083 static int
1084 pr_read_ldt(prnode_t *pnp, uio_t *uiop)
1085 {
1086 proc_t *p;
1087 struct ssd *ssd;
1088 size_t size;
1089 int error;
1090
1091 ASSERT(pnp->pr_type == PR_LDT);
1092
1093 if ((error = prlock(pnp, ZNO)) != 0)
1094 return (error);
1095 p = pnp->pr_common->prc_proc;
1096
1097 mutex_exit(&p->p_lock);
1098 mutex_enter(&p->p_ldtlock);
1099 size = prnldt(p) * sizeof (struct ssd);
1100 if (uiop->uio_offset >= size) {
1101 mutex_exit(&p->p_ldtlock);
1526 if (uiop->uio_offset >= sizeof (prusage_t)) {
1527 prunlock(pnp);
1528 error = 0;
1529 goto out;
1530 }
1531
1532 pup->pr_tstamp = gethrtime();
1533 prgetusage(pnp->pr_common->prc_thread, pup);
1534
1535 prunlock(pnp);
1536
1537 prcvtusage(pup, upup);
1538
1539 error = pr_uioread(upup, sizeof (prusage_t), uiop);
1540 out:
1541 kmem_free(pup, sizeof (*pup));
1542 kmem_free(upup, sizeof (*upup));
1543 return (error);
1544 }
1545
1546 static int
1547 pr_read_lwpname(prnode_t *pnp, uio_t *uiop)
1548 {
1549 char lwpname[THREAD_NAME_MAX];
1550 kthread_t *t;
1551 int error;
1552
1553 ASSERT(pnp->pr_type == PR_LWPNAME);
1554
1555 if (uiop->uio_offset >= THREAD_NAME_MAX)
1556 return (0);
1557
1558 if ((error = prlock(pnp, ZNO)) != 0)
1559 return (error);
1560
1561 bzero(lwpname, sizeof (lwpname));
1562
1563 t = pnp->pr_common->prc_thread;
1564
1565 if (t->t_name != NULL)
1566 (void) strlcpy(lwpname, t->t_name, sizeof (lwpname));
1567
1568 prunlock(pnp);
1569
1570 return (pr_uioread(lwpname, sizeof (lwpname), uiop));
1571 }
1572
1573 /* ARGSUSED */
1574 static int
1575 pr_read_xregs(prnode_t *pnp, uio_t *uiop)
1576 {
1577 #if defined(__sparc)
1578 proc_t *p;
1579 kthread_t *t;
1580 int error;
1581 char *xreg;
1582 size_t size;
1583
1584 ASSERT(pnp->pr_type == PR_XREGS);
1585
1586 xreg = kmem_zalloc(sizeof (prxregset_t), KM_SLEEP);
1587
1588 if ((error = prlock(pnp, ZNO)) != 0)
1589 goto out;
1590
1591 p = pnp->pr_common->prc_proc;
1592 t = pnp->pr_common->prc_thread;
1823 pr_read_xmap_32, /* /proc/<pid>/xmap */
1824 pr_read_cred, /* /proc/<pid>/cred */
1825 pr_read_sigact_32, /* /proc/<pid>/sigact */
1826 pr_read_auxv_32, /* /proc/<pid>/auxv */
1827 #if defined(__x86)
1828 pr_read_ldt, /* /proc/<pid>/ldt */
1829 #endif
1830 pr_read_usage_32, /* /proc/<pid>/usage */
1831 pr_read_lusage_32, /* /proc/<pid>/lusage */
1832 pr_read_pagedata_32, /* /proc/<pid>/pagedata */
1833 pr_read_watch_32, /* /proc/<pid>/watch */
1834 pr_read_inval, /* /proc/<pid>/cwd */
1835 pr_read_inval, /* /proc/<pid>/root */
1836 pr_read_inval, /* /proc/<pid>/fd */
1837 pr_read_inval, /* /proc/<pid>/fd/nn */
1838 pr_read_inval, /* /proc/<pid>/object */
1839 pr_read_inval, /* /proc/<pid>/object/xxx */
1840 pr_read_inval, /* /proc/<pid>/lwp */
1841 pr_read_inval, /* /proc/<pid>/lwp/<lwpid> */
1842 pr_read_inval, /* /proc/<pid>/lwp/<lwpid>/lwpctl */
1843 pr_read_lwpname, /* /proc/<pid>/lwp/<lwpid>/lwpname */
1844 pr_read_lwpstatus_32, /* /proc/<pid>/lwp/<lwpid>/lwpstatus */
1845 pr_read_lwpsinfo_32, /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
1846 pr_read_lwpusage_32, /* /proc/<pid>/lwp/<lwpid>/lwpusage */
1847 pr_read_xregs, /* /proc/<pid>/lwp/<lwpid>/xregs */
1848 pr_read_inval, /* /proc/<pid>/lwp/<lwpid>/templates */
1849 pr_read_inval, /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
1850 pr_read_spymaster_32, /* /proc/<pid>/lwp/<lwpid>/spymaster */
1851 #if defined(__sparc)
1852 pr_read_gwindows_32, /* /proc/<pid>/lwp/<lwpid>/gwindows */
1853 pr_read_asrs, /* /proc/<pid>/lwp/<lwpid>/asrs */
1854 #endif
1855 pr_read_priv, /* /proc/<pid>/priv */
1856 pr_read_inval, /* /proc/<pid>/path */
1857 pr_read_inval, /* /proc/<pid>/path/xxx */
1858 pr_read_inval, /* /proc/<pid>/contracts */
1859 pr_read_inval, /* /proc/<pid>/contracts/<ctid> */
1860 pr_read_secflags, /* /proc/<pid>/secflags */
1861 pr_read_pidfile, /* old process file */
1862 pr_read_pidfile, /* old lwp file */
1863 pr_read_opagedata_32, /* old pagedata file */
2736 {
2737 prnode_t *pnp = VTOP(vp);
2738
2739 ASSERT(pnp->pr_type < PR_NFILES);
2740
2741 #ifdef _SYSCALL32_IMPL
2742 /*
2743 * What is read from the /proc files depends on the data
2744 * model of the caller. An LP64 process will see LP64
2745 * data. An ILP32 process will see ILP32 data.
2746 */
2747 if (curproc->p_model == DATAMODEL_LP64)
2748 return (pr_read_function[pnp->pr_type](pnp, uiop));
2749 else
2750 return (pr_read_function_32[pnp->pr_type](pnp, uiop));
2751 #else
2752 return (pr_read_function[pnp->pr_type](pnp, uiop));
2753 #endif
2754 }
2755
2756 /* Note we intentionally don't handle partial writes/updates. */
2757 static int
2758 pr_write_lwpname(prnode_t *pnp, uio_t *uiop)
2759 {
2760 kthread_t *t = NULL;
2761 char *lwpname;
2762 int error;
2763
2764 lwpname = kmem_zalloc(THREAD_NAME_MAX, KM_SLEEP);
2765
2766 if ((error = uiomove(lwpname, THREAD_NAME_MAX, UIO_WRITE, uiop)) != 0) {
2767 kmem_free(lwpname, THREAD_NAME_MAX);
2768 return (error);
2769 }
2770
2771 /* Somebody tried to write too long a thread name... */
2772 if (lwpname[THREAD_NAME_MAX - 1] != '\0' || uiop->uio_resid > 0) {
2773 kmem_free(lwpname, THREAD_NAME_MAX);
2774 return (EIO);
2775 }
2776
2777 VERIFY3U(lwpname[THREAD_NAME_MAX - 1], ==, '\0');
2778
2779 for (size_t i = 0; lwpname[i] != '\0'; i++) {
2780 if (!ISPRINT(lwpname[i])) {
2781 kmem_free(lwpname, THREAD_NAME_MAX);
2782 return (EINVAL);
2783 }
2784 }
2785
2786 /* Equivalent of thread_setname(), but with the ZNO magic. */
2787 if ((error = prlock(pnp, ZNO)) != 0) {
2788 kmem_free(lwpname, THREAD_NAME_MAX);
2789 return (error);
2790 }
2791
2792 t = pnp->pr_common->prc_thread;
2793 if (t->t_name == NULL) {
2794 t->t_name = lwpname;
2795 } else {
2796 (void) strlcpy(t->t_name, lwpname, THREAD_NAME_MAX);
2797 kmem_free(lwpname, THREAD_NAME_MAX);
2798 }
2799
2800 prunlock(pnp);
2801 return (0);
2802 }
2803
2804 /* ARGSUSED */
2805 static int
2806 prwrite(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *cr, caller_context_t *ct)
2807 {
2808 prnode_t *pnp = VTOP(vp);
2809 int old = 0;
2810 int error;
2811 ssize_t resid;
2812
2813 ASSERT(pnp->pr_type < PR_NFILES);
2814
2815 /*
2816 * Only a handful of /proc files are writable, enumerate them here.
2817 */
2818 switch (pnp->pr_type) {
2819 case PR_PIDDIR: /* directory write()s: visceral revulsion. */
2820 ASSERT(pnp->pr_pidfile != NULL);
2821 /* use the underlying PR_PIDFILE to write the process */
2822 vp = pnp->pr_pidfile;
2823 pnp = VTOP(vp);
2862 * Perform the action on the control file
2863 * by passing curthreads credentials
2864 * and not target process's credentials.
2865 */
2866 #ifdef _SYSCALL32_IMPL
2867 if (curproc->p_model == DATAMODEL_ILP32)
2868 error = prwritectl32(vp, uiop, CRED());
2869 else
2870 error = prwritectl(vp, uiop, CRED());
2871 #else
2872 error = prwritectl(vp, uiop, CRED());
2873 #endif
2874 /*
2875 * This hack makes sure that the EINTR is passed
2876 * all the way back to the caller's write() call.
2877 */
2878 if (error == EINTR)
2879 uiop->uio_resid = resid;
2880 return (error);
2881
2882 case PR_LWPNAME:
2883 return (pr_write_lwpname(pnp, uiop));
2884
2885 default:
2886 return ((vp->v_type == VDIR)? EISDIR : EBADF);
2887 }
2888 /* NOTREACHED */
2889 }
2890
2891 static int
2892 prgetattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr,
2893 caller_context_t *ct)
2894 {
2895 prnode_t *pnp = VTOP(vp);
2896 prnodetype_t type = pnp->pr_type;
2897 prcommon_t *pcp;
2898 proc_t *p;
2899 struct as *as;
2900 int error;
2901 vnode_t *rvp;
2902 timestruc_t now;
2903 extern uint_t nproc;
2904 int ngroups;
3425 pr_lookup_notdir, /* /proc/<pid>/xmap */
3426 pr_lookup_notdir, /* /proc/<pid>/cred */
3427 pr_lookup_notdir, /* /proc/<pid>/sigact */
3428 pr_lookup_notdir, /* /proc/<pid>/auxv */
3429 #if defined(__x86)
3430 pr_lookup_notdir, /* /proc/<pid>/ldt */
3431 #endif
3432 pr_lookup_notdir, /* /proc/<pid>/usage */
3433 pr_lookup_notdir, /* /proc/<pid>/lusage */
3434 pr_lookup_notdir, /* /proc/<pid>/pagedata */
3435 pr_lookup_notdir, /* /proc/<pid>/watch */
3436 pr_lookup_notdir, /* /proc/<pid>/cwd */
3437 pr_lookup_notdir, /* /proc/<pid>/root */
3438 pr_lookup_fddir, /* /proc/<pid>/fd */
3439 pr_lookup_notdir, /* /proc/<pid>/fd/nn */
3440 pr_lookup_objectdir, /* /proc/<pid>/object */
3441 pr_lookup_notdir, /* /proc/<pid>/object/xxx */
3442 pr_lookup_lwpdir, /* /proc/<pid>/lwp */
3443 pr_lookup_lwpiddir, /* /proc/<pid>/lwp/<lwpid> */
3444 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpctl */
3445 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpname */
3446 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpstatus */
3447 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
3448 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpusage */
3449 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/xregs */
3450 pr_lookup_tmpldir, /* /proc/<pid>/lwp/<lwpid>/templates */
3451 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
3452 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/spymaster */
3453 #if defined(__sparc)
3454 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/gwindows */
3455 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/asrs */
3456 #endif
3457 pr_lookup_notdir, /* /proc/<pid>/priv */
3458 pr_lookup_pathdir, /* /proc/<pid>/path */
3459 pr_lookup_notdir, /* /proc/<pid>/path/xxx */
3460 pr_lookup_ctdir, /* /proc/<pid>/contracts */
3461 pr_lookup_notdir, /* /proc/<pid>/contracts/<ctid> */
3462 pr_lookup_notdir, /* /proc/<pid>/secflags */
3463 pr_lookup_notdir, /* old process file */
3464 pr_lookup_notdir, /* old lwp file */
3465 pr_lookup_notdir, /* old pagedata file */
4689 case PR_LWPDIR:
4690 vp->v_type = VDIR;
4691 pnp->pr_mode = 0555; /* read-search by all */
4692 break;
4693
4694 case PR_AS:
4695 case PR_TMPL:
4696 pnp->pr_mode = 0600; /* read-write by owner only */
4697 break;
4698
4699 case PR_CTL:
4700 case PR_LWPCTL:
4701 pnp->pr_mode = 0200; /* write-only by owner only */
4702 break;
4703
4704 case PR_PIDFILE:
4705 case PR_LWPIDFILE:
4706 pnp->pr_mode = 0600; /* read-write by owner only */
4707 break;
4708
4709 case PR_LWPNAME:
4710 pnp->pr_mode = 0644; /* readable by all + owner can write */
4711 break;
4712
4713 case PR_PSINFO:
4714 case PR_LPSINFO:
4715 case PR_LWPSINFO:
4716 case PR_USAGE:
4717 case PR_LUSAGE:
4718 case PR_LWPUSAGE:
4719 pnp->pr_mode = 0444; /* read-only by all */
4720 break;
4721
4722 default:
4723 pnp->pr_mode = 0400; /* read-only by owner only */
4724 break;
4725 }
4726 vn_exists(vp);
4727 return (pnp);
4728 }
4729
4730 /*
4731 * Free the storage obtained from prgetnode().
4732 */
4817 pr_readdir_notdir, /* /proc/<pid>/xmap */
4818 pr_readdir_notdir, /* /proc/<pid>/cred */
4819 pr_readdir_notdir, /* /proc/<pid>/sigact */
4820 pr_readdir_notdir, /* /proc/<pid>/auxv */
4821 #if defined(__x86)
4822 pr_readdir_notdir, /* /proc/<pid>/ldt */
4823 #endif
4824 pr_readdir_notdir, /* /proc/<pid>/usage */
4825 pr_readdir_notdir, /* /proc/<pid>/lusage */
4826 pr_readdir_notdir, /* /proc/<pid>/pagedata */
4827 pr_readdir_notdir, /* /proc/<pid>/watch */
4828 pr_readdir_notdir, /* /proc/<pid>/cwd */
4829 pr_readdir_notdir, /* /proc/<pid>/root */
4830 pr_readdir_fddir, /* /proc/<pid>/fd */
4831 pr_readdir_notdir, /* /proc/<pid>/fd/nn */
4832 pr_readdir_objectdir, /* /proc/<pid>/object */
4833 pr_readdir_notdir, /* /proc/<pid>/object/xxx */
4834 pr_readdir_lwpdir, /* /proc/<pid>/lwp */
4835 pr_readdir_lwpiddir, /* /proc/<pid>/lwp/<lwpid> */
4836 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpctl */
4837 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpname */
4838 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpstatus */
4839 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
4840 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpusage */
4841 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/xregs */
4842 pr_readdir_tmpldir, /* /proc/<pid>/lwp/<lwpid>/templates */
4843 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
4844 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/spymaster */
4845 #if defined(__sparc)
4846 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/gwindows */
4847 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/asrs */
4848 #endif
4849 pr_readdir_notdir, /* /proc/<pid>/priv */
4850 pr_readdir_pathdir, /* /proc/<pid>/path */
4851 pr_readdir_notdir, /* /proc/<pid>/path/xxx */
4852 pr_readdir_ctdir, /* /proc/<pid>/contracts */
4853 pr_readdir_notdir, /* /proc/<pid>/contracts/<ctid> */
4854 pr_readdir_notdir, /* /proc/<pid>/secflags */
4855 pr_readdir_notdir, /* old process file */
4856 pr_readdir_notdir, /* old lwp file */
4857 pr_readdir_notdir, /* old pagedata file */
|