1 /*
2 * CDDL HEADER START
3 *
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 * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
27 * Copyright 2022 MNX Cloud, Inc.
28 * Copyright 2023 Oxide Computer Company
29 */
30
31 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
32 /* All Rights Reserved */
33
34 #include <sys/types.h>
35 #include <sys/param.h>
36 #include <sys/time.h>
37 #include <sys/cred.h>
38 #include <sys/policy.h>
39 #include <sys/debug.h>
40 #include <sys/dirent.h>
41 #include <sys/errno.h>
42 #include <sys/file.h>
43 #include <sys/inline.h>
44 #include <sys/kmem.h>
45 #include <sys/pathname.h>
46 #include <sys/proc.h>
47 #include <sys/brand.h>
48 #include <sys/signal.h>
49 #include <sys/stat.h>
50 #include <sys/sysmacros.h>
51 #include <sys/systm.h>
52 #include <sys/zone.h>
53 #include <sys/uio.h>
54 #include <sys/var.h>
55 #include <sys/mode.h>
56 #include <sys/poll.h>
57 #include <sys/user.h>
58 #include <sys/vfs.h>
59 #include <sys/vfs_opreg.h>
60 #include <sys/gfs.h>
61 #include <sys/vnode.h>
62 #include <sys/fault.h>
63 #include <sys/syscall.h>
64 #include <sys/procfs.h>
65 #include <sys/atomic.h>
66 #include <sys/cmn_err.h>
67 #include <sys/contract_impl.h>
68 #include <sys/ctfs.h>
69 #include <sys/avl.h>
70 #include <sys/ctype.h>
71 #include <fs/fs_subr.h>
72 #include <vm/rm.h>
73 #include <vm/as.h>
74 #include <vm/seg.h>
75 #include <vm/seg_vn.h>
76 #include <vm/hat.h>
77 #include <fs/proc/prdata.h>
78 #if defined(__sparc)
79 #include <sys/regset.h>
80 #endif
81 #if defined(__x86)
82 #include <sys/sysi86.h>
83 #endif
84
85 /*
86 * Created by prinit.
87 */
88 vnodeops_t *prvnodeops;
89
90 /*
91 * Directory characteristics (patterned after the s5 file system).
92 */
93 #define PRROOTINO 2
94
95 #define PRDIRSIZE 14
96 struct prdirect {
97 ushort_t d_ino;
98 char d_name[PRDIRSIZE];
99 };
100
101 #define PRSDSIZE (sizeof (struct prdirect))
102
103 /*
104 * Directory characteristics.
105 */
106 typedef struct prdirent {
107 ino64_t d_ino; /* "inode number" of entry */
108 off64_t d_off; /* offset of disk directory entry */
109 unsigned short d_reclen; /* length of this record */
110 char d_name[14]; /* name of file */
111 } prdirent_t;
112
113 /*
114 * Contents of a /proc/<pid> directory.
115 * Reuse d_ino field for the /proc file type.
116 */
117 static prdirent_t piddir[] = {
118 { PR_PIDDIR, 1 * sizeof (prdirent_t), sizeof (prdirent_t),
119 "." },
120 { PR_PROCDIR, 2 * sizeof (prdirent_t), sizeof (prdirent_t),
121 ".." },
122 { PR_AS, 3 * sizeof (prdirent_t), sizeof (prdirent_t),
123 "as" },
124 { PR_CTL, 4 * sizeof (prdirent_t), sizeof (prdirent_t),
125 "ctl" },
126 { PR_STATUS, 5 * sizeof (prdirent_t), sizeof (prdirent_t),
127 "status" },
128 { PR_LSTATUS, 6 * sizeof (prdirent_t), sizeof (prdirent_t),
129 "lstatus" },
130 { PR_PSINFO, 7 * sizeof (prdirent_t), sizeof (prdirent_t),
131 "psinfo" },
132 { PR_LPSINFO, 8 * sizeof (prdirent_t), sizeof (prdirent_t),
133 "lpsinfo" },
134 { PR_MAP, 9 * sizeof (prdirent_t), sizeof (prdirent_t),
135 "map" },
136 { PR_RMAP, 10 * sizeof (prdirent_t), sizeof (prdirent_t),
137 "rmap" },
138 { PR_XMAP, 11 * sizeof (prdirent_t), sizeof (prdirent_t),
139 "xmap" },
140 { PR_CRED, 12 * sizeof (prdirent_t), sizeof (prdirent_t),
141 "cred" },
142 { PR_SIGACT, 13 * sizeof (prdirent_t), sizeof (prdirent_t),
143 "sigact" },
144 { PR_AUXV, 14 * sizeof (prdirent_t), sizeof (prdirent_t),
145 "auxv" },
146 { PR_USAGE, 15 * sizeof (prdirent_t), sizeof (prdirent_t),
147 "usage" },
148 { PR_LUSAGE, 16 * sizeof (prdirent_t), sizeof (prdirent_t),
149 "lusage" },
150 { PR_PAGEDATA, 17 * sizeof (prdirent_t), sizeof (prdirent_t),
151 "pagedata" },
152 { PR_WATCH, 18 * sizeof (prdirent_t), sizeof (prdirent_t),
153 "watch" },
154 { PR_CURDIR, 19 * sizeof (prdirent_t), sizeof (prdirent_t),
155 "cwd" },
156 { PR_ROOTDIR, 20 * sizeof (prdirent_t), sizeof (prdirent_t),
157 "root" },
158 { PR_FDDIR, 21 * sizeof (prdirent_t), sizeof (prdirent_t),
159 "fd" },
160 { PR_FDINFODIR, 22 * sizeof (prdirent_t), sizeof (prdirent_t),
161 "fdinfo" },
162 { PR_OBJECTDIR, 23 * sizeof (prdirent_t), sizeof (prdirent_t),
163 "object" },
164 { PR_LWPDIR, 24 * sizeof (prdirent_t), sizeof (prdirent_t),
165 "lwp" },
166 { PR_PRIV, 25 * sizeof (prdirent_t), sizeof (prdirent_t),
167 "priv" },
168 { PR_PATHDIR, 26 * sizeof (prdirent_t), sizeof (prdirent_t),
169 "path" },
170 { PR_CTDIR, 27 * sizeof (prdirent_t), sizeof (prdirent_t),
171 "contracts" },
172 { PR_SECFLAGS, 28 * sizeof (prdirent_t), sizeof (prdirent_t),
173 "secflags" },
174 #if defined(__x86)
175 { PR_LDT, 29 * sizeof (prdirent_t), sizeof (prdirent_t),
176 "ldt" },
177 #endif
178 };
179
180 #define NPIDDIRFILES (sizeof (piddir) / sizeof (piddir[0]) - 2)
181
182 /*
183 * Contents of a /proc/<pid>/lwp/<lwpid> directory.
184 */
185 static prdirent_t lwpiddir[] = {
186 { PR_LWPIDDIR, 1 * sizeof (prdirent_t), sizeof (prdirent_t),
187 "." },
188 { PR_LWPDIR, 2 * sizeof (prdirent_t), sizeof (prdirent_t),
189 ".." },
190 { PR_LWPCTL, 3 * sizeof (prdirent_t), sizeof (prdirent_t),
191 "lwpctl" },
192 { PR_LWPNAME, 4 * sizeof (prdirent_t), sizeof (prdirent_t),
193 "lwpname" },
194 { PR_LWPSTATUS, 5 * sizeof (prdirent_t), sizeof (prdirent_t),
195 "lwpstatus" },
196 { PR_LWPSINFO, 6 * sizeof (prdirent_t), sizeof (prdirent_t),
197 "lwpsinfo" },
198 { PR_LWPUSAGE, 7 * sizeof (prdirent_t), sizeof (prdirent_t),
199 "lwpusage" },
200 { PR_XREGS, 8 * sizeof (prdirent_t), sizeof (prdirent_t),
201 "xregs" },
202 { PR_TMPLDIR, 9 * sizeof (prdirent_t), sizeof (prdirent_t),
203 "templates" },
204 { PR_SPYMASTER, 10 * sizeof (prdirent_t), sizeof (prdirent_t),
205 "spymaster" },
206 #if defined(__sparc)
207 { PR_GWINDOWS, 11 * sizeof (prdirent_t), sizeof (prdirent_t),
208 "gwindows" },
209 { PR_ASRS, 12 * sizeof (prdirent_t), sizeof (prdirent_t),
210 "asrs" },
211 #endif
212 };
213
214 #define NLWPIDDIRFILES (sizeof (lwpiddir) / sizeof (lwpiddir[0]) - 2)
215
216 /*
217 * Span of entries in the array files (lstatus, lpsinfo, lusage).
218 * We make the span larger than the size of the structure on purpose,
219 * to make sure that programs cannot use the structure size by mistake.
220 * Align _ILP32 structures at 8 bytes, _LP64 structures at 16 bytes.
221 */
222 #ifdef _LP64
223 #define LSPAN(type) (round16(sizeof (type)) + 16)
224 #define LSPAN32(type) (round8(sizeof (type)) + 8)
225 #else
226 #define LSPAN(type) (round8(sizeof (type)) + 8)
227 #endif
228
229 static void rebuild_objdir(struct as *);
230 static void prfreecommon(prcommon_t *);
231 static int praccess(vnode_t *, int, int, cred_t *, caller_context_t *);
232
233 static int
propen(vnode_t ** vpp,int flag,cred_t * cr,caller_context_t * ct)234 propen(vnode_t **vpp, int flag, cred_t *cr, caller_context_t *ct)
235 {
236 vnode_t *vp = *vpp;
237 prnode_t *pnp = VTOP(vp);
238 prcommon_t *pcp = pnp->pr_pcommon;
239 prnodetype_t type = pnp->pr_type;
240 vnode_t *rvp;
241 vtype_t vtype;
242 proc_t *p;
243 int error = 0;
244 prnode_t *npnp = NULL;
245
246 /*
247 * Nothing to do for the /proc directory itself.
248 */
249 if (type == PR_PROCDIR)
250 return (0);
251
252 /*
253 * If we are opening an underlying mapped object, reject opens
254 * for writing regardless of the objects's access modes.
255 * If we are opening a file in the /proc/pid/fd directory,
256 * reject the open for any but a regular file or directory.
257 * Just do it if we are opening the current or root directory.
258 */
259 switch (type) {
260 case PR_OBJECT:
261 case PR_FD:
262 case PR_CURDIR:
263 case PR_ROOTDIR:
264 rvp = pnp->pr_realvp;
265 vtype = rvp->v_type;
266 if ((type == PR_OBJECT && (flag & FWRITE)) ||
267 (type == PR_FD && vtype != VREG && vtype != VDIR))
268 error = EACCES;
269 else {
270 /*
271 * Need to hold rvp since VOP_OPEN() may release it.
272 */
273 VN_HOLD(rvp);
274 error = VOP_OPEN(&rvp, flag, cr, ct);
275 if (error) {
276 VN_RELE(rvp);
277 } else {
278 *vpp = rvp;
279 VN_RELE(vp);
280 }
281 }
282 return (error);
283 default:
284 break;
285 }
286
287 /*
288 * If we are opening the pagedata file, allocate a prnode now
289 * to avoid calling kmem_alloc() while holding p->p_lock.
290 */
291 if (type == PR_PAGEDATA || type == PR_OPAGEDATA)
292 npnp = prgetnode(vp, type);
293
294 /*
295 * If the process exists, lock it now.
296 * Otherwise we have a race condition with prclose().
297 */
298 p = pr_p_lock(pnp);
299 mutex_exit(&pr_pidlock);
300 if (p == NULL) {
301 if (npnp != NULL)
302 prfreenode(npnp);
303 return (ENOENT);
304 }
305 ASSERT(p == pcp->prc_proc);
306 ASSERT(p->p_proc_flag & P_PR_LOCK);
307
308 /*
309 * Maintain a count of opens for write. Allow exactly one
310 * O_WRITE|O_EXCL request and fail subsequent ones.
311 * Don't fail opens of old (bletch!) /proc lwp files.
312 * Special case for open by the process itself:
313 * Always allow the open by self and discount this
314 * open for other opens for writing.
315 */
316 if (flag & FWRITE) {
317 if (p == curproc) {
318 pcp->prc_selfopens++;
319 pnp->pr_flags |= PR_ISSELF;
320 } else if (type == PR_LWPIDFILE) {
321 /* EMPTY */;
322 } else if (flag & FEXCL) {
323 if (pcp->prc_writers > pcp->prc_selfopens) {
324 error = EBUSY;
325 goto out;
326 }
327 /* semantic for old /proc interface */
328 if (type == PR_PIDDIR)
329 pcp->prc_flags |= PRC_EXCL;
330 } else if (pcp->prc_flags & PRC_EXCL) {
331 ASSERT(pcp->prc_writers > pcp->prc_selfopens);
332 error = secpolicy_proc_excl_open(cr);
333 if (error)
334 goto out;
335 }
336 pcp->prc_writers++;
337 /*
338 * The vnode may have become invalid between the
339 * VOP_LOOKUP() of the /proc vnode and the VOP_OPEN().
340 * If so, do now what prinvalidate() should have done.
341 */
342 if ((pnp->pr_flags & PR_INVAL) ||
343 (type == PR_PIDDIR &&
344 (VTOP(pnp->pr_pidfile)->pr_flags & PR_INVAL))) {
345 if (p != curproc)
346 pcp->prc_selfopens++;
347 ASSERT(pcp->prc_selfopens <= pcp->prc_writers);
348 if (pcp->prc_selfopens == pcp->prc_writers)
349 pcp->prc_flags &= ~PRC_EXCL;
350 }
351 }
352
353 /*
354 * If this is a large file open, indicate that in our flags -- some
355 * procfs structures are not off_t-neutral (e.g., priovec_t), and
356 * the open will need to be differentiated where 32-bit processes
357 * pass these structures across the user/kernel boundary.
358 */
359 if (flag & FOFFMAX)
360 pnp->pr_flags |= PR_OFFMAX;
361
362 /*
363 * Do file-specific things.
364 */
365 switch (type) {
366 default:
367 break;
368 case PR_PAGEDATA:
369 case PR_OPAGEDATA:
370 /*
371 * Enable data collection for page data file;
372 * get unique id from the hat layer.
373 */
374 {
375 int id;
376
377 /*
378 * Drop p->p_lock to call hat_startstat()
379 */
380 mutex_exit(&p->p_lock);
381 if ((p->p_flag & SSYS) || p->p_as == &kas ||
382 (id = hat_startstat(p->p_as)) == -1) {
383 mutex_enter(&p->p_lock);
384 error = ENOMEM;
385 } else if (pnp->pr_hatid == 0) {
386 mutex_enter(&p->p_lock);
387 pnp->pr_hatid = (uint_t)id;
388 } else {
389 mutex_enter(&p->p_lock);
390 /*
391 * Use our newly allocated prnode.
392 */
393 npnp->pr_hatid = (uint_t)id;
394 /*
395 * prgetnode() initialized most of the prnode.
396 * Duplicate the remainder.
397 */
398 npnp->pr_ino = pnp->pr_ino;
399 npnp->pr_common = pnp->pr_common;
400 npnp->pr_pcommon = pnp->pr_pcommon;
401 npnp->pr_parent = pnp->pr_parent;
402 VN_HOLD(npnp->pr_parent);
403 npnp->pr_index = pnp->pr_index;
404
405 npnp->pr_next = p->p_plist;
406 p->p_plist = PTOV(npnp);
407
408 VN_RELE(PTOV(pnp));
409 pnp = npnp;
410 npnp = NULL;
411 *vpp = PTOV(pnp);
412 }
413 }
414 break;
415 }
416
417 out:
418 prunlock(pnp);
419
420 if (npnp != NULL)
421 prfreenode(npnp);
422 return (error);
423 }
424
425 /* ARGSUSED */
426 static int
prclose(vnode_t * vp,int flag,int count,offset_t offset,cred_t * cr,caller_context_t * ct)427 prclose(vnode_t *vp, int flag, int count, offset_t offset, cred_t *cr,
428 caller_context_t *ct)
429 {
430 prnode_t *pnp = VTOP(vp);
431 prcommon_t *pcp = pnp->pr_pcommon;
432 prnodetype_t type = pnp->pr_type;
433 proc_t *p;
434 kthread_t *t;
435 user_t *up;
436
437 /*
438 * Nothing to do for the /proc directory itself.
439 */
440 if (type == PR_PROCDIR)
441 return (0);
442
443 ASSERT(type != PR_OBJECT && type != PR_FD &&
444 type != PR_CURDIR && type != PR_ROOTDIR);
445
446 /*
447 * If the process exists, lock it now.
448 * Otherwise we have a race condition with propen().
449 * Hold pr_pidlock across the reference to prc_selfopens,
450 * and prc_writers in case there is no process anymore,
451 * to cover the case of concurrent calls to prclose()
452 * after the process has been reaped by freeproc().
453 */
454 p = pr_p_lock(pnp);
455
456 /*
457 * There is nothing more to do until the last close of
458 * the file table entry except to clear the pr_owner
459 * field of the prnode and notify any waiters
460 * (their file descriptor may have just been closed).
461 */
462 if (count > 1) {
463 mutex_exit(&pr_pidlock);
464 if (pnp->pr_owner == curproc && !fisopen(vp))
465 pnp->pr_owner = NULL;
466 if (p != NULL) {
467 prnotify(vp);
468 prunlock(pnp);
469 }
470 return (0);
471 }
472
473 /*
474 * Decrement the count of self-opens for writing.
475 * Decrement the total count of opens for writing.
476 * Cancel exclusive opens when only self-opens remain.
477 */
478 if (flag & FWRITE) {
479 /*
480 * prc_selfopens also contains the count of
481 * invalid writers. See prinvalidate().
482 */
483 if ((pnp->pr_flags & (PR_ISSELF|PR_INVAL)) ||
484 (type == PR_PIDDIR &&
485 (VTOP(pnp->pr_pidfile)->pr_flags & PR_INVAL))) {
486 ASSERT(pcp->prc_selfopens != 0);
487 --pcp->prc_selfopens;
488 }
489 ASSERT(pcp->prc_writers != 0);
490 if (--pcp->prc_writers == pcp->prc_selfopens)
491 pcp->prc_flags &= ~PRC_EXCL;
492 }
493 ASSERT(pcp->prc_writers >= pcp->prc_selfopens);
494 mutex_exit(&pr_pidlock);
495 if (pnp->pr_owner == curproc && !fisopen(vp))
496 pnp->pr_owner = NULL;
497
498 /*
499 * If there is no process, there is nothing more to do.
500 */
501 if (p == NULL)
502 return (0);
503
504 ASSERT(p == pcp->prc_proc);
505 prnotify(vp); /* notify waiters */
506
507 /*
508 * Do file-specific things.
509 */
510 switch (type) {
511 default:
512 break;
513 case PR_PAGEDATA:
514 case PR_OPAGEDATA:
515 /*
516 * This is a page data file.
517 * Free the hat level statistics.
518 * Drop p->p_lock before calling hat_freestat().
519 */
520 mutex_exit(&p->p_lock);
521 if (p->p_as != &kas && pnp->pr_hatid != 0)
522 hat_freestat(p->p_as, pnp->pr_hatid);
523 mutex_enter(&p->p_lock);
524 pnp->pr_hatid = 0;
525 break;
526 }
527
528 /*
529 * On last close of all writable file descriptors,
530 * perform run-on-last-close and/or kill-on-last-close logic.
531 * Can't do this is the /proc agent lwp still exists.
532 */
533 if (pcp->prc_writers == 0 &&
534 p->p_agenttp == NULL &&
535 !(pcp->prc_flags & PRC_DESTROY) &&
536 p->p_stat != SZOMB &&
537 (p->p_proc_flag & (P_PR_RUNLCL|P_PR_KILLCL))) {
538 int killproc;
539
540 /*
541 * Cancel any watchpoints currently in effect.
542 * The process might disappear during this operation.
543 */
544 if (pr_cancel_watch(pnp) == NULL)
545 return (0);
546 /*
547 * If any tracing flags are set, clear them.
548 */
549 if (p->p_proc_flag & P_PR_TRACE) {
550 up = PTOU(p);
551 premptyset(&up->u_entrymask);
552 premptyset(&up->u_exitmask);
553 up->u_systrap = 0;
554 }
555 premptyset(&p->p_sigmask);
556 premptyset(&p->p_fltmask);
557 killproc = (p->p_proc_flag & P_PR_KILLCL);
558 p->p_proc_flag &= ~(P_PR_RUNLCL|P_PR_KILLCL|P_PR_TRACE);
559 /*
560 * Cancel any outstanding single-step requests.
561 */
562 if ((t = p->p_tlist) != NULL) {
563 /*
564 * Drop p_lock because prnostep() touches the stack.
565 * The loop is safe because the process is P_PR_LOCK'd.
566 */
567 mutex_exit(&p->p_lock);
568 do {
569 prnostep(ttolwp(t));
570 } while ((t = t->t_forw) != p->p_tlist);
571 mutex_enter(&p->p_lock);
572 }
573 /*
574 * Set runnable all lwps stopped by /proc.
575 */
576 if (killproc)
577 sigtoproc(p, NULL, SIGKILL);
578 else
579 allsetrun(p);
580 }
581
582 prunlock(pnp);
583 return (0);
584 }
585
586 /*
587 * Array of read functions, indexed by /proc file type.
588 */
589 static int pr_read_inval(), pr_read_as(), pr_read_status(),
590 pr_read_lstatus(), pr_read_psinfo(), pr_read_lpsinfo(),
591 pr_read_map(), pr_read_rmap(), pr_read_xmap(),
592 pr_read_cred(), pr_read_sigact(), pr_read_auxv(),
593 #if defined(__x86)
594 pr_read_ldt(),
595 #endif
596 pr_read_usage(), pr_read_lusage(), pr_read_pagedata(),
597 pr_read_watch(), pr_read_lwpstatus(), pr_read_lwpsinfo(),
598 pr_read_lwpusage(), pr_read_lwpname(),
599 pr_read_xregs(), pr_read_priv(),
600 pr_read_spymaster(), pr_read_secflags(),
601 #if defined(__sparc)
602 pr_read_gwindows(), pr_read_asrs(),
603 #endif
604 pr_read_piddir(), pr_read_pidfile(), pr_read_opagedata(),
605 pr_read_fdinfo();
606
607 static int (*pr_read_function[PR_NFILES])() = {
608 pr_read_inval, /* /proc */
609 pr_read_inval, /* /proc/self */
610 pr_read_piddir, /* /proc/<pid> (old /proc read()) */
611 pr_read_as, /* /proc/<pid>/as */
612 pr_read_inval, /* /proc/<pid>/ctl */
613 pr_read_status, /* /proc/<pid>/status */
614 pr_read_lstatus, /* /proc/<pid>/lstatus */
615 pr_read_psinfo, /* /proc/<pid>/psinfo */
616 pr_read_lpsinfo, /* /proc/<pid>/lpsinfo */
617 pr_read_map, /* /proc/<pid>/map */
618 pr_read_rmap, /* /proc/<pid>/rmap */
619 pr_read_xmap, /* /proc/<pid>/xmap */
620 pr_read_cred, /* /proc/<pid>/cred */
621 pr_read_sigact, /* /proc/<pid>/sigact */
622 pr_read_auxv, /* /proc/<pid>/auxv */
623 #if defined(__x86)
624 pr_read_ldt, /* /proc/<pid>/ldt */
625 #endif
626 pr_read_usage, /* /proc/<pid>/usage */
627 pr_read_lusage, /* /proc/<pid>/lusage */
628 pr_read_pagedata, /* /proc/<pid>/pagedata */
629 pr_read_watch, /* /proc/<pid>/watch */
630 pr_read_inval, /* /proc/<pid>/cwd */
631 pr_read_inval, /* /proc/<pid>/root */
632 pr_read_inval, /* /proc/<pid>/fd */
633 pr_read_inval, /* /proc/<pid>/fd/nn */
634 pr_read_inval, /* /proc/<pid>/fdinfo */
635 pr_read_fdinfo, /* /proc/<pid>/fdinfo/nn */
636 pr_read_inval, /* /proc/<pid>/object */
637 pr_read_inval, /* /proc/<pid>/object/xxx */
638 pr_read_inval, /* /proc/<pid>/lwp */
639 pr_read_inval, /* /proc/<pid>/lwp/<lwpid> */
640 pr_read_inval, /* /proc/<pid>/lwp/<lwpid>/lwpctl */
641 pr_read_lwpname, /* /proc/<pid>/lwp/<lwpid>/lwpname */
642 pr_read_lwpstatus, /* /proc/<pid>/lwp/<lwpid>/lwpstatus */
643 pr_read_lwpsinfo, /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
644 pr_read_lwpusage, /* /proc/<pid>/lwp/<lwpid>/lwpusage */
645 pr_read_xregs, /* /proc/<pid>/lwp/<lwpid>/xregs */
646 pr_read_inval, /* /proc/<pid>/lwp/<lwpid>/templates */
647 pr_read_inval, /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
648 pr_read_spymaster, /* /proc/<pid>/lwp/<lwpid>/spymaster */
649 #if defined(__sparc)
650 pr_read_gwindows, /* /proc/<pid>/lwp/<lwpid>/gwindows */
651 pr_read_asrs, /* /proc/<pid>/lwp/<lwpid>/asrs */
652 #endif
653 pr_read_priv, /* /proc/<pid>/priv */
654 pr_read_inval, /* /proc/<pid>/path */
655 pr_read_inval, /* /proc/<pid>/path/xxx */
656 pr_read_inval, /* /proc/<pid>/contracts */
657 pr_read_inval, /* /proc/<pid>/contracts/<ctid> */
658 pr_read_secflags, /* /proc/<pid>/secflags */
659 pr_read_pidfile, /* old process file */
660 pr_read_pidfile, /* old lwp file */
661 pr_read_opagedata, /* old pagedata file */
662 };
663
664 /* ARGSUSED */
665 static int
pr_read_inval(prnode_t * pnp,uio_t * uiop,cred_t * cr)666 pr_read_inval(prnode_t *pnp, uio_t *uiop, cred_t *cr)
667 {
668 /*
669 * No read() on any /proc directory, use getdents(2) instead.
670 * Cannot read a control file either.
671 * An underlying mapped object file cannot get here.
672 */
673 return (EINVAL);
674 }
675
676 static int
pr_uioread(void * base,long count,uio_t * uiop)677 pr_uioread(void *base, long count, uio_t *uiop)
678 {
679 int error = 0;
680
681 ASSERT(count >= 0);
682 count -= uiop->uio_offset;
683 if (count > 0 && uiop->uio_offset >= 0) {
684 error = uiomove((char *)base + uiop->uio_offset,
685 count, UIO_READ, uiop);
686 }
687
688 return (error);
689 }
690
691 static int
pr_read_as(prnode_t * pnp,uio_t * uiop)692 pr_read_as(prnode_t *pnp, uio_t *uiop)
693 {
694 int error;
695
696 ASSERT(pnp->pr_type == PR_AS);
697
698 if ((error = prlock(pnp, ZNO)) == 0) {
699 proc_t *p = pnp->pr_common->prc_proc;
700 struct as *as = p->p_as;
701
702 /*
703 * /proc I/O cannot be done to a system process.
704 * A 32-bit process cannot read a 64-bit process.
705 */
706 if ((p->p_flag & SSYS) || as == &kas) {
707 error = 0;
708 #ifdef _SYSCALL32_IMPL
709 } else if (curproc->p_model == DATAMODEL_ILP32 &&
710 PROCESS_NOT_32BIT(p)) {
711 error = EOVERFLOW;
712 #endif
713 } else {
714 /*
715 * We don't hold p_lock over an i/o operation because
716 * that could lead to deadlock with the clock thread.
717 */
718 mutex_exit(&p->p_lock);
719 error = prusrio(p, UIO_READ, uiop, 0);
720 mutex_enter(&p->p_lock);
721 }
722 prunlock(pnp);
723 }
724
725 return (error);
726 }
727
728 static int
pr_read_status(prnode_t * pnp,uio_t * uiop,cred_t * cr)729 pr_read_status(prnode_t *pnp, uio_t *uiop, cred_t *cr)
730 {
731 pstatus_t *sp;
732 int error;
733
734 ASSERT(pnp->pr_type == PR_STATUS);
735
736 /*
737 * We kmem_alloc() the pstatus structure because
738 * it is so big it might blow the kernel stack.
739 */
740 sp = kmem_alloc(sizeof (*sp), KM_SLEEP);
741 if ((error = prlock(pnp, ZNO)) == 0) {
742 prgetstatus(pnp->pr_common->prc_proc, sp, VTOZONE(PTOV(pnp)));
743 prunlock(pnp);
744 error = pr_uioread(sp, sizeof (*sp), uiop);
745 }
746 kmem_free(sp, sizeof (*sp));
747 return (error);
748 }
749
750 static int
pr_read_lstatus(prnode_t * pnp,uio_t * uiop,cred_t * cr)751 pr_read_lstatus(prnode_t *pnp, uio_t *uiop, cred_t *cr)
752 {
753 proc_t *p;
754 kthread_t *t;
755 lwpdir_t *ldp;
756 size_t size;
757 prheader_t *php;
758 lwpstatus_t *sp;
759 int error;
760 int nlwp;
761 int i;
762
763 ASSERT(pnp->pr_type == PR_LSTATUS);
764
765 if ((error = prlock(pnp, ZNO)) != 0)
766 return (error);
767 p = pnp->pr_common->prc_proc;
768 nlwp = p->p_lwpcnt;
769 size = sizeof (prheader_t) + nlwp * LSPAN(lwpstatus_t);
770
771 /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
772 mutex_exit(&p->p_lock);
773 php = kmem_zalloc(size, KM_SLEEP);
774 mutex_enter(&p->p_lock);
775 /* p->p_lwpcnt can't change while process is locked */
776 ASSERT(nlwp == p->p_lwpcnt);
777
778 php->pr_nent = nlwp;
779 php->pr_entsize = LSPAN(lwpstatus_t);
780
781 sp = (lwpstatus_t *)(php + 1);
782 for (ldp = p->p_lwpdir, i = 0; i < p->p_lwpdir_sz; i++, ldp++) {
783 if (ldp->ld_entry == NULL ||
784 (t = ldp->ld_entry->le_thread) == NULL)
785 continue;
786 prgetlwpstatus(t, sp, VTOZONE(PTOV(pnp)));
787 sp = (lwpstatus_t *)((caddr_t)sp + LSPAN(lwpstatus_t));
788 }
789 prunlock(pnp);
790
791 error = pr_uioread(php, size, uiop);
792 kmem_free(php, size);
793 return (error);
794 }
795
796 static int
pr_read_psinfo(prnode_t * pnp,uio_t * uiop,cred_t * cr)797 pr_read_psinfo(prnode_t *pnp, uio_t *uiop, cred_t *cr)
798 {
799 psinfo_t psinfo;
800 proc_t *p;
801 int error = 0;
802
803 ASSERT(pnp->pr_type == PR_PSINFO);
804
805 /*
806 * We don't want the full treatment of prlock(pnp) here.
807 * This file is world-readable and never goes invalid.
808 * It doesn't matter if we are in the middle of an exec().
809 */
810 p = pr_p_lock(pnp);
811 mutex_exit(&pr_pidlock);
812 if (p == NULL)
813 error = ENOENT;
814 else {
815 ASSERT(p == pnp->pr_common->prc_proc);
816 prgetpsinfo(p, &psinfo);
817 prunlock(pnp);
818 error = pr_uioread(&psinfo, sizeof (psinfo), uiop);
819 }
820 return (error);
821 }
822
823 static int
pr_read_fdinfo(prnode_t * pnp,uio_t * uiop,cred_t * cr)824 pr_read_fdinfo(prnode_t *pnp, uio_t *uiop, cred_t *cr)
825 {
826 prfdinfo_t *fdinfo;
827 list_t data;
828 proc_t *p;
829 uint_t fd;
830 file_t *fp;
831 short ufp_flag;
832 int error = 0;
833
834 ASSERT(pnp->pr_type == PR_FDINFO);
835
836 /*
837 * This is a guess at the size of the structure that needs to
838 * be returned. It's a balance between not allocating too much more
839 * space than is required and not requiring too many subsequent
840 * reallocations. Allocate it before acquiring the process lock.
841 */
842 pr_iol_initlist(&data, sizeof (prfdinfo_t) + MAXPATHLEN + 2, 1);
843
844 if ((error = prlock(pnp, ZNO)) != 0) {
845 pr_iol_freelist(&data);
846 return (error);
847 }
848
849 p = pnp->pr_common->prc_proc;
850
851 if ((p->p_flag & SSYS) || p->p_as == &kas) {
852 prunlock(pnp);
853 pr_iol_freelist(&data);
854 return (0);
855 }
856
857 fd = pnp->pr_index;
858
859 /* Fetch and lock the file_t for this descriptor */
860 fp = pr_getf(p, fd, &ufp_flag);
861
862 if (fp == NULL) {
863 error = ENOENT;
864 prunlock(pnp);
865 goto out;
866 }
867
868 /*
869 * For fdinfo, we don't want to include the placeholder pr_misc at the
870 * end of the struct. We'll terminate the data with an empty pr_misc
871 * header before returning.
872 */
873
874 fdinfo = pr_iol_newbuf(&data, offsetof(prfdinfo_t, pr_misc));
875 fdinfo->pr_fd = fd;
876 fdinfo->pr_fdflags = ufp_flag;
877 fdinfo->pr_fileflags = fp->f_flag2 << 16 | fp->f_flag;
878 if ((fdinfo->pr_fileflags & (FSEARCH | FEXEC)) == 0)
879 fdinfo->pr_fileflags += FOPEN;
880 fdinfo->pr_offset = fp->f_offset;
881 /*
882 * Information from the vnode (rather than the file_t) is retrieved
883 * later, in prgetfdinfo() - for example sock_getfasync()
884 */
885
886 prunlock(pnp);
887
888 error = prgetfdinfo(p, fp->f_vnode, fdinfo, cr, fp->f_cred, &data);
889
890 pr_releasef(fp);
891
892 out:
893 if (error == 0)
894 error = pr_iol_uiomove_and_free(&data, uiop, error);
895 else
896 pr_iol_freelist(&data);
897
898 return (error);
899 }
900
901 static int
pr_read_lpsinfo(prnode_t * pnp,uio_t * uiop,cred_t * cr)902 pr_read_lpsinfo(prnode_t *pnp, uio_t *uiop, cred_t *cr)
903 {
904 proc_t *p;
905 kthread_t *t;
906 lwpdir_t *ldp;
907 lwpent_t *lep;
908 size_t size;
909 prheader_t *php;
910 lwpsinfo_t *sp;
911 int error;
912 int nlwp;
913 int i;
914
915 ASSERT(pnp->pr_type == PR_LPSINFO);
916
917 /*
918 * We don't want the full treatment of prlock(pnp) here.
919 * This file is world-readable and never goes invalid.
920 * It doesn't matter if we are in the middle of an exec().
921 */
922 p = pr_p_lock(pnp);
923 mutex_exit(&pr_pidlock);
924 if (p == NULL)
925 return (ENOENT);
926 ASSERT(p == pnp->pr_common->prc_proc);
927 if ((nlwp = p->p_lwpcnt + p->p_zombcnt) == 0) {
928 prunlock(pnp);
929 return (ENOENT);
930 }
931 size = sizeof (prheader_t) + nlwp * LSPAN(lwpsinfo_t);
932
933 /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
934 mutex_exit(&p->p_lock);
935 php = kmem_zalloc(size, KM_SLEEP);
936 mutex_enter(&p->p_lock);
937 /* p->p_lwpcnt can't change while process is locked */
938 ASSERT(nlwp == p->p_lwpcnt + p->p_zombcnt);
939
940 php->pr_nent = nlwp;
941 php->pr_entsize = LSPAN(lwpsinfo_t);
942
943 sp = (lwpsinfo_t *)(php + 1);
944 for (ldp = p->p_lwpdir, i = 0; i < p->p_lwpdir_sz; i++, ldp++) {
945 if ((lep = ldp->ld_entry) == NULL)
946 continue;
947 if ((t = lep->le_thread) != NULL)
948 prgetlwpsinfo(t, sp);
949 else {
950 bzero(sp, sizeof (*sp));
951 sp->pr_lwpid = lep->le_lwpid;
952 sp->pr_state = SZOMB;
953 sp->pr_sname = 'Z';
954 sp->pr_start.tv_sec = lep->le_start;
955 sp->pr_bindpro = PBIND_NONE;
956 sp->pr_bindpset = PS_NONE;
957 }
958 sp = (lwpsinfo_t *)((caddr_t)sp + LSPAN(lwpsinfo_t));
959 }
960 prunlock(pnp);
961
962 error = pr_uioread(php, size, uiop);
963 kmem_free(php, size);
964 return (error);
965 }
966
967 static int
pr_read_map_common(prnode_t * pnp,uio_t * uiop,prnodetype_t type)968 pr_read_map_common(prnode_t *pnp, uio_t *uiop, prnodetype_t type)
969 {
970 proc_t *p;
971 struct as *as;
972 list_t iolhead;
973 int error;
974
975 readmap_common:
976 if ((error = prlock(pnp, ZNO)) != 0)
977 return (error);
978
979 p = pnp->pr_common->prc_proc;
980 as = p->p_as;
981
982 if ((p->p_flag & SSYS) || as == &kas) {
983 prunlock(pnp);
984 return (0);
985 }
986
987 if (!AS_LOCK_TRYENTER(as, RW_WRITER)) {
988 prunlock(pnp);
989 delay(1);
990 goto readmap_common;
991 }
992 mutex_exit(&p->p_lock);
993
994 switch (type) {
995 case PR_XMAP:
996 error = prgetxmap(p, &iolhead);
997 break;
998 case PR_RMAP:
999 error = prgetmap(p, 1, &iolhead);
1000 break;
1001 case PR_MAP:
1002 error = prgetmap(p, 0, &iolhead);
1003 break;
1004 }
1005
1006 AS_LOCK_EXIT(as);
1007 mutex_enter(&p->p_lock);
1008 prunlock(pnp);
1009
1010 error = pr_iol_uiomove_and_free(&iolhead, uiop, error);
1011
1012 return (error);
1013 }
1014
1015 static int
pr_read_map(prnode_t * pnp,uio_t * uiop,cred_t * cr)1016 pr_read_map(prnode_t *pnp, uio_t *uiop, cred_t *cr)
1017 {
1018 ASSERT(pnp->pr_type == PR_MAP);
1019 return (pr_read_map_common(pnp, uiop, pnp->pr_type));
1020 }
1021
1022 static int
pr_read_rmap(prnode_t * pnp,uio_t * uiop,cred_t * cr)1023 pr_read_rmap(prnode_t *pnp, uio_t *uiop, cred_t *cr)
1024 {
1025 ASSERT(pnp->pr_type == PR_RMAP);
1026 return (pr_read_map_common(pnp, uiop, pnp->pr_type));
1027 }
1028
1029 static int
pr_read_xmap(prnode_t * pnp,uio_t * uiop,cred_t * cr)1030 pr_read_xmap(prnode_t *pnp, uio_t *uiop, cred_t *cr)
1031 {
1032 ASSERT(pnp->pr_type == PR_XMAP);
1033 return (pr_read_map_common(pnp, uiop, pnp->pr_type));
1034 }
1035
1036 static int
pr_read_cred(prnode_t * pnp,uio_t * uiop,cred_t * cr)1037 pr_read_cred(prnode_t *pnp, uio_t *uiop, cred_t *cr)
1038 {
1039 proc_t *p;
1040 prcred_t *pcrp;
1041 int error;
1042 size_t count;
1043
1044 ASSERT(pnp->pr_type == PR_CRED);
1045
1046 /*
1047 * We kmem_alloc() the prcred_t structure because
1048 * the number of supplementary groups is variable.
1049 */
1050 pcrp =
1051 kmem_zalloc(sizeof (prcred_t) + sizeof (gid_t) * (ngroups_max - 1),
1052 KM_SLEEP);
1053
1054 if ((error = prlock(pnp, ZNO)) != 0)
1055 goto out;
1056 p = pnp->pr_common->prc_proc;
1057 ASSERT(p != NULL);
1058
1059 prgetcred(p, pcrp);
1060 prunlock(pnp);
1061
1062 count = sizeof (prcred_t);
1063 if (pcrp->pr_ngroups > 1)
1064 count += sizeof (gid_t) * (pcrp->pr_ngroups - 1);
1065 error = pr_uioread(pcrp, count, uiop);
1066 out:
1067 kmem_free(pcrp, sizeof (prcred_t) + sizeof (gid_t) * (ngroups_max - 1));
1068 return (error);
1069 }
1070
1071 static int
pr_read_priv(prnode_t * pnp,uio_t * uiop,cred_t * cr)1072 pr_read_priv(prnode_t *pnp, uio_t *uiop, cred_t *cr)
1073 {
1074 proc_t *p;
1075 size_t psize = prgetprivsize();
1076 prpriv_t *ppriv = kmem_zalloc(psize, KM_SLEEP);
1077 int error;
1078
1079 ASSERT(pnp->pr_type == PR_PRIV);
1080
1081 if ((error = prlock(pnp, ZNO)) != 0)
1082 goto out;
1083 p = pnp->pr_common->prc_proc;
1084 ASSERT(p != NULL);
1085
1086 prgetpriv(p, ppriv);
1087 prunlock(pnp);
1088
1089 error = pr_uioread(ppriv, psize, uiop);
1090 out:
1091 kmem_free(ppriv, psize);
1092 return (error);
1093 }
1094
1095 static int
pr_read_sigact(prnode_t * pnp,uio_t * uiop,cred_t * cr)1096 pr_read_sigact(prnode_t *pnp, uio_t *uiop, cred_t *cr)
1097 {
1098 int nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG;
1099 proc_t *p;
1100 struct sigaction *sap;
1101 int sig;
1102 int error;
1103 user_t *up;
1104
1105 ASSERT(pnp->pr_type == PR_SIGACT);
1106
1107 /*
1108 * We kmem_alloc() the sigaction array because
1109 * it is so big it might blow the kernel stack.
1110 */
1111 sap = kmem_alloc((nsig-1) * sizeof (struct sigaction), KM_SLEEP);
1112
1113 if ((error = prlock(pnp, ZNO)) != 0)
1114 goto out;
1115 p = pnp->pr_common->prc_proc;
1116 ASSERT(p != NULL);
1117
1118 if (uiop->uio_offset >= (nsig-1)*sizeof (struct sigaction)) {
1119 prunlock(pnp);
1120 goto out;
1121 }
1122
1123 up = PTOU(p);
1124 for (sig = 1; sig < nsig; sig++)
1125 prgetaction(p, up, sig, &sap[sig-1]);
1126 prunlock(pnp);
1127
1128 error = pr_uioread(sap, (nsig - 1) * sizeof (struct sigaction), uiop);
1129 out:
1130 kmem_free(sap, (nsig-1) * sizeof (struct sigaction));
1131 return (error);
1132 }
1133
1134 static int
pr_read_auxv(prnode_t * pnp,uio_t * uiop,cred_t * cr)1135 pr_read_auxv(prnode_t *pnp, uio_t *uiop, cred_t *cr)
1136 {
1137 auxv_t auxv[__KERN_NAUXV_IMPL];
1138 proc_t *p;
1139 user_t *up;
1140 int error;
1141
1142 ASSERT(pnp->pr_type == PR_AUXV);
1143
1144 if ((error = prlock(pnp, ZNO)) != 0)
1145 return (error);
1146
1147 if (uiop->uio_offset >= sizeof (auxv)) {
1148 prunlock(pnp);
1149 return (0);
1150 }
1151
1152 p = pnp->pr_common->prc_proc;
1153 up = PTOU(p);
1154 bcopy(up->u_auxv, auxv, sizeof (auxv));
1155 prunlock(pnp);
1156
1157 return (pr_uioread(auxv, sizeof (auxv), uiop));
1158 }
1159
1160 #if defined(__x86)
1161 /*
1162 * XX64
1163 * This is almost certainly broken for the amd64 kernel, because
1164 * we have two kinds of LDT structures to export -- one for compatibility
1165 * mode, and one for long mode, sigh.
1166 *
1167 * For now let's just have a ldt of size 0 for 64-bit processes.
1168 */
1169 static int
pr_read_ldt(prnode_t * pnp,uio_t * uiop,cred_t * cr)1170 pr_read_ldt(prnode_t *pnp, uio_t *uiop, cred_t *cr)
1171 {
1172 proc_t *p;
1173 struct ssd *ssd;
1174 size_t size;
1175 int error;
1176
1177 ASSERT(pnp->pr_type == PR_LDT);
1178
1179 if ((error = prlock(pnp, ZNO)) != 0)
1180 return (error);
1181 p = pnp->pr_common->prc_proc;
1182
1183 mutex_exit(&p->p_lock);
1184 mutex_enter(&p->p_ldtlock);
1185 size = prnldt(p) * sizeof (struct ssd);
1186 if (uiop->uio_offset >= size) {
1187 mutex_exit(&p->p_ldtlock);
1188 mutex_enter(&p->p_lock);
1189 prunlock(pnp);
1190 return (0);
1191 }
1192
1193 ssd = kmem_alloc(size, KM_SLEEP);
1194 prgetldt(p, ssd);
1195 mutex_exit(&p->p_ldtlock);
1196 mutex_enter(&p->p_lock);
1197 prunlock(pnp);
1198
1199 error = pr_uioread(ssd, size, uiop);
1200 kmem_free(ssd, size);
1201 return (error);
1202 }
1203 #endif /* __x86 */
1204
1205 static int
pr_read_usage(prnode_t * pnp,uio_t * uiop,cred_t * cr)1206 pr_read_usage(prnode_t *pnp, uio_t *uiop, cred_t *cr)
1207 {
1208 prhusage_t *pup;
1209 prusage_t *upup;
1210 proc_t *p;
1211 kthread_t *t;
1212 int error;
1213
1214 ASSERT(pnp->pr_type == PR_USAGE);
1215
1216 /* allocate now, before locking the process */
1217 pup = kmem_zalloc(sizeof (*pup), KM_SLEEP);
1218 upup = kmem_alloc(sizeof (*upup), KM_SLEEP);
1219
1220 /*
1221 * We don't want the full treatment of prlock(pnp) here.
1222 * This file is world-readable and never goes invalid.
1223 * It doesn't matter if we are in the middle of an exec().
1224 */
1225 p = pr_p_lock(pnp);
1226 mutex_exit(&pr_pidlock);
1227 if (p == NULL) {
1228 error = ENOENT;
1229 goto out;
1230 }
1231 ASSERT(p == pnp->pr_common->prc_proc);
1232
1233 if (uiop->uio_offset >= sizeof (prusage_t)) {
1234 prunlock(pnp);
1235 error = 0;
1236 goto out;
1237 }
1238
1239 pup->pr_tstamp = gethrtime();
1240
1241 pup->pr_count = p->p_defunct;
1242 pup->pr_create = p->p_mstart;
1243 pup->pr_term = p->p_mterm;
1244
1245 pup->pr_rtime = p->p_mlreal;
1246 pup->pr_utime = p->p_acct[LMS_USER];
1247 pup->pr_stime = p->p_acct[LMS_SYSTEM];
1248 pup->pr_ttime = p->p_acct[LMS_TRAP];
1249 pup->pr_tftime = p->p_acct[LMS_TFAULT];
1250 pup->pr_dftime = p->p_acct[LMS_DFAULT];
1251 pup->pr_kftime = p->p_acct[LMS_KFAULT];
1252 pup->pr_ltime = p->p_acct[LMS_USER_LOCK];
1253 pup->pr_slptime = p->p_acct[LMS_SLEEP];
1254 pup->pr_wtime = p->p_acct[LMS_WAIT_CPU];
1255 pup->pr_stoptime = p->p_acct[LMS_STOPPED];
1256
1257 pup->pr_minf = p->p_ru.minflt;
1258 pup->pr_majf = p->p_ru.majflt;
1259 pup->pr_nswap = p->p_ru.nswap;
1260 pup->pr_inblk = p->p_ru.inblock;
1261 pup->pr_oublk = p->p_ru.oublock;
1262 pup->pr_msnd = p->p_ru.msgsnd;
1263 pup->pr_mrcv = p->p_ru.msgrcv;
1264 pup->pr_sigs = p->p_ru.nsignals;
1265 pup->pr_vctx = p->p_ru.nvcsw;
1266 pup->pr_ictx = p->p_ru.nivcsw;
1267 pup->pr_sysc = p->p_ru.sysc;
1268 pup->pr_ioch = p->p_ru.ioch;
1269
1270 /*
1271 * Add the usage information for each active lwp.
1272 */
1273 if ((t = p->p_tlist) != NULL &&
1274 !(pnp->pr_pcommon->prc_flags & PRC_DESTROY)) {
1275 do {
1276 if (t->t_proc_flag & TP_LWPEXIT)
1277 continue;
1278 pup->pr_count++;
1279 praddusage(t, pup);
1280 } while ((t = t->t_forw) != p->p_tlist);
1281 }
1282
1283 prunlock(pnp);
1284
1285 prcvtusage(pup, upup);
1286
1287 error = pr_uioread(upup, sizeof (prusage_t), uiop);
1288 out:
1289 kmem_free(pup, sizeof (*pup));
1290 kmem_free(upup, sizeof (*upup));
1291 return (error);
1292 }
1293
1294 static int
pr_read_lusage(prnode_t * pnp,uio_t * uiop,cred_t * cr)1295 pr_read_lusage(prnode_t *pnp, uio_t *uiop, cred_t *cr)
1296 {
1297 int nlwp;
1298 prhusage_t *pup;
1299 prheader_t *php;
1300 prusage_t *upup;
1301 size_t size;
1302 hrtime_t curtime;
1303 proc_t *p;
1304 kthread_t *t;
1305 lwpdir_t *ldp;
1306 int error;
1307 int i;
1308
1309 ASSERT(pnp->pr_type == PR_LUSAGE);
1310
1311 /*
1312 * We don't want the full treatment of prlock(pnp) here.
1313 * This file is world-readable and never goes invalid.
1314 * It doesn't matter if we are in the middle of an exec().
1315 */
1316 p = pr_p_lock(pnp);
1317 mutex_exit(&pr_pidlock);
1318 if (p == NULL)
1319 return (ENOENT);
1320 ASSERT(p == pnp->pr_common->prc_proc);
1321 if ((nlwp = p->p_lwpcnt) == 0) {
1322 prunlock(pnp);
1323 return (ENOENT);
1324 }
1325
1326 size = sizeof (prheader_t) + (nlwp + 1) * LSPAN(prusage_t);
1327 if (uiop->uio_offset >= size) {
1328 prunlock(pnp);
1329 return (0);
1330 }
1331
1332 /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
1333 mutex_exit(&p->p_lock);
1334 pup = kmem_zalloc(size + sizeof (prhusage_t), KM_SLEEP);
1335 mutex_enter(&p->p_lock);
1336 /* p->p_lwpcnt can't change while process is locked */
1337 ASSERT(nlwp == p->p_lwpcnt);
1338
1339 php = (prheader_t *)(pup + 1);
1340 upup = (prusage_t *)(php + 1);
1341
1342 php->pr_nent = nlwp + 1;
1343 php->pr_entsize = LSPAN(prusage_t);
1344
1345 curtime = gethrtime();
1346
1347 /*
1348 * First the summation over defunct lwps.
1349 */
1350 pup->pr_count = p->p_defunct;
1351 pup->pr_tstamp = curtime;
1352 pup->pr_create = p->p_mstart;
1353 pup->pr_term = p->p_mterm;
1354
1355 pup->pr_rtime = p->p_mlreal;
1356 pup->pr_utime = p->p_acct[LMS_USER];
1357 pup->pr_stime = p->p_acct[LMS_SYSTEM];
1358 pup->pr_ttime = p->p_acct[LMS_TRAP];
1359 pup->pr_tftime = p->p_acct[LMS_TFAULT];
1360 pup->pr_dftime = p->p_acct[LMS_DFAULT];
1361 pup->pr_kftime = p->p_acct[LMS_KFAULT];
1362 pup->pr_ltime = p->p_acct[LMS_USER_LOCK];
1363 pup->pr_slptime = p->p_acct[LMS_SLEEP];
1364 pup->pr_wtime = p->p_acct[LMS_WAIT_CPU];
1365 pup->pr_stoptime = p->p_acct[LMS_STOPPED];
1366
1367 pup->pr_minf = p->p_ru.minflt;
1368 pup->pr_majf = p->p_ru.majflt;
1369 pup->pr_nswap = p->p_ru.nswap;
1370 pup->pr_inblk = p->p_ru.inblock;
1371 pup->pr_oublk = p->p_ru.oublock;
1372 pup->pr_msnd = p->p_ru.msgsnd;
1373 pup->pr_mrcv = p->p_ru.msgrcv;
1374 pup->pr_sigs = p->p_ru.nsignals;
1375 pup->pr_vctx = p->p_ru.nvcsw;
1376 pup->pr_ictx = p->p_ru.nivcsw;
1377 pup->pr_sysc = p->p_ru.sysc;
1378 pup->pr_ioch = p->p_ru.ioch;
1379
1380 prcvtusage(pup, upup);
1381
1382 /*
1383 * Fill one prusage struct for each active lwp.
1384 */
1385 for (ldp = p->p_lwpdir, i = 0; i < p->p_lwpdir_sz; i++, ldp++) {
1386 if (ldp->ld_entry == NULL ||
1387 (t = ldp->ld_entry->le_thread) == NULL)
1388 continue;
1389 ASSERT(!(t->t_proc_flag & TP_LWPEXIT));
1390 ASSERT(nlwp > 0);
1391 --nlwp;
1392 upup = (prusage_t *)((caddr_t)upup + LSPAN(prusage_t));
1393 prgetusage(t, pup);
1394 prcvtusage(pup, upup);
1395 }
1396 ASSERT(nlwp == 0);
1397
1398 prunlock(pnp);
1399
1400 error = pr_uioread(php, size, uiop);
1401 kmem_free(pup, size + sizeof (prhusage_t));
1402 return (error);
1403 }
1404
1405 static int
pr_read_pagedata(prnode_t * pnp,uio_t * uiop,cred_t * cr)1406 pr_read_pagedata(prnode_t *pnp, uio_t *uiop, cred_t *cr)
1407 {
1408 proc_t *p;
1409 int error;
1410
1411 ASSERT(pnp->pr_type == PR_PAGEDATA);
1412
1413 if ((error = prlock(pnp, ZNO)) != 0)
1414 return (error);
1415
1416 p = pnp->pr_common->prc_proc;
1417 if ((p->p_flag & SSYS) || p->p_as == &kas) {
1418 prunlock(pnp);
1419 return (0);
1420 }
1421
1422 mutex_exit(&p->p_lock);
1423 error = prpdread(p, pnp->pr_hatid, uiop);
1424 mutex_enter(&p->p_lock);
1425
1426 prunlock(pnp);
1427 return (error);
1428 }
1429
1430 static int
pr_read_opagedata(prnode_t * pnp,uio_t * uiop,cred_t * cr)1431 pr_read_opagedata(prnode_t *pnp, uio_t *uiop, cred_t *cr)
1432 {
1433 proc_t *p;
1434 struct as *as;
1435 int error;
1436
1437 ASSERT(pnp->pr_type == PR_OPAGEDATA);
1438
1439 if ((error = prlock(pnp, ZNO)) != 0)
1440 return (error);
1441
1442 p = pnp->pr_common->prc_proc;
1443 as = p->p_as;
1444 if ((p->p_flag & SSYS) || as == &kas) {
1445 prunlock(pnp);
1446 return (0);
1447 }
1448
1449 mutex_exit(&p->p_lock);
1450 error = oprpdread(as, pnp->pr_hatid, uiop);
1451 mutex_enter(&p->p_lock);
1452
1453 prunlock(pnp);
1454 return (error);
1455 }
1456
1457 static int
pr_read_watch(prnode_t * pnp,uio_t * uiop,cred_t * cr)1458 pr_read_watch(prnode_t *pnp, uio_t *uiop, cred_t *cr)
1459 {
1460 proc_t *p;
1461 int error;
1462 prwatch_t *Bpwp;
1463 size_t size;
1464 prwatch_t *pwp;
1465 int nwarea;
1466 struct watched_area *pwarea;
1467
1468 ASSERT(pnp->pr_type == PR_WATCH);
1469
1470 if ((error = prlock(pnp, ZNO)) != 0)
1471 return (error);
1472
1473 p = pnp->pr_common->prc_proc;
1474 nwarea = avl_numnodes(&p->p_warea);
1475 size = nwarea * sizeof (prwatch_t);
1476 if (uiop->uio_offset >= size) {
1477 prunlock(pnp);
1478 return (0);
1479 }
1480
1481 /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
1482 mutex_exit(&p->p_lock);
1483 Bpwp = pwp = kmem_zalloc(size, KM_SLEEP);
1484 mutex_enter(&p->p_lock);
1485 /* p->p_nwarea can't change while process is locked */
1486 ASSERT(nwarea == avl_numnodes(&p->p_warea));
1487
1488 /* gather the watched areas */
1489 for (pwarea = avl_first(&p->p_warea); pwarea != NULL;
1490 pwarea = AVL_NEXT(&p->p_warea, pwarea), pwp++) {
1491 pwp->pr_vaddr = (uintptr_t)pwarea->wa_vaddr;
1492 pwp->pr_size = pwarea->wa_eaddr - pwarea->wa_vaddr;
1493 pwp->pr_wflags = (int)pwarea->wa_flags;
1494 }
1495
1496 prunlock(pnp);
1497
1498 error = pr_uioread(Bpwp, size, uiop);
1499 kmem_free(Bpwp, size);
1500 return (error);
1501 }
1502
1503 static int
pr_read_lwpstatus(prnode_t * pnp,uio_t * uiop,cred_t * cr)1504 pr_read_lwpstatus(prnode_t *pnp, uio_t *uiop, cred_t *cr)
1505 {
1506 lwpstatus_t *sp;
1507 int error;
1508
1509 ASSERT(pnp->pr_type == PR_LWPSTATUS);
1510
1511 /*
1512 * We kmem_alloc() the lwpstatus structure because
1513 * it is so big it might blow the kernel stack.
1514 */
1515 sp = kmem_alloc(sizeof (*sp), KM_SLEEP);
1516
1517 if ((error = prlock(pnp, ZNO)) != 0)
1518 goto out;
1519
1520 if (uiop->uio_offset >= sizeof (*sp)) {
1521 prunlock(pnp);
1522 goto out;
1523 }
1524
1525 prgetlwpstatus(pnp->pr_common->prc_thread, sp, VTOZONE(PTOV(pnp)));
1526 prunlock(pnp);
1527
1528 error = pr_uioread(sp, sizeof (*sp), uiop);
1529 out:
1530 kmem_free(sp, sizeof (*sp));
1531 return (error);
1532 }
1533
1534 static int
pr_read_lwpsinfo(prnode_t * pnp,uio_t * uiop,cred_t * cr)1535 pr_read_lwpsinfo(prnode_t *pnp, uio_t *uiop, cred_t *cr)
1536 {
1537 lwpsinfo_t lwpsinfo;
1538 proc_t *p;
1539 kthread_t *t;
1540 lwpent_t *lep;
1541
1542 ASSERT(pnp->pr_type == PR_LWPSINFO);
1543
1544 /*
1545 * We don't want the full treatment of prlock(pnp) here.
1546 * This file is world-readable and never goes invalid.
1547 * It doesn't matter if we are in the middle of an exec().
1548 */
1549 p = pr_p_lock(pnp);
1550 mutex_exit(&pr_pidlock);
1551 if (p == NULL)
1552 return (ENOENT);
1553 ASSERT(p == pnp->pr_common->prc_proc);
1554 if (pnp->pr_common->prc_tslot == -1) {
1555 prunlock(pnp);
1556 return (ENOENT);
1557 }
1558
1559 if (uiop->uio_offset >= sizeof (lwpsinfo)) {
1560 prunlock(pnp);
1561 return (0);
1562 }
1563
1564 if ((t = pnp->pr_common->prc_thread) != NULL)
1565 prgetlwpsinfo(t, &lwpsinfo);
1566 else {
1567 lep = p->p_lwpdir[pnp->pr_common->prc_tslot].ld_entry;
1568 bzero(&lwpsinfo, sizeof (lwpsinfo));
1569 lwpsinfo.pr_lwpid = lep->le_lwpid;
1570 lwpsinfo.pr_state = SZOMB;
1571 lwpsinfo.pr_sname = 'Z';
1572 lwpsinfo.pr_start.tv_sec = lep->le_start;
1573 lwpsinfo.pr_bindpro = PBIND_NONE;
1574 lwpsinfo.pr_bindpset = PS_NONE;
1575 }
1576 prunlock(pnp);
1577
1578 return (pr_uioread(&lwpsinfo, sizeof (lwpsinfo), uiop));
1579 }
1580
1581 static int
pr_read_lwpusage(prnode_t * pnp,uio_t * uiop,cred_t * cr)1582 pr_read_lwpusage(prnode_t *pnp, uio_t *uiop, cred_t *cr)
1583 {
1584 prhusage_t *pup;
1585 prusage_t *upup;
1586 proc_t *p;
1587 int error;
1588
1589 ASSERT(pnp->pr_type == PR_LWPUSAGE);
1590
1591 /* allocate now, before locking the process */
1592 pup = kmem_zalloc(sizeof (*pup), KM_SLEEP);
1593 upup = kmem_alloc(sizeof (*upup), KM_SLEEP);
1594
1595 /*
1596 * We don't want the full treatment of prlock(pnp) here.
1597 * This file is world-readable and never goes invalid.
1598 * It doesn't matter if we are in the middle of an exec().
1599 */
1600 p = pr_p_lock(pnp);
1601 mutex_exit(&pr_pidlock);
1602 if (p == NULL) {
1603 error = ENOENT;
1604 goto out;
1605 }
1606 ASSERT(p == pnp->pr_common->prc_proc);
1607 if (pnp->pr_common->prc_thread == NULL) {
1608 prunlock(pnp);
1609 error = ENOENT;
1610 goto out;
1611 }
1612 if (uiop->uio_offset >= sizeof (prusage_t)) {
1613 prunlock(pnp);
1614 error = 0;
1615 goto out;
1616 }
1617
1618 pup->pr_tstamp = gethrtime();
1619 prgetusage(pnp->pr_common->prc_thread, pup);
1620
1621 prunlock(pnp);
1622
1623 prcvtusage(pup, upup);
1624
1625 error = pr_uioread(upup, sizeof (prusage_t), uiop);
1626 out:
1627 kmem_free(pup, sizeof (*pup));
1628 kmem_free(upup, sizeof (*upup));
1629 return (error);
1630 }
1631
1632 static int
pr_read_lwpname(prnode_t * pnp,uio_t * uiop,cred_t * cr)1633 pr_read_lwpname(prnode_t *pnp, uio_t *uiop, cred_t *cr)
1634 {
1635 char lwpname[THREAD_NAME_MAX];
1636 kthread_t *t;
1637 int error;
1638
1639 ASSERT(pnp->pr_type == PR_LWPNAME);
1640
1641 if (uiop->uio_offset >= THREAD_NAME_MAX)
1642 return (0);
1643
1644 if ((error = prlock(pnp, ZNO)) != 0)
1645 return (error);
1646
1647 bzero(lwpname, sizeof (lwpname));
1648
1649 t = pnp->pr_common->prc_thread;
1650
1651 if (t->t_name != NULL)
1652 (void) strlcpy(lwpname, t->t_name, sizeof (lwpname));
1653
1654 prunlock(pnp);
1655
1656 return (pr_uioread(lwpname, sizeof (lwpname), uiop));
1657 }
1658
1659 /* ARGSUSED */
1660 static int
pr_read_xregs(prnode_t * pnp,uio_t * uiop,cred_t * cr)1661 pr_read_xregs(prnode_t *pnp, uio_t *uiop, cred_t *cr)
1662 {
1663 proc_t *p;
1664 kthread_t *t;
1665 int error;
1666 void *xreg;
1667 size_t size;
1668
1669 ASSERT(pnp->pr_type == PR_XREGS);
1670
1671 if ((error = prlock(pnp, ZNO)) != 0)
1672 return (error);
1673
1674 p = pnp->pr_common->prc_proc;
1675 t = pnp->pr_common->prc_thread;
1676
1677 /*
1678 * While we would prefer to do the allocation without holding the
1679 * process under a prlock(), we can only determine this size while
1680 * holding the process as the hold guarantees us:
1681 *
1682 * o That the process in question actualy exists.
1683 * o That the process in question cannot change the set of FPU features
1684 * it has enabled.
1685 *
1686 * We will drop p_lock across the allocation call itself. This should be
1687 * safe as the enabled feature set should not change while the process
1688 * is locked (e.g. enabling extending FPU state like AMX on x86 should
1689 * require the process to be locked).
1690 */
1691 size = prhasx(p) ? prgetprxregsize(p) : 0;
1692 if (size == 0) {
1693 prunlock(pnp);
1694 return (0);
1695 }
1696
1697 /*
1698 * To read the extended register set we require that the thread be
1699 * stopped as this state is only valid in the kernel when it is. An
1700 * exception made if the target thread and the current thread are one
1701 * and the same. We won't stop you from doing something... weird.
1702 */
1703 thread_lock(t);
1704 if (t != curthread && !ISTOPPED(t) && !VSTOPPED(t) && !DSTOPPED(t)) {
1705 thread_unlock(t);
1706 prunlock(pnp);
1707 return (EBUSY);
1708 }
1709 thread_unlock(t);
1710
1711 mutex_exit(&p->p_lock);
1712 xreg = kmem_zalloc(size, KM_SLEEP);
1713 mutex_enter(&p->p_lock);
1714 ASSERT3U(size, ==, prgetprxregsize(p));
1715
1716 if (uiop->uio_offset >= size) {
1717 prunlock(pnp);
1718 goto out;
1719 }
1720
1721 /* drop p->p_lock while (possibly) touching the stack */
1722 mutex_exit(&p->p_lock);
1723 prgetprxregs(ttolwp(t), xreg);
1724 mutex_enter(&p->p_lock);
1725 prunlock(pnp);
1726
1727 error = pr_uioread(xreg, size, uiop);
1728 out:
1729 kmem_free(xreg, size);
1730 return (error);
1731 }
1732
1733 static int
pr_read_spymaster(prnode_t * pnp,uio_t * uiop,cred_t * cr)1734 pr_read_spymaster(prnode_t *pnp, uio_t *uiop, cred_t *cr)
1735 {
1736 psinfo_t psinfo;
1737 int error;
1738 klwp_t *lwp;
1739
1740 ASSERT(pnp->pr_type == PR_SPYMASTER);
1741
1742 if ((error = prlock(pnp, ZNO)) != 0)
1743 return (error);
1744
1745 if (pnp->pr_common->prc_thread == NULL) {
1746 prunlock(pnp);
1747 return (0);
1748 }
1749
1750 lwp = pnp->pr_common->prc_thread->t_lwp;
1751
1752 if (lwp->lwp_spymaster == NULL) {
1753 prunlock(pnp);
1754 return (0);
1755 }
1756
1757 bcopy(lwp->lwp_spymaster, &psinfo, sizeof (psinfo_t));
1758 prunlock(pnp);
1759
1760 return (pr_uioread(&psinfo, sizeof (psinfo), uiop));
1761 }
1762
1763 static int
pr_read_secflags(prnode_t * pnp,uio_t * uiop,cred_t * cr)1764 pr_read_secflags(prnode_t *pnp, uio_t *uiop, cred_t *cr)
1765 {
1766 prsecflags_t ret;
1767 int error;
1768 proc_t *p;
1769
1770 ASSERT(pnp->pr_type == PR_SECFLAGS);
1771
1772 if ((error = prlock(pnp, ZNO)) != 0)
1773 return (error);
1774
1775 p = pnp->pr_common->prc_proc;
1776 prgetsecflags(p, &ret);
1777 prunlock(pnp);
1778
1779 return (pr_uioread(&ret, sizeof (ret), uiop));
1780 }
1781
1782 #if defined(__sparc)
1783
1784 static int
pr_read_gwindows(prnode_t * pnp,uio_t * uiop,cred_t * cr)1785 pr_read_gwindows(prnode_t *pnp, uio_t *uiop, cred_t *cr)
1786 {
1787 proc_t *p;
1788 kthread_t *t;
1789 gwindows_t *gwp;
1790 int error;
1791 size_t size;
1792
1793 ASSERT(pnp->pr_type == PR_GWINDOWS);
1794
1795 gwp = kmem_zalloc(sizeof (gwindows_t), KM_SLEEP);
1796
1797 if ((error = prlock(pnp, ZNO)) != 0)
1798 goto out;
1799
1800 p = pnp->pr_common->prc_proc;
1801 t = pnp->pr_common->prc_thread;
1802
1803 /*
1804 * Drop p->p_lock while touching the stack.
1805 * The P_PR_LOCK flag prevents the lwp from
1806 * disappearing while we do this.
1807 */
1808 mutex_exit(&p->p_lock);
1809 if ((size = prnwindows(ttolwp(t))) != 0)
1810 size = sizeof (gwindows_t) -
1811 (SPARC_MAXREGWINDOW - size) * sizeof (struct rwindow);
1812 if (uiop->uio_offset >= size) {
1813 mutex_enter(&p->p_lock);
1814 prunlock(pnp);
1815 goto out;
1816 }
1817 prgetwindows(ttolwp(t), gwp);
1818 mutex_enter(&p->p_lock);
1819 prunlock(pnp);
1820
1821 error = pr_uioread(gwp, size, uiop);
1822 out:
1823 kmem_free(gwp, sizeof (gwindows_t));
1824 return (error);
1825 }
1826
1827 /* ARGSUSED */
1828 static int
pr_read_asrs(prnode_t * pnp,uio_t * uiop,cred_t * cr)1829 pr_read_asrs(prnode_t *pnp, uio_t *uiop, cred_t *cr)
1830 {
1831 int error;
1832
1833 ASSERT(pnp->pr_type == PR_ASRS);
1834
1835 /* the asrs file exists only for sparc v9 _LP64 processes */
1836 if ((error = prlock(pnp, ZNO)) == 0) {
1837 proc_t *p = pnp->pr_common->prc_proc;
1838 kthread_t *t = pnp->pr_common->prc_thread;
1839 asrset_t asrset;
1840
1841 if (p->p_model != DATAMODEL_LP64 ||
1842 uiop->uio_offset >= sizeof (asrset_t)) {
1843 prunlock(pnp);
1844 return (0);
1845 }
1846
1847 /*
1848 * Drop p->p_lock while touching the stack.
1849 * The P_PR_LOCK flag prevents the lwp from
1850 * disappearing while we do this.
1851 */
1852 mutex_exit(&p->p_lock);
1853 prgetasregs(ttolwp(t), asrset);
1854 mutex_enter(&p->p_lock);
1855 prunlock(pnp);
1856
1857 error = pr_uioread(&asrset[0], sizeof (asrset_t), uiop);
1858 }
1859
1860 return (error);
1861 }
1862
1863 #endif /* __sparc */
1864
1865 static int
pr_read_piddir(prnode_t * pnp,uio_t * uiop,cred_t * cr)1866 pr_read_piddir(prnode_t *pnp, uio_t *uiop, cred_t *cr)
1867 {
1868 ASSERT(pnp->pr_type == PR_PIDDIR);
1869 ASSERT(pnp->pr_pidfile != NULL);
1870
1871 /* use the underlying PR_PIDFILE to read the process */
1872 pnp = VTOP(pnp->pr_pidfile);
1873 ASSERT(pnp->pr_type == PR_PIDFILE);
1874
1875 return (pr_read_pidfile(pnp, uiop));
1876 }
1877
1878 static int
pr_read_pidfile(prnode_t * pnp,uio_t * uiop,cred_t * cr)1879 pr_read_pidfile(prnode_t *pnp, uio_t *uiop, cred_t *cr)
1880 {
1881 int error;
1882
1883 ASSERT(pnp->pr_type == PR_PIDFILE || pnp->pr_type == PR_LWPIDFILE);
1884
1885 if ((error = prlock(pnp, ZNO)) == 0) {
1886 proc_t *p = pnp->pr_common->prc_proc;
1887 struct as *as = p->p_as;
1888
1889 if ((p->p_flag & SSYS) || as == &kas) {
1890 /*
1891 * /proc I/O cannot be done to a system process.
1892 */
1893 error = EIO; /* old /proc semantics */
1894 } else {
1895 /*
1896 * We drop p_lock because we don't want to hold
1897 * it over an I/O operation because that could
1898 * lead to deadlock with the clock thread.
1899 * The process will not disappear and its address
1900 * space will not change because it is marked P_PR_LOCK.
1901 */
1902 mutex_exit(&p->p_lock);
1903 error = prusrio(p, UIO_READ, uiop, 1);
1904 mutex_enter(&p->p_lock);
1905 }
1906 prunlock(pnp);
1907 }
1908
1909 return (error);
1910 }
1911
1912 #ifdef _SYSCALL32_IMPL
1913
1914 /*
1915 * Array of ILP32 read functions, indexed by /proc file type.
1916 */
1917 static int pr_read_status_32(),
1918 pr_read_lstatus_32(), pr_read_psinfo_32(), pr_read_lpsinfo_32(),
1919 pr_read_map_32(), pr_read_rmap_32(), pr_read_xmap_32(),
1920 pr_read_sigact_32(), pr_read_auxv_32(),
1921 pr_read_usage_32(), pr_read_lusage_32(), pr_read_pagedata_32(),
1922 pr_read_watch_32(), pr_read_lwpstatus_32(), pr_read_lwpsinfo_32(),
1923 pr_read_lwpusage_32(), pr_read_spymaster_32(),
1924 #if defined(__sparc)
1925 pr_read_gwindows_32(),
1926 #endif
1927 pr_read_opagedata_32();
1928
1929 static int (*pr_read_function_32[PR_NFILES])() = {
1930 pr_read_inval, /* /proc */
1931 pr_read_inval, /* /proc/self */
1932 pr_read_piddir, /* /proc/<pid> (old /proc read()) */
1933 pr_read_as, /* /proc/<pid>/as */
1934 pr_read_inval, /* /proc/<pid>/ctl */
1935 pr_read_status_32, /* /proc/<pid>/status */
1936 pr_read_lstatus_32, /* /proc/<pid>/lstatus */
1937 pr_read_psinfo_32, /* /proc/<pid>/psinfo */
1938 pr_read_lpsinfo_32, /* /proc/<pid>/lpsinfo */
1939 pr_read_map_32, /* /proc/<pid>/map */
1940 pr_read_rmap_32, /* /proc/<pid>/rmap */
1941 pr_read_xmap_32, /* /proc/<pid>/xmap */
1942 pr_read_cred, /* /proc/<pid>/cred */
1943 pr_read_sigact_32, /* /proc/<pid>/sigact */
1944 pr_read_auxv_32, /* /proc/<pid>/auxv */
1945 #if defined(__x86)
1946 pr_read_ldt, /* /proc/<pid>/ldt */
1947 #endif
1948 pr_read_usage_32, /* /proc/<pid>/usage */
1949 pr_read_lusage_32, /* /proc/<pid>/lusage */
1950 pr_read_pagedata_32, /* /proc/<pid>/pagedata */
1951 pr_read_watch_32, /* /proc/<pid>/watch */
1952 pr_read_inval, /* /proc/<pid>/cwd */
1953 pr_read_inval, /* /proc/<pid>/root */
1954 pr_read_inval, /* /proc/<pid>/fd */
1955 pr_read_inval, /* /proc/<pid>/fd/nn */
1956 pr_read_inval, /* /proc/<pid>/fdinfo */
1957 pr_read_fdinfo, /* /proc/<pid>/fdinfo/nn */
1958 pr_read_inval, /* /proc/<pid>/object */
1959 pr_read_inval, /* /proc/<pid>/object/xxx */
1960 pr_read_inval, /* /proc/<pid>/lwp */
1961 pr_read_inval, /* /proc/<pid>/lwp/<lwpid> */
1962 pr_read_inval, /* /proc/<pid>/lwp/<lwpid>/lwpctl */
1963 pr_read_lwpname, /* /proc/<pid>/lwp/<lwpid>/lwpname */
1964 pr_read_lwpstatus_32, /* /proc/<pid>/lwp/<lwpid>/lwpstatus */
1965 pr_read_lwpsinfo_32, /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
1966 pr_read_lwpusage_32, /* /proc/<pid>/lwp/<lwpid>/lwpusage */
1967 pr_read_xregs, /* /proc/<pid>/lwp/<lwpid>/xregs */
1968 pr_read_inval, /* /proc/<pid>/lwp/<lwpid>/templates */
1969 pr_read_inval, /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
1970 pr_read_spymaster_32, /* /proc/<pid>/lwp/<lwpid>/spymaster */
1971 #if defined(__sparc)
1972 pr_read_gwindows_32, /* /proc/<pid>/lwp/<lwpid>/gwindows */
1973 pr_read_asrs, /* /proc/<pid>/lwp/<lwpid>/asrs */
1974 #endif
1975 pr_read_priv, /* /proc/<pid>/priv */
1976 pr_read_inval, /* /proc/<pid>/path */
1977 pr_read_inval, /* /proc/<pid>/path/xxx */
1978 pr_read_inval, /* /proc/<pid>/contracts */
1979 pr_read_inval, /* /proc/<pid>/contracts/<ctid> */
1980 pr_read_secflags, /* /proc/<pid>/secflags */
1981 pr_read_pidfile, /* old process file */
1982 pr_read_pidfile, /* old lwp file */
1983 pr_read_opagedata_32, /* old pagedata file */
1984 };
1985
1986 static int
pr_read_status_32(prnode_t * pnp,uio_t * uiop,cred_t * cr)1987 pr_read_status_32(prnode_t *pnp, uio_t *uiop, cred_t *cr)
1988 {
1989 pstatus32_t *sp;
1990 proc_t *p;
1991 int error;
1992
1993 ASSERT(pnp->pr_type == PR_STATUS);
1994
1995 /*
1996 * We kmem_alloc() the pstatus structure because
1997 * it is so big it might blow the kernel stack.
1998 */
1999 sp = kmem_alloc(sizeof (*sp), KM_SLEEP);
2000 if ((error = prlock(pnp, ZNO)) == 0) {
2001 /*
2002 * A 32-bit process cannot get the status of a 64-bit process.
2003 * The fields for the 64-bit quantities are not large enough.
2004 */
2005 p = pnp->pr_common->prc_proc;
2006 if (PROCESS_NOT_32BIT(p)) {
2007 prunlock(pnp);
2008 error = EOVERFLOW;
2009 } else {
2010 prgetstatus32(pnp->pr_common->prc_proc, sp,
2011 VTOZONE(PTOV(pnp)));
2012 prunlock(pnp);
2013 error = pr_uioread(sp, sizeof (*sp), uiop);
2014 }
2015 }
2016 kmem_free((caddr_t)sp, sizeof (*sp));
2017 return (error);
2018 }
2019
2020 static int
pr_read_lstatus_32(prnode_t * pnp,uio_t * uiop,cred_t * cr)2021 pr_read_lstatus_32(prnode_t *pnp, uio_t *uiop, cred_t *cr)
2022 {
2023 proc_t *p;
2024 kthread_t *t;
2025 lwpdir_t *ldp;
2026 size_t size;
2027 prheader32_t *php;
2028 lwpstatus32_t *sp;
2029 int error;
2030 int nlwp;
2031 int i;
2032
2033 ASSERT(pnp->pr_type == PR_LSTATUS);
2034
2035 if ((error = prlock(pnp, ZNO)) != 0)
2036 return (error);
2037 p = pnp->pr_common->prc_proc;
2038 /*
2039 * A 32-bit process cannot get the status of a 64-bit process.
2040 * The fields for the 64-bit quantities are not large enough.
2041 */
2042 if (PROCESS_NOT_32BIT(p)) {
2043 prunlock(pnp);
2044 return (EOVERFLOW);
2045 }
2046 nlwp = p->p_lwpcnt;
2047 size = sizeof (prheader32_t) + nlwp * LSPAN32(lwpstatus32_t);
2048
2049 /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
2050 mutex_exit(&p->p_lock);
2051 php = kmem_zalloc(size, KM_SLEEP);
2052 mutex_enter(&p->p_lock);
2053 /* p->p_lwpcnt can't change while process is locked */
2054 ASSERT(nlwp == p->p_lwpcnt);
2055
2056 php->pr_nent = nlwp;
2057 php->pr_entsize = LSPAN32(lwpstatus32_t);
2058
2059 sp = (lwpstatus32_t *)(php + 1);
2060 for (ldp = p->p_lwpdir, i = 0; i < p->p_lwpdir_sz; i++, ldp++) {
2061 if (ldp->ld_entry == NULL ||
2062 (t = ldp->ld_entry->le_thread) == NULL)
2063 continue;
2064 prgetlwpstatus32(t, sp, VTOZONE(PTOV(pnp)));
2065 sp = (lwpstatus32_t *)((caddr_t)sp + LSPAN32(lwpstatus32_t));
2066 }
2067 prunlock(pnp);
2068
2069 error = pr_uioread(php, size, uiop);
2070 kmem_free(php, size);
2071 return (error);
2072 }
2073
2074 static int
pr_read_psinfo_32(prnode_t * pnp,uio_t * uiop,cred_t * cr)2075 pr_read_psinfo_32(prnode_t *pnp, uio_t *uiop, cred_t *cr)
2076 {
2077 psinfo32_t psinfo;
2078 proc_t *p;
2079 int error = 0;
2080
2081 ASSERT(pnp->pr_type == PR_PSINFO);
2082
2083 /*
2084 * We don't want the full treatment of prlock(pnp) here.
2085 * This file is world-readable and never goes invalid.
2086 * It doesn't matter if we are in the middle of an exec().
2087 */
2088 p = pr_p_lock(pnp);
2089 mutex_exit(&pr_pidlock);
2090 if (p == NULL)
2091 error = ENOENT;
2092 else {
2093 ASSERT(p == pnp->pr_common->prc_proc);
2094 prgetpsinfo32(p, &psinfo);
2095 prunlock(pnp);
2096 error = pr_uioread(&psinfo, sizeof (psinfo), uiop);
2097 }
2098 return (error);
2099 }
2100
2101 static int
pr_read_lpsinfo_32(prnode_t * pnp,uio_t * uiop,cred_t * cr)2102 pr_read_lpsinfo_32(prnode_t *pnp, uio_t *uiop, cred_t *cr)
2103 {
2104 proc_t *p;
2105 kthread_t *t;
2106 lwpdir_t *ldp;
2107 lwpent_t *lep;
2108 size_t size;
2109 prheader32_t *php;
2110 lwpsinfo32_t *sp;
2111 int error;
2112 int nlwp;
2113 int i;
2114
2115 ASSERT(pnp->pr_type == PR_LPSINFO);
2116
2117 /*
2118 * We don't want the full treatment of prlock(pnp) here.
2119 * This file is world-readable and never goes invalid.
2120 * It doesn't matter if we are in the middle of an exec().
2121 */
2122 p = pr_p_lock(pnp);
2123 mutex_exit(&pr_pidlock);
2124 if (p == NULL)
2125 return (ENOENT);
2126 ASSERT(p == pnp->pr_common->prc_proc);
2127 if ((nlwp = p->p_lwpcnt + p->p_zombcnt) == 0) {
2128 prunlock(pnp);
2129 return (ENOENT);
2130 }
2131 size = sizeof (prheader32_t) + nlwp * LSPAN32(lwpsinfo32_t);
2132
2133 /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
2134 mutex_exit(&p->p_lock);
2135 php = kmem_zalloc(size, KM_SLEEP);
2136 mutex_enter(&p->p_lock);
2137 /* p->p_lwpcnt can't change while process is locked */
2138 ASSERT(nlwp == p->p_lwpcnt + p->p_zombcnt);
2139
2140 php->pr_nent = nlwp;
2141 php->pr_entsize = LSPAN32(lwpsinfo32_t);
2142
2143 sp = (lwpsinfo32_t *)(php + 1);
2144 for (ldp = p->p_lwpdir, i = 0; i < p->p_lwpdir_sz; i++, ldp++) {
2145 if ((lep = ldp->ld_entry) == NULL)
2146 continue;
2147 if ((t = lep->le_thread) != NULL)
2148 prgetlwpsinfo32(t, sp);
2149 else {
2150 bzero(sp, sizeof (*sp));
2151 sp->pr_lwpid = lep->le_lwpid;
2152 sp->pr_state = SZOMB;
2153 sp->pr_sname = 'Z';
2154 sp->pr_start.tv_sec = (time32_t)lep->le_start;
2155 }
2156 sp = (lwpsinfo32_t *)((caddr_t)sp + LSPAN32(lwpsinfo32_t));
2157 }
2158 prunlock(pnp);
2159
2160 error = pr_uioread(php, size, uiop);
2161 kmem_free(php, size);
2162 return (error);
2163 }
2164
2165 static int
pr_read_map_common_32(prnode_t * pnp,uio_t * uiop,prnodetype_t type)2166 pr_read_map_common_32(prnode_t *pnp, uio_t *uiop, prnodetype_t type)
2167 {
2168 proc_t *p;
2169 struct as *as;
2170 list_t iolhead;
2171 int error;
2172
2173 readmap32_common:
2174 if ((error = prlock(pnp, ZNO)) != 0)
2175 return (error);
2176
2177 p = pnp->pr_common->prc_proc;
2178 as = p->p_as;
2179
2180 if ((p->p_flag & SSYS) || as == &kas) {
2181 prunlock(pnp);
2182 return (0);
2183 }
2184
2185 if (PROCESS_NOT_32BIT(p)) {
2186 prunlock(pnp);
2187 return (EOVERFLOW);
2188 }
2189
2190 if (!AS_LOCK_TRYENTER(as, RW_WRITER)) {
2191 prunlock(pnp);
2192 delay(1);
2193 goto readmap32_common;
2194 }
2195 mutex_exit(&p->p_lock);
2196
2197 switch (type) {
2198 case PR_XMAP:
2199 error = prgetxmap32(p, &iolhead);
2200 break;
2201 case PR_RMAP:
2202 error = prgetmap32(p, 1, &iolhead);
2203 break;
2204 case PR_MAP:
2205 error = prgetmap32(p, 0, &iolhead);
2206 break;
2207 }
2208 AS_LOCK_EXIT(as);
2209 mutex_enter(&p->p_lock);
2210 prunlock(pnp);
2211
2212 error = pr_iol_uiomove_and_free(&iolhead, uiop, error);
2213
2214 return (error);
2215 }
2216
2217 static int
pr_read_map_32(prnode_t * pnp,uio_t * uiop,cred_t * cr)2218 pr_read_map_32(prnode_t *pnp, uio_t *uiop, cred_t *cr)
2219 {
2220 ASSERT(pnp->pr_type == PR_MAP);
2221 return (pr_read_map_common_32(pnp, uiop, pnp->pr_type));
2222 }
2223
2224 static int
pr_read_rmap_32(prnode_t * pnp,uio_t * uiop,cred_t * cr)2225 pr_read_rmap_32(prnode_t *pnp, uio_t *uiop, cred_t *cr)
2226 {
2227 ASSERT(pnp->pr_type == PR_RMAP);
2228 return (pr_read_map_common_32(pnp, uiop, pnp->pr_type));
2229 }
2230
2231 static int
pr_read_xmap_32(prnode_t * pnp,uio_t * uiop,cred_t * cr)2232 pr_read_xmap_32(prnode_t *pnp, uio_t *uiop, cred_t *cr)
2233 {
2234 ASSERT(pnp->pr_type == PR_XMAP);
2235 return (pr_read_map_common_32(pnp, uiop, pnp->pr_type));
2236 }
2237
2238 static int
pr_read_sigact_32(prnode_t * pnp,uio_t * uiop,cred_t * cr)2239 pr_read_sigact_32(prnode_t *pnp, uio_t *uiop, cred_t *cr)
2240 {
2241 int nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG;
2242 proc_t *p;
2243 struct sigaction32 *sap;
2244 int sig;
2245 int error;
2246 user_t *up;
2247
2248 ASSERT(pnp->pr_type == PR_SIGACT);
2249
2250 /*
2251 * We kmem_alloc() the sigaction32 array because
2252 * it is so big it might blow the kernel stack.
2253 */
2254 sap = kmem_alloc((nsig-1) * sizeof (struct sigaction32), KM_SLEEP);
2255
2256 if ((error = prlock(pnp, ZNO)) != 0)
2257 goto out;
2258 p = pnp->pr_common->prc_proc;
2259
2260 if (PROCESS_NOT_32BIT(p)) {
2261 prunlock(pnp);
2262 error = EOVERFLOW;
2263 goto out;
2264 }
2265
2266 if (uiop->uio_offset >= (nsig-1) * sizeof (struct sigaction32)) {
2267 prunlock(pnp);
2268 goto out;
2269 }
2270
2271 up = PTOU(p);
2272 for (sig = 1; sig < nsig; sig++)
2273 prgetaction32(p, up, sig, &sap[sig-1]);
2274 prunlock(pnp);
2275
2276 error = pr_uioread(sap, (nsig - 1) * sizeof (struct sigaction32), uiop);
2277 out:
2278 kmem_free(sap, (nsig-1) * sizeof (struct sigaction32));
2279 return (error);
2280 }
2281
2282 static int
pr_read_auxv_32(prnode_t * pnp,uio_t * uiop,cred_t * cr)2283 pr_read_auxv_32(prnode_t *pnp, uio_t *uiop, cred_t *cr)
2284 {
2285 auxv32_t auxv[__KERN_NAUXV_IMPL];
2286 proc_t *p;
2287 user_t *up;
2288 int error;
2289 int i;
2290
2291 ASSERT(pnp->pr_type == PR_AUXV);
2292
2293 if ((error = prlock(pnp, ZNO)) != 0)
2294 return (error);
2295 p = pnp->pr_common->prc_proc;
2296
2297 if (PROCESS_NOT_32BIT(p)) {
2298 prunlock(pnp);
2299 return (EOVERFLOW);
2300 }
2301
2302 if (uiop->uio_offset >= sizeof (auxv)) {
2303 prunlock(pnp);
2304 return (0);
2305 }
2306
2307 up = PTOU(p);
2308 for (i = 0; i < __KERN_NAUXV_IMPL; i++) {
2309 auxv[i].a_type = (int32_t)up->u_auxv[i].a_type;
2310 auxv[i].a_un.a_val = (int32_t)up->u_auxv[i].a_un.a_val;
2311 }
2312 prunlock(pnp);
2313
2314 return (pr_uioread(auxv, sizeof (auxv), uiop));
2315 }
2316
2317 static int
pr_read_usage_32(prnode_t * pnp,uio_t * uiop,cred_t * cr)2318 pr_read_usage_32(prnode_t *pnp, uio_t *uiop, cred_t *cr)
2319 {
2320 prhusage_t *pup;
2321 prusage32_t *upup;
2322 proc_t *p;
2323 kthread_t *t;
2324 int error;
2325
2326 ASSERT(pnp->pr_type == PR_USAGE);
2327
2328 /* allocate now, before locking the process */
2329 pup = kmem_zalloc(sizeof (*pup), KM_SLEEP);
2330 upup = kmem_alloc(sizeof (*upup), KM_SLEEP);
2331
2332 /*
2333 * We don't want the full treatment of prlock(pnp) here.
2334 * This file is world-readable and never goes invalid.
2335 * It doesn't matter if we are in the middle of an exec().
2336 */
2337 p = pr_p_lock(pnp);
2338 mutex_exit(&pr_pidlock);
2339 if (p == NULL) {
2340 error = ENOENT;
2341 goto out;
2342 }
2343 ASSERT(p == pnp->pr_common->prc_proc);
2344
2345 if (uiop->uio_offset >= sizeof (prusage32_t)) {
2346 prunlock(pnp);
2347 error = 0;
2348 goto out;
2349 }
2350
2351 pup->pr_tstamp = gethrtime();
2352
2353 pup->pr_count = p->p_defunct;
2354 pup->pr_create = p->p_mstart;
2355 pup->pr_term = p->p_mterm;
2356
2357 pup->pr_rtime = p->p_mlreal;
2358 pup->pr_utime = p->p_acct[LMS_USER];
2359 pup->pr_stime = p->p_acct[LMS_SYSTEM];
2360 pup->pr_ttime = p->p_acct[LMS_TRAP];
2361 pup->pr_tftime = p->p_acct[LMS_TFAULT];
2362 pup->pr_dftime = p->p_acct[LMS_DFAULT];
2363 pup->pr_kftime = p->p_acct[LMS_KFAULT];
2364 pup->pr_ltime = p->p_acct[LMS_USER_LOCK];
2365 pup->pr_slptime = p->p_acct[LMS_SLEEP];
2366 pup->pr_wtime = p->p_acct[LMS_WAIT_CPU];
2367 pup->pr_stoptime = p->p_acct[LMS_STOPPED];
2368
2369 pup->pr_minf = p->p_ru.minflt;
2370 pup->pr_majf = p->p_ru.majflt;
2371 pup->pr_nswap = p->p_ru.nswap;
2372 pup->pr_inblk = p->p_ru.inblock;
2373 pup->pr_oublk = p->p_ru.oublock;
2374 pup->pr_msnd = p->p_ru.msgsnd;
2375 pup->pr_mrcv = p->p_ru.msgrcv;
2376 pup->pr_sigs = p->p_ru.nsignals;
2377 pup->pr_vctx = p->p_ru.nvcsw;
2378 pup->pr_ictx = p->p_ru.nivcsw;
2379 pup->pr_sysc = p->p_ru.sysc;
2380 pup->pr_ioch = p->p_ru.ioch;
2381
2382 /*
2383 * Add the usage information for each active lwp.
2384 */
2385 if ((t = p->p_tlist) != NULL &&
2386 !(pnp->pr_pcommon->prc_flags & PRC_DESTROY)) {
2387 do {
2388 if (t->t_proc_flag & TP_LWPEXIT)
2389 continue;
2390 pup->pr_count++;
2391 praddusage(t, pup);
2392 } while ((t = t->t_forw) != p->p_tlist);
2393 }
2394
2395 prunlock(pnp);
2396
2397 prcvtusage32(pup, upup);
2398
2399 error = pr_uioread(upup, sizeof (prusage32_t), uiop);
2400 out:
2401 kmem_free(pup, sizeof (*pup));
2402 kmem_free(upup, sizeof (*upup));
2403 return (error);
2404 }
2405
2406 static int
pr_read_lusage_32(prnode_t * pnp,uio_t * uiop,cred_t * cr)2407 pr_read_lusage_32(prnode_t *pnp, uio_t *uiop, cred_t *cr)
2408 {
2409 int nlwp;
2410 prhusage_t *pup;
2411 prheader32_t *php;
2412 prusage32_t *upup;
2413 size_t size;
2414 hrtime_t curtime;
2415 proc_t *p;
2416 kthread_t *t;
2417 lwpdir_t *ldp;
2418 int error;
2419 int i;
2420
2421 ASSERT(pnp->pr_type == PR_LUSAGE);
2422
2423 /*
2424 * We don't want the full treatment of prlock(pnp) here.
2425 * This file is world-readable and never goes invalid.
2426 * It doesn't matter if we are in the middle of an exec().
2427 */
2428 p = pr_p_lock(pnp);
2429 mutex_exit(&pr_pidlock);
2430 if (p == NULL)
2431 return (ENOENT);
2432 ASSERT(p == pnp->pr_common->prc_proc);
2433 if ((nlwp = p->p_lwpcnt) == 0) {
2434 prunlock(pnp);
2435 return (ENOENT);
2436 }
2437
2438 size = sizeof (prheader32_t) + (nlwp + 1) * LSPAN32(prusage32_t);
2439 if (uiop->uio_offset >= size) {
2440 prunlock(pnp);
2441 return (0);
2442 }
2443
2444 /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
2445 mutex_exit(&p->p_lock);
2446 pup = kmem_zalloc(size + sizeof (prhusage_t), KM_SLEEP);
2447 mutex_enter(&p->p_lock);
2448 /* p->p_lwpcnt can't change while process is locked */
2449 ASSERT(nlwp == p->p_lwpcnt);
2450
2451 php = (prheader32_t *)(pup + 1);
2452 upup = (prusage32_t *)(php + 1);
2453
2454 php->pr_nent = nlwp + 1;
2455 php->pr_entsize = LSPAN32(prusage32_t);
2456
2457 curtime = gethrtime();
2458
2459 /*
2460 * First the summation over defunct lwps.
2461 */
2462 pup->pr_count = p->p_defunct;
2463 pup->pr_tstamp = curtime;
2464 pup->pr_create = p->p_mstart;
2465 pup->pr_term = p->p_mterm;
2466
2467 pup->pr_rtime = p->p_mlreal;
2468 pup->pr_utime = p->p_acct[LMS_USER];
2469 pup->pr_stime = p->p_acct[LMS_SYSTEM];
2470 pup->pr_ttime = p->p_acct[LMS_TRAP];
2471 pup->pr_tftime = p->p_acct[LMS_TFAULT];
2472 pup->pr_dftime = p->p_acct[LMS_DFAULT];
2473 pup->pr_kftime = p->p_acct[LMS_KFAULT];
2474 pup->pr_ltime = p->p_acct[LMS_USER_LOCK];
2475 pup->pr_slptime = p->p_acct[LMS_SLEEP];
2476 pup->pr_wtime = p->p_acct[LMS_WAIT_CPU];
2477 pup->pr_stoptime = p->p_acct[LMS_STOPPED];
2478
2479 pup->pr_minf = p->p_ru.minflt;
2480 pup->pr_majf = p->p_ru.majflt;
2481 pup->pr_nswap = p->p_ru.nswap;
2482 pup->pr_inblk = p->p_ru.inblock;
2483 pup->pr_oublk = p->p_ru.oublock;
2484 pup->pr_msnd = p->p_ru.msgsnd;
2485 pup->pr_mrcv = p->p_ru.msgrcv;
2486 pup->pr_sigs = p->p_ru.nsignals;
2487 pup->pr_vctx = p->p_ru.nvcsw;
2488 pup->pr_ictx = p->p_ru.nivcsw;
2489 pup->pr_sysc = p->p_ru.sysc;
2490 pup->pr_ioch = p->p_ru.ioch;
2491
2492 prcvtusage32(pup, upup);
2493
2494 /*
2495 * Fill one prusage struct for each active lwp.
2496 */
2497 for (ldp = p->p_lwpdir, i = 0; i < p->p_lwpdir_sz; i++, ldp++) {
2498 if (ldp->ld_entry == NULL ||
2499 (t = ldp->ld_entry->le_thread) == NULL)
2500 continue;
2501 ASSERT(!(t->t_proc_flag & TP_LWPEXIT));
2502 ASSERT(nlwp > 0);
2503 --nlwp;
2504 upup = (prusage32_t *)
2505 ((caddr_t)upup + LSPAN32(prusage32_t));
2506 prgetusage(t, pup);
2507 prcvtusage32(pup, upup);
2508 }
2509 ASSERT(nlwp == 0);
2510
2511 prunlock(pnp);
2512
2513 error = pr_uioread(php, size, uiop);
2514 kmem_free(pup, size + sizeof (prhusage_t));
2515 return (error);
2516 }
2517
2518 static int
pr_read_pagedata_32(prnode_t * pnp,uio_t * uiop,cred_t * cr)2519 pr_read_pagedata_32(prnode_t *pnp, uio_t *uiop, cred_t *cr)
2520 {
2521 proc_t *p;
2522 int error;
2523
2524 ASSERT(pnp->pr_type == PR_PAGEDATA);
2525
2526 if ((error = prlock(pnp, ZNO)) != 0)
2527 return (error);
2528
2529 p = pnp->pr_common->prc_proc;
2530 if ((p->p_flag & SSYS) || p->p_as == &kas) {
2531 prunlock(pnp);
2532 return (0);
2533 }
2534
2535 if (PROCESS_NOT_32BIT(p)) {
2536 prunlock(pnp);
2537 return (EOVERFLOW);
2538 }
2539
2540 mutex_exit(&p->p_lock);
2541 error = prpdread32(p, pnp->pr_hatid, uiop);
2542 mutex_enter(&p->p_lock);
2543
2544 prunlock(pnp);
2545 return (error);
2546 }
2547
2548 static int
pr_read_opagedata_32(prnode_t * pnp,uio_t * uiop,cred_t * cr)2549 pr_read_opagedata_32(prnode_t *pnp, uio_t *uiop, cred_t *cr)
2550 {
2551 proc_t *p;
2552 struct as *as;
2553 int error;
2554
2555 ASSERT(pnp->pr_type == PR_OPAGEDATA);
2556
2557 if ((error = prlock(pnp, ZNO)) != 0)
2558 return (error);
2559
2560 p = pnp->pr_common->prc_proc;
2561 as = p->p_as;
2562
2563 if ((p->p_flag & SSYS) || as == &kas) {
2564 prunlock(pnp);
2565 return (0);
2566 }
2567
2568 if (PROCESS_NOT_32BIT(p)) {
2569 prunlock(pnp);
2570 return (EOVERFLOW);
2571 }
2572
2573 mutex_exit(&p->p_lock);
2574 error = oprpdread32(as, pnp->pr_hatid, uiop);
2575 mutex_enter(&p->p_lock);
2576
2577 prunlock(pnp);
2578 return (error);
2579 }
2580
2581 static int
pr_read_watch_32(prnode_t * pnp,uio_t * uiop,cred_t * cr)2582 pr_read_watch_32(prnode_t *pnp, uio_t *uiop, cred_t *cr)
2583 {
2584 proc_t *p;
2585 int error;
2586 prwatch32_t *Bpwp;
2587 size_t size;
2588 prwatch32_t *pwp;
2589 int nwarea;
2590 struct watched_area *pwarea;
2591
2592 ASSERT(pnp->pr_type == PR_WATCH);
2593
2594 if ((error = prlock(pnp, ZNO)) != 0)
2595 return (error);
2596
2597 p = pnp->pr_common->prc_proc;
2598 if (PROCESS_NOT_32BIT(p)) {
2599 prunlock(pnp);
2600 return (EOVERFLOW);
2601 }
2602 nwarea = avl_numnodes(&p->p_warea);
2603 size = nwarea * sizeof (prwatch32_t);
2604 if (uiop->uio_offset >= size) {
2605 prunlock(pnp);
2606 return (0);
2607 }
2608
2609 /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
2610 mutex_exit(&p->p_lock);
2611 Bpwp = pwp = kmem_zalloc(size, KM_SLEEP);
2612 mutex_enter(&p->p_lock);
2613 /* p->p_nwarea can't change while process is locked */
2614 ASSERT(nwarea == avl_numnodes(&p->p_warea));
2615
2616 /* gather the watched areas */
2617 for (pwarea = avl_first(&p->p_warea); pwarea != NULL;
2618 pwarea = AVL_NEXT(&p->p_warea, pwarea), pwp++) {
2619 pwp->pr_vaddr = (caddr32_t)(uintptr_t)pwarea->wa_vaddr;
2620 pwp->pr_size = (size32_t)(pwarea->wa_eaddr - pwarea->wa_vaddr);
2621 pwp->pr_wflags = (int)pwarea->wa_flags;
2622 }
2623
2624 prunlock(pnp);
2625
2626 error = pr_uioread(Bpwp, size, uiop);
2627 kmem_free(Bpwp, size);
2628 return (error);
2629 }
2630
2631 static int
pr_read_lwpstatus_32(prnode_t * pnp,uio_t * uiop,cred_t * cr)2632 pr_read_lwpstatus_32(prnode_t *pnp, uio_t *uiop, cred_t *cr)
2633 {
2634 lwpstatus32_t *sp;
2635 proc_t *p;
2636 int error;
2637
2638 ASSERT(pnp->pr_type == PR_LWPSTATUS);
2639
2640 /*
2641 * We kmem_alloc() the lwpstatus structure because
2642 * it is so big it might blow the kernel stack.
2643 */
2644 sp = kmem_alloc(sizeof (*sp), KM_SLEEP);
2645
2646 if ((error = prlock(pnp, ZNO)) != 0)
2647 goto out;
2648
2649 /*
2650 * A 32-bit process cannot get the status of a 64-bit process.
2651 * The fields for the 64-bit quantities are not large enough.
2652 */
2653 p = pnp->pr_common->prc_proc;
2654 if (PROCESS_NOT_32BIT(p)) {
2655 prunlock(pnp);
2656 error = EOVERFLOW;
2657 goto out;
2658 }
2659
2660 if (uiop->uio_offset >= sizeof (*sp)) {
2661 prunlock(pnp);
2662 goto out;
2663 }
2664
2665 prgetlwpstatus32(pnp->pr_common->prc_thread, sp, VTOZONE(PTOV(pnp)));
2666 prunlock(pnp);
2667
2668 error = pr_uioread(sp, sizeof (*sp), uiop);
2669 out:
2670 kmem_free(sp, sizeof (*sp));
2671 return (error);
2672 }
2673
2674 static int
pr_read_lwpsinfo_32(prnode_t * pnp,uio_t * uiop,cred_t * cr)2675 pr_read_lwpsinfo_32(prnode_t *pnp, uio_t *uiop, cred_t *cr)
2676 {
2677 lwpsinfo32_t lwpsinfo;
2678 proc_t *p;
2679 kthread_t *t;
2680 lwpent_t *lep;
2681
2682 ASSERT(pnp->pr_type == PR_LWPSINFO);
2683
2684 /*
2685 * We don't want the full treatment of prlock(pnp) here.
2686 * This file is world-readable and never goes invalid.
2687 * It doesn't matter if we are in the middle of an exec().
2688 */
2689 p = pr_p_lock(pnp);
2690 mutex_exit(&pr_pidlock);
2691 if (p == NULL)
2692 return (ENOENT);
2693 ASSERT(p == pnp->pr_common->prc_proc);
2694 if (pnp->pr_common->prc_tslot == -1) {
2695 prunlock(pnp);
2696 return (ENOENT);
2697 }
2698
2699 if (uiop->uio_offset >= sizeof (lwpsinfo)) {
2700 prunlock(pnp);
2701 return (0);
2702 }
2703
2704 if ((t = pnp->pr_common->prc_thread) != NULL)
2705 prgetlwpsinfo32(t, &lwpsinfo);
2706 else {
2707 lep = p->p_lwpdir[pnp->pr_common->prc_tslot].ld_entry;
2708 bzero(&lwpsinfo, sizeof (lwpsinfo));
2709 lwpsinfo.pr_lwpid = lep->le_lwpid;
2710 lwpsinfo.pr_state = SZOMB;
2711 lwpsinfo.pr_sname = 'Z';
2712 lwpsinfo.pr_start.tv_sec = (time32_t)lep->le_start;
2713 }
2714 prunlock(pnp);
2715
2716 return (pr_uioread(&lwpsinfo, sizeof (lwpsinfo), uiop));
2717 }
2718
2719 static int
pr_read_lwpusage_32(prnode_t * pnp,uio_t * uiop,cred_t * cr)2720 pr_read_lwpusage_32(prnode_t *pnp, uio_t *uiop, cred_t *cr)
2721 {
2722 prhusage_t *pup;
2723 prusage32_t *upup;
2724 proc_t *p;
2725 int error;
2726
2727 ASSERT(pnp->pr_type == PR_LWPUSAGE);
2728
2729 /* allocate now, before locking the process */
2730 pup = kmem_zalloc(sizeof (*pup), KM_SLEEP);
2731 upup = kmem_alloc(sizeof (*upup), KM_SLEEP);
2732
2733 /*
2734 * We don't want the full treatment of prlock(pnp) here.
2735 * This file is world-readable and never goes invalid.
2736 * It doesn't matter if we are in the middle of an exec().
2737 */
2738 p = pr_p_lock(pnp);
2739 mutex_exit(&pr_pidlock);
2740 if (p == NULL) {
2741 error = ENOENT;
2742 goto out;
2743 }
2744 ASSERT(p == pnp->pr_common->prc_proc);
2745 if (pnp->pr_common->prc_thread == NULL) {
2746 prunlock(pnp);
2747 error = ENOENT;
2748 goto out;
2749 }
2750 if (uiop->uio_offset >= sizeof (prusage32_t)) {
2751 prunlock(pnp);
2752 error = 0;
2753 goto out;
2754 }
2755
2756 pup->pr_tstamp = gethrtime();
2757 prgetusage(pnp->pr_common->prc_thread, pup);
2758
2759 prunlock(pnp);
2760
2761 prcvtusage32(pup, upup);
2762
2763 error = pr_uioread(upup, sizeof (prusage32_t), uiop);
2764 out:
2765 kmem_free(pup, sizeof (*pup));
2766 kmem_free(upup, sizeof (*upup));
2767 return (error);
2768 }
2769
2770 static int
pr_read_spymaster_32(prnode_t * pnp,uio_t * uiop,cred_t * cr)2771 pr_read_spymaster_32(prnode_t *pnp, uio_t *uiop, cred_t *cr)
2772 {
2773 psinfo32_t psinfo;
2774 int error;
2775 klwp_t *lwp;
2776
2777 ASSERT(pnp->pr_type == PR_SPYMASTER);
2778
2779 if ((error = prlock(pnp, ZNO)) != 0)
2780 return (error);
2781
2782 if (pnp->pr_common->prc_thread == NULL) {
2783 prunlock(pnp);
2784 return (0);
2785 }
2786
2787 lwp = pnp->pr_common->prc_thread->t_lwp;
2788
2789 if (lwp->lwp_spymaster == NULL) {
2790 prunlock(pnp);
2791 return (0);
2792 }
2793
2794 psinfo_kto32(lwp->lwp_spymaster, &psinfo);
2795 prunlock(pnp);
2796
2797 return (pr_uioread(&psinfo, sizeof (psinfo), uiop));
2798 }
2799
2800 #if defined(__sparc)
2801 static int
pr_read_gwindows_32(prnode_t * pnp,uio_t * uiop,cred_t * cr)2802 pr_read_gwindows_32(prnode_t *pnp, uio_t *uiop, cred_t *cr)
2803 {
2804 proc_t *p;
2805 kthread_t *t;
2806 gwindows32_t *gwp;
2807 int error;
2808 size_t size;
2809
2810 ASSERT(pnp->pr_type == PR_GWINDOWS);
2811
2812 gwp = kmem_zalloc(sizeof (gwindows32_t), KM_SLEEP);
2813
2814 if ((error = prlock(pnp, ZNO)) != 0)
2815 goto out;
2816
2817 p = pnp->pr_common->prc_proc;
2818 t = pnp->pr_common->prc_thread;
2819
2820 if (PROCESS_NOT_32BIT(p)) {
2821 prunlock(pnp);
2822 error = EOVERFLOW;
2823 goto out;
2824 }
2825
2826 /*
2827 * Drop p->p_lock while touching the stack.
2828 * The P_PR_LOCK flag prevents the lwp from
2829 * disappearing while we do this.
2830 */
2831 mutex_exit(&p->p_lock);
2832 if ((size = prnwindows(ttolwp(t))) != 0)
2833 size = sizeof (gwindows32_t) -
2834 (SPARC_MAXREGWINDOW - size) * sizeof (struct rwindow32);
2835 if (uiop->uio_offset >= size) {
2836 mutex_enter(&p->p_lock);
2837 prunlock(pnp);
2838 goto out;
2839 }
2840 prgetwindows32(ttolwp(t), gwp);
2841 mutex_enter(&p->p_lock);
2842 prunlock(pnp);
2843
2844 error = pr_uioread(gwp, size, uiop);
2845 out:
2846 kmem_free(gwp, sizeof (gwindows32_t));
2847 return (error);
2848 }
2849 #endif /* __sparc */
2850
2851 #endif /* _SYSCALL32_IMPL */
2852
2853 /* ARGSUSED */
2854 static int
prread(vnode_t * vp,uio_t * uiop,int ioflag,cred_t * cr,caller_context_t * ct)2855 prread(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *cr, caller_context_t *ct)
2856 {
2857 prnode_t *pnp = VTOP(vp);
2858
2859 ASSERT(pnp->pr_type < PR_NFILES);
2860
2861 #ifdef _SYSCALL32_IMPL
2862 /*
2863 * What is read from the /proc files depends on the data
2864 * model of the caller. An LP64 process will see LP64
2865 * data. An ILP32 process will see ILP32 data.
2866 */
2867 if (curproc->p_model == DATAMODEL_LP64)
2868 return (pr_read_function[pnp->pr_type](pnp, uiop, cr));
2869 else
2870 return (pr_read_function_32[pnp->pr_type](pnp, uiop, cr));
2871 #else
2872 return (pr_read_function[pnp->pr_type](pnp, uiop, cr));
2873 #endif
2874 }
2875
2876 /* Note we intentionally don't handle partial writes/updates. */
2877 static int
pr_write_lwpname(prnode_t * pnp,uio_t * uiop)2878 pr_write_lwpname(prnode_t *pnp, uio_t *uiop)
2879 {
2880 kthread_t *t = NULL;
2881 char *lwpname;
2882 int error;
2883
2884 lwpname = kmem_zalloc(THREAD_NAME_MAX, KM_SLEEP);
2885
2886 if ((error = uiomove(lwpname, THREAD_NAME_MAX, UIO_WRITE, uiop)) != 0) {
2887 kmem_free(lwpname, THREAD_NAME_MAX);
2888 return (error);
2889 }
2890
2891 /* Somebody tried to write too long a thread name... */
2892 if (lwpname[THREAD_NAME_MAX - 1] != '\0' || uiop->uio_resid > 0) {
2893 kmem_free(lwpname, THREAD_NAME_MAX);
2894 return (EIO);
2895 }
2896
2897 VERIFY3U(lwpname[THREAD_NAME_MAX - 1], ==, '\0');
2898
2899 for (size_t i = 0; lwpname[i] != '\0'; i++) {
2900 if (!ISPRINT(lwpname[i])) {
2901 kmem_free(lwpname, THREAD_NAME_MAX);
2902 return (EINVAL);
2903 }
2904 }
2905
2906 /* Equivalent of thread_setname(), but with the ZNO magic. */
2907 if ((error = prlock(pnp, ZNO)) != 0) {
2908 kmem_free(lwpname, THREAD_NAME_MAX);
2909 return (error);
2910 }
2911
2912 t = pnp->pr_common->prc_thread;
2913 if (t->t_name == NULL) {
2914 t->t_name = lwpname;
2915 } else {
2916 (void) strlcpy(t->t_name, lwpname, THREAD_NAME_MAX);
2917 kmem_free(lwpname, THREAD_NAME_MAX);
2918 }
2919
2920 prunlock(pnp);
2921 return (0);
2922 }
2923
2924 /* ARGSUSED */
2925 static int
prwrite(vnode_t * vp,uio_t * uiop,int ioflag,cred_t * cr,caller_context_t * ct)2926 prwrite(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *cr, caller_context_t *ct)
2927 {
2928 prnode_t *pnp = VTOP(vp);
2929 int old = 0;
2930 int error;
2931 ssize_t resid;
2932
2933 ASSERT(pnp->pr_type < PR_NFILES);
2934
2935 /*
2936 * Only a handful of /proc files are writable, enumerate them here.
2937 */
2938 switch (pnp->pr_type) {
2939 case PR_PIDDIR: /* directory write()s: visceral revulsion. */
2940 ASSERT(pnp->pr_pidfile != NULL);
2941 /* use the underlying PR_PIDFILE to write the process */
2942 vp = pnp->pr_pidfile;
2943 pnp = VTOP(vp);
2944 ASSERT(pnp->pr_type == PR_PIDFILE);
2945 /* FALLTHROUGH */
2946 case PR_PIDFILE:
2947 case PR_LWPIDFILE:
2948 old = 1;
2949 /* FALLTHROUGH */
2950 case PR_AS:
2951 if ((error = prlock(pnp, ZNO)) == 0) {
2952 proc_t *p = pnp->pr_common->prc_proc;
2953 struct as *as = p->p_as;
2954
2955 if ((p->p_flag & SSYS) || as == &kas) {
2956 /*
2957 * /proc I/O cannot be done to a system process.
2958 */
2959 error = EIO;
2960 #ifdef _SYSCALL32_IMPL
2961 } else if (curproc->p_model == DATAMODEL_ILP32 &&
2962 PROCESS_NOT_32BIT(p)) {
2963 error = EOVERFLOW;
2964 #endif
2965 } else {
2966 /*
2967 * See comments above (pr_read_pidfile)
2968 * about this locking dance.
2969 */
2970 mutex_exit(&p->p_lock);
2971 error = prusrio(p, UIO_WRITE, uiop, old);
2972 mutex_enter(&p->p_lock);
2973 }
2974 prunlock(pnp);
2975 }
2976 return (error);
2977
2978 case PR_CTL:
2979 case PR_LWPCTL:
2980 resid = uiop->uio_resid;
2981 /*
2982 * Perform the action on the control file
2983 * by passing curthreads credentials
2984 * and not target process's credentials.
2985 */
2986 #ifdef _SYSCALL32_IMPL
2987 if (curproc->p_model == DATAMODEL_ILP32)
2988 error = prwritectl32(vp, uiop, CRED());
2989 else
2990 error = prwritectl(vp, uiop, CRED());
2991 #else
2992 error = prwritectl(vp, uiop, CRED());
2993 #endif
2994 /*
2995 * This hack makes sure that the EINTR is passed
2996 * all the way back to the caller's write() call.
2997 */
2998 if (error == EINTR)
2999 uiop->uio_resid = resid;
3000 return (error);
3001
3002 case PR_LWPNAME:
3003 return (pr_write_lwpname(pnp, uiop));
3004
3005 default:
3006 return ((vp->v_type == VDIR)? EISDIR : EBADF);
3007 }
3008 /* NOTREACHED */
3009 }
3010
3011 static int
prgetattr(vnode_t * vp,vattr_t * vap,int flags,cred_t * cr,caller_context_t * ct)3012 prgetattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr,
3013 caller_context_t *ct)
3014 {
3015 prnode_t *pnp = VTOP(vp);
3016 prnodetype_t type = pnp->pr_type;
3017 prcommon_t *pcp;
3018 proc_t *p;
3019 struct as *as;
3020 int error;
3021 vnode_t *rvp;
3022 timestruc_t now;
3023 extern uint_t nproc;
3024 int ngroups;
3025 int nsig;
3026
3027 /*
3028 * This ugly bit of code allows us to keep both versions of this
3029 * function from the same source.
3030 */
3031 #ifdef _LP64
3032 int iam32bit = (curproc->p_model == DATAMODEL_ILP32);
3033 #define PR_OBJSIZE(obj32, obj64) \
3034 (iam32bit ? sizeof (obj32) : sizeof (obj64))
3035 #define PR_OBJSPAN(obj32, obj64) \
3036 (iam32bit ? LSPAN32(obj32) : LSPAN(obj64))
3037 #else
3038 #define PR_OBJSIZE(obj32, obj64) \
3039 (sizeof (obj64))
3040 #define PR_OBJSPAN(obj32, obj64) \
3041 (LSPAN(obj64))
3042 #endif
3043
3044 /*
3045 * Return all the attributes. Should be refined
3046 * so that it returns only those asked for.
3047 * Most of this is complete fakery anyway.
3048 */
3049
3050 /*
3051 * For files in the /proc/<pid>/object directory,
3052 * return the attributes of the underlying object.
3053 * For files in the /proc/<pid>/fd directory,
3054 * return the attributes of the underlying file, but
3055 * make it look inaccessible if it is not a regular file.
3056 * Make directories look like symlinks.
3057 */
3058 switch (type) {
3059 case PR_CURDIR:
3060 case PR_ROOTDIR:
3061 if (!(flags & ATTR_REAL))
3062 break;
3063 /* restrict full knowledge of the attributes to owner or root */
3064 if ((error = praccess(vp, 0, 0, cr, ct)) != 0)
3065 return (error);
3066 /* FALLTHROUGH */
3067 case PR_OBJECT:
3068 case PR_FD:
3069 rvp = pnp->pr_realvp;
3070 error = VOP_GETATTR(rvp, vap, flags, cr, ct);
3071 if (error)
3072 return (error);
3073 if (type == PR_FD) {
3074 if (rvp->v_type != VREG && rvp->v_type != VDIR)
3075 vap->va_mode = 0;
3076 else
3077 vap->va_mode &= pnp->pr_mode;
3078 }
3079 if (type == PR_OBJECT)
3080 vap->va_mode &= 07555;
3081 if (rvp->v_type == VDIR && !(flags & ATTR_REAL)) {
3082 vap->va_type = VLNK;
3083 vap->va_size = 0;
3084 vap->va_nlink = 1;
3085 }
3086 return (0);
3087 default:
3088 break;
3089 }
3090
3091 bzero(vap, sizeof (*vap));
3092 /*
3093 * Large Files: Internally proc now uses VPROC to indicate
3094 * a proc file. Since we have been returning VREG through
3095 * VOP_GETATTR() until now, we continue to do this so as
3096 * not to break apps depending on this return value.
3097 */
3098 vap->va_type = (vp->v_type == VPROC) ? VREG : vp->v_type;
3099 vap->va_mode = pnp->pr_mode;
3100 vap->va_fsid = vp->v_vfsp->vfs_dev;
3101 vap->va_blksize = DEV_BSIZE;
3102 vap->va_rdev = 0;
3103 vap->va_seq = 0;
3104
3105 if (type == PR_PROCDIR) {
3106 vap->va_uid = 0;
3107 vap->va_gid = 0;
3108 vap->va_nlink = nproc + 2;
3109 vap->va_nodeid = (ino64_t)PRROOTINO;
3110 gethrestime(&now);
3111 vap->va_atime = vap->va_mtime = vap->va_ctime = now;
3112 vap->va_size = (v.v_proc + 2) * PRSDSIZE;
3113 vap->va_nblocks = btod(vap->va_size);
3114 return (0);
3115 }
3116
3117 /*
3118 * /proc/<pid>/self is a symbolic link, and has no prcommon member
3119 */
3120 if (type == PR_SELF) {
3121 vap->va_uid = crgetruid(CRED());
3122 vap->va_gid = crgetrgid(CRED());
3123 vap->va_nodeid = (ino64_t)PR_SELF;
3124 gethrestime(&now);
3125 vap->va_atime = vap->va_mtime = vap->va_ctime = now;
3126 vap->va_nlink = 1;
3127 vap->va_type = VLNK;
3128 vap->va_size = 0;
3129 return (0);
3130 }
3131
3132 /* A subset of prlock(pnp...) */
3133 p = pr_p_lock(pnp);
3134 mutex_exit(&pr_pidlock);
3135 if (p == NULL)
3136 return (ENOENT);
3137 pcp = pnp->pr_common;
3138
3139 /*
3140 * Because we're performing a subset of prlock() inline here, we must
3141 * follow prlock's semantics when encountering a zombie process
3142 * (PRC_DESTROY flag is set) or an exiting process (SEXITING flag is
3143 * set). Those semantics indicate acting as if the process is no
3144 * longer there (return ENOENT).
3145 *
3146 * If we chose to proceed here regardless, we may encounter issues
3147 * when we drop the p_lock (see PR_OBJECTDIR, PR_PATHDIR, PR_*MAP,
3148 * PR_LDT, and PR_*PAGEDATA below). A process-cleanup which was
3149 * blocked on p_lock may ignore the P_PR_LOCK flag we set above, since
3150 * it set one of PRC_DESTROY or SEXITING. If the process then gets
3151 * destroyed our "p" will be useless, as will its p_lock.
3152 *
3153 * It may be desirable to move this check to only places further down
3154 * prior to actual droppages of p->p_lock, but for now, we're playing
3155 * it safe and checking here immediately, like prlock() does..
3156 */
3157 if (((pcp->prc_flags & PRC_DESTROY) || (p->p_flag & SEXITING))) {
3158 prunlock(pnp);
3159 return (ENOENT);
3160 }
3161
3162 mutex_enter(&p->p_crlock);
3163 vap->va_uid = crgetruid(p->p_cred);
3164 vap->va_gid = crgetrgid(p->p_cred);
3165 mutex_exit(&p->p_crlock);
3166
3167 vap->va_nlink = 1;
3168 vap->va_nodeid = pnp->pr_ino? pnp->pr_ino :
3169 pmkino(pcp->prc_tslot, pcp->prc_slot, pnp->pr_type);
3170 if ((pcp->prc_flags & PRC_LWP) && pcp->prc_tslot != -1) {
3171 vap->va_atime.tv_sec = vap->va_mtime.tv_sec =
3172 vap->va_ctime.tv_sec =
3173 p->p_lwpdir[pcp->prc_tslot].ld_entry->le_start;
3174 vap->va_atime.tv_nsec = vap->va_mtime.tv_nsec =
3175 vap->va_ctime.tv_nsec = 0;
3176 } else {
3177 user_t *up = PTOU(p);
3178 vap->va_atime.tv_sec = vap->va_mtime.tv_sec =
3179 vap->va_ctime.tv_sec = up->u_start.tv_sec;
3180 vap->va_atime.tv_nsec = vap->va_mtime.tv_nsec =
3181 vap->va_ctime.tv_nsec = up->u_start.tv_nsec;
3182 }
3183
3184 switch (type) {
3185 case PR_PIDDIR:
3186 /* va_nlink: count 'lwp', 'object' and 'fd' directory links */
3187 vap->va_nlink = 5;
3188 vap->va_size = sizeof (piddir);
3189 break;
3190 case PR_OBJECTDIR:
3191 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas)
3192 vap->va_size = 2 * PRSDSIZE;
3193 else {
3194 mutex_exit(&p->p_lock);
3195 AS_LOCK_ENTER(as, RW_WRITER);
3196 if (as->a_updatedir)
3197 rebuild_objdir(as);
3198 vap->va_size = (as->a_sizedir + 2) * PRSDSIZE;
3199 AS_LOCK_EXIT(as);
3200 mutex_enter(&p->p_lock);
3201 }
3202 vap->va_nlink = 2;
3203 break;
3204 case PR_PATHDIR:
3205 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas)
3206 vap->va_size = (P_FINFO(p)->fi_nfiles + 4) * PRSDSIZE;
3207 else {
3208 mutex_exit(&p->p_lock);
3209 AS_LOCK_ENTER(as, RW_WRITER);
3210 if (as->a_updatedir)
3211 rebuild_objdir(as);
3212 vap->va_size = (as->a_sizedir + 4 +
3213 P_FINFO(p)->fi_nfiles) * PRSDSIZE;
3214 AS_LOCK_EXIT(as);
3215 mutex_enter(&p->p_lock);
3216 }
3217 vap->va_nlink = 2;
3218 break;
3219 case PR_PATH:
3220 case PR_CURDIR:
3221 case PR_ROOTDIR:
3222 case PR_CT:
3223 vap->va_type = VLNK;
3224 vap->va_size = 0;
3225 break;
3226 case PR_FDDIR:
3227 case PR_FDINFODIR:
3228 vap->va_nlink = 2;
3229 vap->va_size = (P_FINFO(p)->fi_nfiles + 2) * PRSDSIZE;
3230 break;
3231 case PR_FDINFO: {
3232 file_t *fp;
3233 int fd = pnp->pr_index;
3234
3235 fp = pr_getf(p, fd, NULL);
3236 if (fp == NULL) {
3237 prunlock(pnp);
3238 return (ENOENT);
3239 }
3240 prunlock(pnp);
3241 vap->va_size = prgetfdinfosize(p, fp->f_vnode, cr);
3242 vap->va_nblocks = (fsblkcnt64_t)btod(vap->va_size);
3243 pr_releasef(fp);
3244 return (0);
3245 }
3246 case PR_LWPDIR:
3247 /*
3248 * va_nlink: count each lwp as a directory link.
3249 * va_size: size of p_lwpdir + 2
3250 */
3251 vap->va_nlink = p->p_lwpcnt + p->p_zombcnt + 2;
3252 vap->va_size = (p->p_lwpdir_sz + 2) * PRSDSIZE;
3253 break;
3254 case PR_LWPIDDIR:
3255 vap->va_nlink = 2;
3256 vap->va_size = sizeof (lwpiddir);
3257 break;
3258 case PR_CTDIR:
3259 vap->va_nlink = 2;
3260 vap->va_size = (avl_numnodes(&p->p_ct_held) + 2) * PRSDSIZE;
3261 break;
3262 case PR_TMPLDIR:
3263 vap->va_nlink = 2;
3264 vap->va_size = (ct_ntypes + 2) * PRSDSIZE;
3265 break;
3266 case PR_AS:
3267 case PR_PIDFILE:
3268 case PR_LWPIDFILE:
3269 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas)
3270 vap->va_size = 0;
3271 else
3272 vap->va_size = as->a_resvsize;
3273 break;
3274 case PR_STATUS:
3275 vap->va_size = PR_OBJSIZE(pstatus32_t, pstatus_t);
3276 break;
3277 case PR_LSTATUS:
3278 vap->va_size = PR_OBJSIZE(prheader32_t, prheader_t) +
3279 p->p_lwpcnt * PR_OBJSPAN(lwpstatus32_t, lwpstatus_t);
3280 break;
3281 case PR_PSINFO:
3282 vap->va_size = PR_OBJSIZE(psinfo32_t, psinfo_t);
3283 break;
3284 case PR_LPSINFO:
3285 vap->va_size = PR_OBJSIZE(prheader32_t, prheader_t) +
3286 (p->p_lwpcnt + p->p_zombcnt) *
3287 PR_OBJSPAN(lwpsinfo32_t, lwpsinfo_t);
3288 break;
3289 case PR_MAP:
3290 case PR_RMAP:
3291 case PR_XMAP:
3292 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas)
3293 vap->va_size = 0;
3294 else {
3295 mutex_exit(&p->p_lock);
3296 AS_LOCK_ENTER(as, RW_WRITER);
3297 if (type == PR_MAP)
3298 vap->va_mtime = as->a_updatetime;
3299 if (type == PR_XMAP)
3300 vap->va_size = prnsegs(as, 0) *
3301 PR_OBJSIZE(prxmap32_t, prxmap_t);
3302 else
3303 vap->va_size = prnsegs(as, type == PR_RMAP) *
3304 PR_OBJSIZE(prmap32_t, prmap_t);
3305 AS_LOCK_EXIT(as);
3306 mutex_enter(&p->p_lock);
3307 }
3308 break;
3309 case PR_CRED:
3310 mutex_enter(&p->p_crlock);
3311 vap->va_size = sizeof (prcred_t);
3312 ngroups = crgetngroups(p->p_cred);
3313 if (ngroups > 1)
3314 vap->va_size += (ngroups - 1) * sizeof (gid_t);
3315 mutex_exit(&p->p_crlock);
3316 break;
3317 case PR_PRIV:
3318 vap->va_size = prgetprivsize();
3319 break;
3320 case PR_SECFLAGS:
3321 vap->va_size = sizeof (prsecflags_t);
3322 break;
3323 case PR_SIGACT:
3324 nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG;
3325 vap->va_size = (nsig-1) *
3326 PR_OBJSIZE(struct sigaction32, struct sigaction);
3327 break;
3328 case PR_AUXV:
3329 vap->va_size = __KERN_NAUXV_IMPL * PR_OBJSIZE(auxv32_t, auxv_t);
3330 break;
3331 #if defined(__x86)
3332 case PR_LDT:
3333 mutex_exit(&p->p_lock);
3334 mutex_enter(&p->p_ldtlock);
3335 vap->va_size = prnldt(p) * sizeof (struct ssd);
3336 mutex_exit(&p->p_ldtlock);
3337 mutex_enter(&p->p_lock);
3338 break;
3339 #endif
3340 case PR_USAGE:
3341 vap->va_size = PR_OBJSIZE(prusage32_t, prusage_t);
3342 break;
3343 case PR_LUSAGE:
3344 vap->va_size = PR_OBJSIZE(prheader32_t, prheader_t) +
3345 (p->p_lwpcnt + 1) * PR_OBJSPAN(prusage32_t, prusage_t);
3346 break;
3347 case PR_PAGEDATA:
3348 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas)
3349 vap->va_size = 0;
3350 else {
3351 /*
3352 * We can drop p->p_lock before grabbing the
3353 * address space lock because p->p_as will not
3354 * change while the process is marked P_PR_LOCK.
3355 */
3356 mutex_exit(&p->p_lock);
3357 AS_LOCK_ENTER(as, RW_WRITER);
3358 #ifdef _LP64
3359 vap->va_size = iam32bit?
3360 prpdsize32(as) : prpdsize(as);
3361 #else
3362 vap->va_size = prpdsize(as);
3363 #endif
3364 AS_LOCK_EXIT(as);
3365 mutex_enter(&p->p_lock);
3366 }
3367 break;
3368 case PR_OPAGEDATA:
3369 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas)
3370 vap->va_size = 0;
3371 else {
3372 mutex_exit(&p->p_lock);
3373 AS_LOCK_ENTER(as, RW_WRITER);
3374 #ifdef _LP64
3375 vap->va_size = iam32bit?
3376 oprpdsize32(as) : oprpdsize(as);
3377 #else
3378 vap->va_size = oprpdsize(as);
3379 #endif
3380 AS_LOCK_EXIT(as);
3381 mutex_enter(&p->p_lock);
3382 }
3383 break;
3384 case PR_WATCH:
3385 vap->va_size = avl_numnodes(&p->p_warea) *
3386 PR_OBJSIZE(prwatch32_t, prwatch_t);
3387 break;
3388 case PR_LWPSTATUS:
3389 vap->va_size = PR_OBJSIZE(lwpstatus32_t, lwpstatus_t);
3390 break;
3391 case PR_LWPSINFO:
3392 vap->va_size = PR_OBJSIZE(lwpsinfo32_t, lwpsinfo_t);
3393 break;
3394 case PR_LWPUSAGE:
3395 vap->va_size = PR_OBJSIZE(prusage32_t, prusage_t);
3396 break;
3397 case PR_XREGS:
3398 if (prhasx(p))
3399 vap->va_size = prgetprxregsize(p);
3400 else
3401 vap->va_size = 0;
3402 break;
3403 case PR_SPYMASTER:
3404 if (pnp->pr_common->prc_thread != NULL &&
3405 pnp->pr_common->prc_thread->t_lwp->lwp_spymaster != NULL) {
3406 vap->va_size = PR_OBJSIZE(psinfo32_t, psinfo_t);
3407 } else {
3408 vap->va_size = 0;
3409 }
3410 break;
3411 #if defined(__sparc)
3412 case PR_GWINDOWS:
3413 {
3414 kthread_t *t;
3415 int n;
3416
3417 /*
3418 * If there is no lwp then just make the size zero.
3419 * This can happen if the lwp exits between the VOP_LOOKUP()
3420 * of the /proc/<pid>/lwp/<lwpid>/gwindows file and the
3421 * VOP_GETATTR() of the resulting vnode.
3422 */
3423 if ((t = pcp->prc_thread) == NULL) {
3424 vap->va_size = 0;
3425 break;
3426 }
3427 /*
3428 * Drop p->p_lock while touching the stack.
3429 * The P_PR_LOCK flag prevents the lwp from
3430 * disappearing while we do this.
3431 */
3432 mutex_exit(&p->p_lock);
3433 if ((n = prnwindows(ttolwp(t))) == 0)
3434 vap->va_size = 0;
3435 else
3436 vap->va_size = PR_OBJSIZE(gwindows32_t, gwindows_t) -
3437 (SPARC_MAXREGWINDOW - n) *
3438 PR_OBJSIZE(struct rwindow32, struct rwindow);
3439 mutex_enter(&p->p_lock);
3440 break;
3441 }
3442 case PR_ASRS:
3443 #ifdef _LP64
3444 if (p->p_model == DATAMODEL_LP64)
3445 vap->va_size = sizeof (asrset_t);
3446 else
3447 #endif
3448 vap->va_size = 0;
3449 break;
3450 #endif
3451 case PR_CTL:
3452 case PR_LWPCTL:
3453 default:
3454 vap->va_size = 0;
3455 break;
3456 }
3457
3458 prunlock(pnp);
3459 vap->va_nblocks = (fsblkcnt64_t)btod(vap->va_size);
3460 return (0);
3461 }
3462
3463 static int
praccess(vnode_t * vp,int mode,int flags,cred_t * cr,caller_context_t * ct)3464 praccess(vnode_t *vp, int mode, int flags, cred_t *cr, caller_context_t *ct)
3465 {
3466 prnode_t *pnp = VTOP(vp);
3467 prnodetype_t type = pnp->pr_type;
3468 int vmode;
3469 vtype_t vtype;
3470 proc_t *p;
3471 int error = 0;
3472 vnode_t *rvp;
3473 vnode_t *xvp;
3474
3475 if ((mode & VWRITE) && vn_is_readonly(vp))
3476 return (EROFS);
3477
3478 switch (type) {
3479 case PR_PROCDIR:
3480 break;
3481
3482 case PR_OBJECT:
3483 case PR_FD:
3484 /*
3485 * Disallow write access to the underlying objects.
3486 * Disallow access to underlying non-regular-file fds.
3487 * Disallow access to fds with other than existing open modes.
3488 */
3489 rvp = pnp->pr_realvp;
3490 vtype = rvp->v_type;
3491 vmode = pnp->pr_mode;
3492 if ((type == PR_OBJECT && (mode & VWRITE)) ||
3493 (type == PR_FD && vtype != VREG && vtype != VDIR) ||
3494 (type == PR_FD && (vmode & mode) != mode &&
3495 secpolicy_proc_access(cr) != 0))
3496 return (EACCES);
3497 return (VOP_ACCESS(rvp, mode, flags, cr, ct));
3498
3499 case PR_PSINFO: /* these files can be read by anyone */
3500 case PR_LPSINFO:
3501 case PR_LWPSINFO:
3502 case PR_LWPDIR:
3503 case PR_LWPIDDIR:
3504 case PR_USAGE:
3505 case PR_LUSAGE:
3506 case PR_LWPUSAGE:
3507 p = pr_p_lock(pnp);
3508 mutex_exit(&pr_pidlock);
3509 if (p == NULL)
3510 return (ENOENT);
3511 prunlock(pnp);
3512 break;
3513
3514 default:
3515 /*
3516 * Except for the world-readable files above,
3517 * only /proc/pid exists if the process is a zombie.
3518 */
3519 if ((error = prlock(pnp,
3520 (type == PR_PIDDIR)? ZYES : ZNO)) != 0)
3521 return (error);
3522 p = pnp->pr_common->prc_proc;
3523 if (p != curproc)
3524 error = priv_proc_cred_perm(cr, p, NULL, mode);
3525
3526 if (error != 0 || p == curproc || (p->p_flag & SSYS) ||
3527 p->p_as == &kas || (xvp = p->p_exec) == NULL) {
3528 prunlock(pnp);
3529 } else {
3530 /*
3531 * Determine if the process's executable is readable.
3532 * We have to drop p->p_lock before the secpolicy
3533 * and VOP operation.
3534 */
3535 VN_HOLD(xvp);
3536 prunlock(pnp);
3537 if (secpolicy_proc_access(cr) != 0)
3538 error = VOP_ACCESS(xvp, VREAD, 0, cr, ct);
3539 VN_RELE(xvp);
3540 }
3541 if (error)
3542 return (error);
3543 break;
3544 }
3545
3546 if (type == PR_CURDIR || type == PR_ROOTDIR) {
3547 /*
3548 * Final access check on the underlying directory vnode.
3549 */
3550 return (VOP_ACCESS(pnp->pr_realvp, mode, flags, cr, ct));
3551 }
3552
3553 /*
3554 * Visceral revulsion: For compatibility with old /proc,
3555 * allow the /proc/<pid> directory to be opened for writing.
3556 */
3557 vmode = pnp->pr_mode;
3558 if (type == PR_PIDDIR)
3559 vmode |= VWRITE;
3560 if ((vmode & mode) != mode)
3561 error = secpolicy_proc_access(cr);
3562 return (error);
3563 }
3564
3565 /*
3566 * Array of lookup functions, indexed by /proc file type.
3567 */
3568 static vnode_t *pr_lookup_notdir(), *pr_lookup_procdir(), *pr_lookup_piddir(),
3569 *pr_lookup_objectdir(), *pr_lookup_lwpdir(), *pr_lookup_lwpiddir(),
3570 *pr_lookup_fddir(), *pr_lookup_fdinfodir(), *pr_lookup_pathdir(),
3571 *pr_lookup_tmpldir(), *pr_lookup_ctdir();
3572
3573 static vnode_t *(*pr_lookup_function[PR_NFILES])() = {
3574 pr_lookup_procdir, /* /proc */
3575 pr_lookup_notdir, /* /proc/self */
3576 pr_lookup_piddir, /* /proc/<pid> */
3577 pr_lookup_notdir, /* /proc/<pid>/as */
3578 pr_lookup_notdir, /* /proc/<pid>/ctl */
3579 pr_lookup_notdir, /* /proc/<pid>/status */
3580 pr_lookup_notdir, /* /proc/<pid>/lstatus */
3581 pr_lookup_notdir, /* /proc/<pid>/psinfo */
3582 pr_lookup_notdir, /* /proc/<pid>/lpsinfo */
3583 pr_lookup_notdir, /* /proc/<pid>/map */
3584 pr_lookup_notdir, /* /proc/<pid>/rmap */
3585 pr_lookup_notdir, /* /proc/<pid>/xmap */
3586 pr_lookup_notdir, /* /proc/<pid>/cred */
3587 pr_lookup_notdir, /* /proc/<pid>/sigact */
3588 pr_lookup_notdir, /* /proc/<pid>/auxv */
3589 #if defined(__x86)
3590 pr_lookup_notdir, /* /proc/<pid>/ldt */
3591 #endif
3592 pr_lookup_notdir, /* /proc/<pid>/usage */
3593 pr_lookup_notdir, /* /proc/<pid>/lusage */
3594 pr_lookup_notdir, /* /proc/<pid>/pagedata */
3595 pr_lookup_notdir, /* /proc/<pid>/watch */
3596 pr_lookup_notdir, /* /proc/<pid>/cwd */
3597 pr_lookup_notdir, /* /proc/<pid>/root */
3598 pr_lookup_fddir, /* /proc/<pid>/fd */
3599 pr_lookup_notdir, /* /proc/<pid>/fd/nn */
3600 pr_lookup_fdinfodir, /* /proc/<pid>/fdinfo */
3601 pr_lookup_notdir, /* /proc/<pid>/fdinfo/nn */
3602 pr_lookup_objectdir, /* /proc/<pid>/object */
3603 pr_lookup_notdir, /* /proc/<pid>/object/xxx */
3604 pr_lookup_lwpdir, /* /proc/<pid>/lwp */
3605 pr_lookup_lwpiddir, /* /proc/<pid>/lwp/<lwpid> */
3606 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpctl */
3607 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpname */
3608 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpstatus */
3609 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
3610 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpusage */
3611 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/xregs */
3612 pr_lookup_tmpldir, /* /proc/<pid>/lwp/<lwpid>/templates */
3613 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
3614 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/spymaster */
3615 #if defined(__sparc)
3616 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/gwindows */
3617 pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/asrs */
3618 #endif
3619 pr_lookup_notdir, /* /proc/<pid>/priv */
3620 pr_lookup_pathdir, /* /proc/<pid>/path */
3621 pr_lookup_notdir, /* /proc/<pid>/path/xxx */
3622 pr_lookup_ctdir, /* /proc/<pid>/contracts */
3623 pr_lookup_notdir, /* /proc/<pid>/contracts/<ctid> */
3624 pr_lookup_notdir, /* /proc/<pid>/secflags */
3625 pr_lookup_notdir, /* old process file */
3626 pr_lookup_notdir, /* old lwp file */
3627 pr_lookup_notdir, /* old pagedata file */
3628 };
3629
3630 static int
prlookup(vnode_t * dp,char * comp,vnode_t ** vpp,pathname_t * pathp,int flags,vnode_t * rdir,cred_t * cr,caller_context_t * ct,int * direntflags,pathname_t * realpnp)3631 prlookup(vnode_t *dp, char *comp, vnode_t **vpp, pathname_t *pathp,
3632 int flags, vnode_t *rdir, cred_t *cr, caller_context_t *ct,
3633 int *direntflags, pathname_t *realpnp)
3634 {
3635 prnode_t *pnp = VTOP(dp);
3636 prnodetype_t type = pnp->pr_type;
3637 int error;
3638
3639 ASSERT(dp->v_type == VDIR);
3640 ASSERT(type < PR_NFILES);
3641
3642 if (type != PR_PROCDIR && strcmp(comp, "..") == 0) {
3643 VN_HOLD(pnp->pr_parent);
3644 *vpp = pnp->pr_parent;
3645 return (0);
3646 }
3647
3648 if (*comp == '\0' ||
3649 strcmp(comp, ".") == 0 || strcmp(comp, "..") == 0) {
3650 VN_HOLD(dp);
3651 *vpp = dp;
3652 return (0);
3653 }
3654
3655 switch (type) {
3656 case PR_CURDIR:
3657 case PR_ROOTDIR:
3658 /* restrict lookup permission to owner or root */
3659 if ((error = praccess(dp, VEXEC, 0, cr, ct)) != 0)
3660 return (error);
3661 /* FALLTHROUGH */
3662 case PR_FD:
3663 /*
3664 * Performing a VOP_LOOKUP on the underlying vnode and emitting
3665 * the resulting vnode, without encapsulation, as our own is a
3666 * very special case when it comes to the assumptions built
3667 * into VFS.
3668 *
3669 * Since the resulting vnode is highly likely to be at some
3670 * abitrary position in another filesystem, we insist that the
3671 * VTRAVERSE flag is set on the parent. This prevents things
3672 * such as the v_path freshness logic from mistaking the
3673 * resulting vnode as a "real" child of the parent, rather than
3674 * a consequence of this "procfs wormhole".
3675 *
3676 * Failure to establish such protections can lead to
3677 * incorrectly calculated v_paths being set on nodes reached
3678 * through these lookups.
3679 */
3680 ASSERT((dp->v_flag & VTRAVERSE) != 0);
3681
3682 dp = pnp->pr_realvp;
3683 return (VOP_LOOKUP(dp, comp, vpp, pathp, flags, rdir, cr, ct,
3684 direntflags, realpnp));
3685 default:
3686 break;
3687 }
3688
3689 if ((type == PR_OBJECTDIR || type == PR_FDDIR ||
3690 type == PR_FDINFODIR || type == PR_PATHDIR) &&
3691 (error = praccess(dp, VEXEC, 0, cr, ct)) != 0)
3692 return (error);
3693
3694 /* XXX - Do we need to pass ct, direntflags, or realpnp? */
3695 *vpp = (pr_lookup_function[type](dp, comp));
3696
3697 return ((*vpp == NULL) ? ENOENT : 0);
3698 }
3699
3700 /* ARGSUSED */
3701 static int
prcreate(vnode_t * dp,char * comp,vattr_t * vap,vcexcl_t excl,int mode,vnode_t ** vpp,cred_t * cr,int flag,caller_context_t * ct,vsecattr_t * vsecp)3702 prcreate(vnode_t *dp, char *comp, vattr_t *vap, vcexcl_t excl,
3703 int mode, vnode_t **vpp, cred_t *cr, int flag, caller_context_t *ct,
3704 vsecattr_t *vsecp)
3705 {
3706 int error;
3707
3708 if ((error = prlookup(dp, comp, vpp, NULL, 0, NULL, cr,
3709 ct, NULL, NULL)) != 0) {
3710 if (error == ENOENT) {
3711 /* One can't O_CREAT nonexistent files in /proc. */
3712 error = EACCES;
3713 }
3714 return (error);
3715 }
3716
3717 if (excl == EXCL) {
3718 /* Disallow the O_EXCL case */
3719 error = EEXIST;
3720 } else if ((error = praccess(*vpp, mode, 0, cr, ct)) == 0) {
3721 /* Before proceeding, handle O_TRUNC if necessary. */
3722 if (vap->va_mask & AT_SIZE) {
3723 vnode_t *vp = *vpp;
3724
3725 if (vp->v_type == VDIR) {
3726 /* Only allow O_TRUNC on files */
3727 error = EISDIR;
3728 } else if (vp->v_type != VPROC ||
3729 VTOP(vp)->pr_type != PR_FD) {
3730 /*
3731 * Disallow for files outside of the
3732 * /proc/<pid>/fd/<n> entries
3733 */
3734 error = EACCES;
3735 } else {
3736 uint_t mask;
3737
3738 vp = VTOP(vp)->pr_realvp;
3739 mask = vap->va_mask;
3740 vap->va_mask = AT_SIZE;
3741 error = VOP_SETATTR(vp, vap, 0, cr, ct);
3742 vap->va_mask = mask;
3743 }
3744 }
3745 }
3746
3747 if (error) {
3748 VN_RELE(*vpp);
3749 *vpp = NULL;
3750 }
3751 return (error);
3752 }
3753
3754 /* ARGSUSED */
3755 static vnode_t *
pr_lookup_notdir(vnode_t * dp,char * comp)3756 pr_lookup_notdir(vnode_t *dp, char *comp)
3757 {
3758 return (NULL);
3759 }
3760
3761 /*
3762 * Find or construct a process vnode for the given pid.
3763 */
3764 static vnode_t *
pr_lookup_procdir(vnode_t * dp,char * comp)3765 pr_lookup_procdir(vnode_t *dp, char *comp)
3766 {
3767 pid_t pid;
3768 prnode_t *pnp;
3769 prcommon_t *pcp;
3770 vnode_t *vp;
3771 proc_t *p;
3772 int c;
3773
3774 ASSERT(VTOP(dp)->pr_type == PR_PROCDIR);
3775
3776 if (strcmp(comp, "self") == 0) {
3777 pnp = prgetnode(dp, PR_SELF);
3778 return (PTOV(pnp));
3779 } else {
3780 pid = 0;
3781 while ((c = *comp++) != '\0') {
3782 if (c < '0' || c > '9')
3783 return (NULL);
3784 pid = 10*pid + c - '0';
3785 if (pid > maxpid)
3786 return (NULL);
3787 }
3788 }
3789
3790 pnp = prgetnode(dp, PR_PIDDIR);
3791
3792 mutex_enter(&pidlock);
3793 if ((p = prfind(pid)) == NULL || p->p_stat == SIDL) {
3794 mutex_exit(&pidlock);
3795 prfreenode(pnp);
3796 return (NULL);
3797 }
3798 ASSERT(p->p_stat != 0);
3799
3800 /* NOTE: we're holding pidlock across the policy call. */
3801 if (secpolicy_basic_procinfo(CRED(), p, curproc) != 0) {
3802 mutex_exit(&pidlock);
3803 prfreenode(pnp);
3804 return (NULL);
3805 }
3806
3807 mutex_enter(&p->p_lock);
3808 mutex_exit(&pidlock);
3809
3810 /*
3811 * If a process vnode already exists and it is not invalid
3812 * and it was created by the current process and it belongs
3813 * to the same /proc mount point as our parent vnode, then
3814 * just use it and discard the newly-allocated prnode.
3815 */
3816 for (vp = p->p_trace; vp != NULL; vp = VTOP(vp)->pr_next) {
3817 if (!(VTOP(VTOP(vp)->pr_pidfile)->pr_flags & PR_INVAL) &&
3818 VTOP(vp)->pr_owner == curproc &&
3819 vp->v_vfsp == dp->v_vfsp) {
3820 ASSERT(!(VTOP(vp)->pr_flags & PR_INVAL));
3821 VN_HOLD(vp);
3822 prfreenode(pnp);
3823 mutex_exit(&p->p_lock);
3824 return (vp);
3825 }
3826 }
3827 pnp->pr_owner = curproc;
3828
3829 /*
3830 * prgetnode() initialized most of the prnode.
3831 * Finish the job.
3832 */
3833 pcp = pnp->pr_common; /* the newly-allocated prcommon struct */
3834 if ((vp = p->p_trace) != NULL) {
3835 /* discard the new prcommon and use the existing prcommon */
3836 prfreecommon(pcp);
3837 pcp = VTOP(vp)->pr_common;
3838 mutex_enter(&pcp->prc_mutex);
3839 ASSERT(pcp->prc_refcnt > 0);
3840 pcp->prc_refcnt++;
3841 mutex_exit(&pcp->prc_mutex);
3842 pnp->pr_common = pcp;
3843 } else {
3844 /* initialize the new prcommon struct */
3845 if ((p->p_flag & SSYS) || p->p_as == &kas)
3846 pcp->prc_flags |= PRC_SYS;
3847 if (p->p_stat == SZOMB || (p->p_flag & SEXITING) != 0)
3848 pcp->prc_flags |= PRC_DESTROY;
3849 pcp->prc_proc = p;
3850 pcp->prc_datamodel = p->p_model;
3851 pcp->prc_pid = p->p_pid;
3852 pcp->prc_slot = p->p_slot;
3853 }
3854 pnp->pr_pcommon = pcp;
3855 pnp->pr_parent = dp;
3856 VN_HOLD(dp);
3857 /*
3858 * Link in the old, invalid directory vnode so we
3859 * can later determine the last close of the file.
3860 */
3861 pnp->pr_next = p->p_trace;
3862 p->p_trace = dp = PTOV(pnp);
3863
3864 /*
3865 * Kludge for old /proc: initialize the PR_PIDFILE as well.
3866 */
3867 vp = pnp->pr_pidfile;
3868 pnp = VTOP(vp);
3869 pnp->pr_ino = ptoi(pcp->prc_pid);
3870 pnp->pr_common = pcp;
3871 pnp->pr_pcommon = pcp;
3872 pnp->pr_parent = dp;
3873 pnp->pr_next = p->p_plist;
3874 p->p_plist = vp;
3875
3876 mutex_exit(&p->p_lock);
3877 return (dp);
3878 }
3879
3880 static vnode_t *
pr_lookup_piddir(vnode_t * dp,char * comp)3881 pr_lookup_piddir(vnode_t *dp, char *comp)
3882 {
3883 prnode_t *dpnp = VTOP(dp);
3884 vnode_t *vp;
3885 prnode_t *pnp;
3886 proc_t *p;
3887 user_t *up;
3888 prdirent_t *dirp;
3889 int i;
3890 enum prnodetype type;
3891
3892 ASSERT(dpnp->pr_type == PR_PIDDIR);
3893
3894 for (i = 0; i < NPIDDIRFILES; i++) {
3895 /* Skip "." and ".." */
3896 dirp = &piddir[i+2];
3897 if (strcmp(comp, dirp->d_name) == 0)
3898 break;
3899 }
3900
3901 if (i >= NPIDDIRFILES)
3902 return (NULL);
3903
3904 type = (int)dirp->d_ino;
3905 pnp = prgetnode(dp, type);
3906
3907 p = pr_p_lock(dpnp);
3908 mutex_exit(&pr_pidlock);
3909 if (p == NULL) {
3910 prfreenode(pnp);
3911 return (NULL);
3912 }
3913 if (dpnp->pr_pcommon->prc_flags & PRC_DESTROY) {
3914 switch (type) {
3915 case PR_PSINFO:
3916 case PR_USAGE:
3917 break;
3918 default:
3919 prunlock(dpnp);
3920 prfreenode(pnp);
3921 return (NULL);
3922 }
3923 }
3924
3925 switch (type) {
3926 case PR_CURDIR:
3927 case PR_ROOTDIR:
3928 up = PTOU(p);
3929 vp = (type == PR_CURDIR)? up->u_cdir :
3930 (up->u_rdir? up->u_rdir : rootdir);
3931
3932 if (vp == NULL) {
3933 /* can't happen(?) */
3934 prunlock(dpnp);
3935 prfreenode(pnp);
3936 return (NULL);
3937 }
3938 /*
3939 * Fill in the prnode so future references will
3940 * be able to find the underlying object's vnode.
3941 */
3942 VN_HOLD(vp);
3943 pnp->pr_realvp = vp;
3944 PTOV(pnp)->v_flag |= VTRAVERSE;
3945 break;
3946 default:
3947 break;
3948 }
3949
3950 mutex_enter(&dpnp->pr_mutex);
3951
3952 if ((vp = dpnp->pr_files[i]) != NULL &&
3953 !(VTOP(vp)->pr_flags & PR_INVAL)) {
3954 VN_HOLD(vp);
3955 mutex_exit(&dpnp->pr_mutex);
3956 prunlock(dpnp);
3957 prfreenode(pnp);
3958 return (vp);
3959 }
3960
3961 /*
3962 * prgetnode() initialized most of the prnode.
3963 * Finish the job.
3964 */
3965 pnp->pr_common = dpnp->pr_common;
3966 pnp->pr_pcommon = dpnp->pr_pcommon;
3967 pnp->pr_parent = dp;
3968 VN_HOLD(dp);
3969 pnp->pr_index = i;
3970
3971 dpnp->pr_files[i] = vp = PTOV(pnp);
3972
3973 /*
3974 * Link new vnode into list of all /proc vnodes for the process.
3975 */
3976 if (vp->v_type == VPROC) {
3977 pnp->pr_next = p->p_plist;
3978 p->p_plist = vp;
3979 }
3980 mutex_exit(&dpnp->pr_mutex);
3981 prunlock(dpnp);
3982 return (vp);
3983 }
3984
3985 static vnode_t *
pr_lookup_objectdir(vnode_t * dp,char * comp)3986 pr_lookup_objectdir(vnode_t *dp, char *comp)
3987 {
3988 prnode_t *dpnp = VTOP(dp);
3989 prnode_t *pnp;
3990 proc_t *p;
3991 struct seg *seg;
3992 struct as *as;
3993 vnode_t *vp;
3994 vattr_t vattr;
3995
3996 ASSERT(dpnp->pr_type == PR_OBJECTDIR);
3997
3998 pnp = prgetnode(dp, PR_OBJECT);
3999
4000 if (prlock(dpnp, ZNO) != 0) {
4001 prfreenode(pnp);
4002 return (NULL);
4003 }
4004 p = dpnp->pr_common->prc_proc;
4005 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) {
4006 prunlock(dpnp);
4007 prfreenode(pnp);
4008 return (NULL);
4009 }
4010
4011 /*
4012 * We drop p_lock before grabbing the address space lock
4013 * in order to avoid a deadlock with the clock thread.
4014 * The process will not disappear and its address space
4015 * will not change because it is marked P_PR_LOCK.
4016 */
4017 mutex_exit(&p->p_lock);
4018 AS_LOCK_ENTER(as, RW_READER);
4019 if ((seg = AS_SEGFIRST(as)) == NULL) {
4020 vp = NULL;
4021 goto out;
4022 }
4023 if (strcmp(comp, "a.out") == 0) {
4024 vp = p->p_exec;
4025 goto out;
4026 }
4027 do {
4028 /*
4029 * Manufacture a filename for the "object" directory.
4030 */
4031 vattr.va_mask = AT_FSID|AT_NODEID;
4032 if (seg->s_ops == &segvn_ops &&
4033 SEGOP_GETVP(seg, seg->s_base, &vp) == 0 &&
4034 vp != NULL && vp->v_type == VREG &&
4035 VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) == 0) {
4036 char name[64];
4037
4038 if (vp == p->p_exec) /* "a.out" */
4039 continue;
4040 pr_object_name(name, vp, &vattr);
4041 if (strcmp(name, comp) == 0)
4042 goto out;
4043 }
4044 } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
4045
4046 vp = NULL;
4047 out:
4048 if (vp != NULL) {
4049 VN_HOLD(vp);
4050 }
4051 AS_LOCK_EXIT(as);
4052 mutex_enter(&p->p_lock);
4053 prunlock(dpnp);
4054
4055 if (vp == NULL)
4056 prfreenode(pnp);
4057 else {
4058 /*
4059 * Fill in the prnode so future references will
4060 * be able to find the underlying object's vnode.
4061 * Don't link this prnode into the list of all
4062 * prnodes for the process; this is a one-use node.
4063 * Its use is entirely to catch and fail opens for writing.
4064 */
4065 pnp->pr_realvp = vp;
4066 vp = PTOV(pnp);
4067 }
4068
4069 return (vp);
4070 }
4071
4072 /*
4073 * Find or construct an lwp vnode for the given lwpid.
4074 */
4075 static vnode_t *
pr_lookup_lwpdir(vnode_t * dp,char * comp)4076 pr_lookup_lwpdir(vnode_t *dp, char *comp)
4077 {
4078 id_t tid; /* same type as t->t_tid */
4079 int want_agent;
4080 prnode_t *dpnp = VTOP(dp);
4081 prnode_t *pnp;
4082 prcommon_t *pcp;
4083 vnode_t *vp;
4084 proc_t *p;
4085 kthread_t *t;
4086 lwpdir_t *ldp;
4087 lwpent_t *lep;
4088 int tslot;
4089 int c;
4090
4091 ASSERT(dpnp->pr_type == PR_LWPDIR);
4092
4093 tid = 0;
4094 if (strcmp(comp, "agent") == 0)
4095 want_agent = 1;
4096 else {
4097 want_agent = 0;
4098 while ((c = *comp++) != '\0') {
4099 id_t otid;
4100
4101 if (c < '0' || c > '9')
4102 return (NULL);
4103 otid = tid;
4104 tid = 10*tid + c - '0';
4105 if (tid/10 != otid) /* integer overflow */
4106 return (NULL);
4107 }
4108 }
4109
4110 pnp = prgetnode(dp, PR_LWPIDDIR);
4111
4112 p = pr_p_lock(dpnp);
4113 mutex_exit(&pr_pidlock);
4114 if (p == NULL) {
4115 prfreenode(pnp);
4116 return (NULL);
4117 }
4118
4119 if (want_agent) {
4120 if ((t = p->p_agenttp) == NULL)
4121 lep = NULL;
4122 else {
4123 tid = t->t_tid;
4124 tslot = t->t_dslot;
4125 lep = p->p_lwpdir[tslot].ld_entry;
4126 }
4127 } else {
4128 if ((ldp = lwp_hash_lookup(p, tid)) == NULL)
4129 lep = NULL;
4130 else {
4131 tslot = (int)(ldp - p->p_lwpdir);
4132 lep = ldp->ld_entry;
4133 }
4134 }
4135
4136 if (lep == NULL) {
4137 prunlock(dpnp);
4138 prfreenode(pnp);
4139 return (NULL);
4140 }
4141
4142 /*
4143 * If an lwp vnode already exists and it is not invalid
4144 * and it was created by the current process and it belongs
4145 * to the same /proc mount point as our parent vnode, then
4146 * just use it and discard the newly-allocated prnode.
4147 */
4148 for (vp = lep->le_trace; vp != NULL; vp = VTOP(vp)->pr_next) {
4149 if (!(VTOP(vp)->pr_flags & PR_INVAL) &&
4150 VTOP(vp)->pr_owner == curproc &&
4151 vp->v_vfsp == dp->v_vfsp) {
4152 VN_HOLD(vp);
4153 prunlock(dpnp);
4154 prfreenode(pnp);
4155 return (vp);
4156 }
4157 }
4158 pnp->pr_owner = curproc;
4159
4160 /*
4161 * prgetnode() initialized most of the prnode.
4162 * Finish the job.
4163 */
4164 pcp = pnp->pr_common; /* the newly-allocated prcommon struct */
4165 if ((vp = lep->le_trace) != NULL) {
4166 /* discard the new prcommon and use the existing prcommon */
4167 prfreecommon(pcp);
4168 pcp = VTOP(vp)->pr_common;
4169 mutex_enter(&pcp->prc_mutex);
4170 ASSERT(pcp->prc_refcnt > 0);
4171 pcp->prc_refcnt++;
4172 mutex_exit(&pcp->prc_mutex);
4173 pnp->pr_common = pcp;
4174 } else {
4175 /* initialize the new prcommon struct */
4176 pcp->prc_flags |= PRC_LWP;
4177 if ((p->p_flag & SSYS) || p->p_as == &kas)
4178 pcp->prc_flags |= PRC_SYS;
4179 if ((t = lep->le_thread) == NULL)
4180 pcp->prc_flags |= PRC_DESTROY;
4181 pcp->prc_proc = p;
4182 pcp->prc_datamodel = dpnp->pr_pcommon->prc_datamodel;
4183 pcp->prc_pid = p->p_pid;
4184 pcp->prc_slot = p->p_slot;
4185 pcp->prc_thread = t;
4186 pcp->prc_tid = tid;
4187 pcp->prc_tslot = tslot;
4188 }
4189 pnp->pr_pcommon = dpnp->pr_pcommon;
4190 pnp->pr_parent = dp;
4191 VN_HOLD(dp);
4192 /*
4193 * Link in the old, invalid directory vnode so we
4194 * can later determine the last close of the file.
4195 */
4196 pnp->pr_next = lep->le_trace;
4197 lep->le_trace = vp = PTOV(pnp);
4198 prunlock(dpnp);
4199 return (vp);
4200 }
4201
4202 static vnode_t *
pr_lookup_lwpiddir(vnode_t * dp,char * comp)4203 pr_lookup_lwpiddir(vnode_t *dp, char *comp)
4204 {
4205 prnode_t *dpnp = VTOP(dp);
4206 vnode_t *vp;
4207 prnode_t *pnp;
4208 proc_t *p;
4209 prdirent_t *dirp;
4210 int i;
4211 enum prnodetype type;
4212
4213 ASSERT(dpnp->pr_type == PR_LWPIDDIR);
4214
4215 for (i = 0; i < NLWPIDDIRFILES; i++) {
4216 /* Skip "." and ".." */
4217 dirp = &lwpiddir[i+2];
4218 if (strcmp(comp, dirp->d_name) == 0)
4219 break;
4220 }
4221
4222 if (i >= NLWPIDDIRFILES)
4223 return (NULL);
4224
4225 type = (int)dirp->d_ino;
4226 pnp = prgetnode(dp, type);
4227
4228 p = pr_p_lock(dpnp);
4229 mutex_exit(&pr_pidlock);
4230 if (p == NULL) {
4231 prfreenode(pnp);
4232 return (NULL);
4233 }
4234 if (dpnp->pr_common->prc_flags & PRC_DESTROY) {
4235 /*
4236 * Only the lwpsinfo file is present for zombie lwps.
4237 * Nothing is present if the lwp has been reaped.
4238 */
4239 if (dpnp->pr_common->prc_tslot == -1 ||
4240 type != PR_LWPSINFO) {
4241 prunlock(dpnp);
4242 prfreenode(pnp);
4243 return (NULL);
4244 }
4245 }
4246
4247 #if defined(__sparc)
4248 /* the asrs file exists only for sparc v9 _LP64 processes */
4249 if (type == PR_ASRS && p->p_model != DATAMODEL_LP64) {
4250 prunlock(dpnp);
4251 prfreenode(pnp);
4252 return (NULL);
4253 }
4254 #endif
4255
4256 mutex_enter(&dpnp->pr_mutex);
4257
4258 if ((vp = dpnp->pr_files[i]) != NULL &&
4259 !(VTOP(vp)->pr_flags & PR_INVAL)) {
4260 VN_HOLD(vp);
4261 mutex_exit(&dpnp->pr_mutex);
4262 prunlock(dpnp);
4263 prfreenode(pnp);
4264 return (vp);
4265 }
4266
4267 /*
4268 * prgetnode() initialized most of the prnode.
4269 * Finish the job.
4270 */
4271 pnp->pr_common = dpnp->pr_common;
4272 pnp->pr_pcommon = dpnp->pr_pcommon;
4273 pnp->pr_parent = dp;
4274 VN_HOLD(dp);
4275 pnp->pr_index = i;
4276
4277 dpnp->pr_files[i] = vp = PTOV(pnp);
4278
4279 /*
4280 * Link new vnode into list of all /proc vnodes for the process.
4281 */
4282 if (vp->v_type == VPROC) {
4283 pnp->pr_next = p->p_plist;
4284 p->p_plist = vp;
4285 }
4286 mutex_exit(&dpnp->pr_mutex);
4287 prunlock(dpnp);
4288 return (vp);
4289 }
4290
4291 /*
4292 * Lookup one of the process's file vnodes.
4293 */
4294 static vnode_t *
pr_lookup_fddir(vnode_t * dp,char * comp)4295 pr_lookup_fddir(vnode_t *dp, char *comp)
4296 {
4297 prnode_t *dpnp = VTOP(dp);
4298 prnode_t *pnp;
4299 vnode_t *vp = NULL;
4300 proc_t *p;
4301 file_t *fp;
4302 uint_t fd;
4303 int c;
4304
4305 ASSERT(dpnp->pr_type == PR_FDDIR);
4306
4307 fd = 0;
4308 while ((c = *comp++) != '\0') {
4309 int ofd;
4310 if (c < '0' || c > '9')
4311 return (NULL);
4312 ofd = fd;
4313 fd = 10 * fd + c - '0';
4314 if (fd / 10 != ofd) /* integer overflow */
4315 return (NULL);
4316 }
4317
4318 pnp = prgetnode(dp, PR_FD);
4319
4320 if (prlock(dpnp, ZNO) != 0) {
4321 prfreenode(pnp);
4322 return (NULL);
4323 }
4324 p = dpnp->pr_common->prc_proc;
4325 if ((p->p_flag & SSYS) || p->p_as == &kas) {
4326 prunlock(dpnp);
4327 prfreenode(pnp);
4328 return (NULL);
4329 }
4330
4331 if ((fp = pr_getf(p, fd, NULL)) != NULL) {
4332 pnp->pr_mode = 07111;
4333 if (fp->f_flag & FREAD)
4334 pnp->pr_mode |= 0444;
4335 if (fp->f_flag & FWRITE)
4336 pnp->pr_mode |= 0222;
4337 vp = fp->f_vnode;
4338 VN_HOLD(vp);
4339 }
4340
4341 prunlock(dpnp);
4342 if (fp != NULL) {
4343 pr_releasef(fp);
4344 }
4345
4346 if (vp == NULL) {
4347 prfreenode(pnp);
4348 return (NULL);
4349 }
4350
4351 /*
4352 * Fill in the prnode so future references will
4353 * be able to find the underlying object's vnode.
4354 * Don't link this prnode into the list of all
4355 * prnodes for the process; this is a one-use node.
4356 */
4357 pnp->pr_realvp = vp;
4358 pnp->pr_parent = dp; /* needed for prlookup */
4359 VN_HOLD(dp);
4360 vp = PTOV(pnp);
4361 if (pnp->pr_realvp->v_type == VDIR) {
4362 vp->v_type = VDIR;
4363 vp->v_flag |= VTRAVERSE;
4364 }
4365
4366 return (vp);
4367 }
4368
4369 static vnode_t *
pr_lookup_fdinfodir(vnode_t * dp,char * comp)4370 pr_lookup_fdinfodir(vnode_t *dp, char *comp)
4371 {
4372 prnode_t *dpnp = VTOP(dp);
4373 prnode_t *pnp;
4374 vnode_t *vp = NULL;
4375 proc_t *p;
4376 uint_t fd;
4377 int c;
4378
4379 ASSERT(dpnp->pr_type == PR_FDINFODIR);
4380
4381 fd = 0;
4382 while ((c = *comp++) != '\0') {
4383 int ofd;
4384 if (c < '0' || c > '9')
4385 return (NULL);
4386 ofd = fd;
4387 fd = 10 * fd + c - '0';
4388 if (fd / 10 != ofd) /* integer overflow */
4389 return (NULL);
4390 }
4391
4392 pnp = prgetnode(dp, PR_FDINFO);
4393
4394 if (prlock(dpnp, ZNO) != 0) {
4395 prfreenode(pnp);
4396 return (NULL);
4397 }
4398 p = dpnp->pr_common->prc_proc;
4399 if ((p->p_flag & SSYS) || p->p_as == &kas) {
4400 prunlock(dpnp);
4401 prfreenode(pnp);
4402 return (NULL);
4403 }
4404
4405 /*
4406 * Don't link this prnode into the list of all
4407 * prnodes for the process; this is a one-use node.
4408 * Unlike the FDDIR case, the underlying vnode is not stored in
4409 * pnp->pr_realvp. Instead, the fd number is stored in pnp->pr_index
4410 * and used by pr_read_fdinfo() to return information for the right
4411 * file descriptor.
4412 */
4413 pnp->pr_common = dpnp->pr_common;
4414 pnp->pr_pcommon = dpnp->pr_pcommon;
4415 pnp->pr_parent = dp;
4416 pnp->pr_index = fd;
4417 VN_HOLD(dp);
4418 prunlock(dpnp);
4419 vp = PTOV(pnp);
4420
4421 return (vp);
4422 }
4423
4424 static vnode_t *
pr_lookup_pathdir(vnode_t * dp,char * comp)4425 pr_lookup_pathdir(vnode_t *dp, char *comp)
4426 {
4427 prnode_t *dpnp = VTOP(dp);
4428 prnode_t *pnp;
4429 vnode_t *vp = NULL;
4430 proc_t *p;
4431 uint_t fd, flags = 0;
4432 int c;
4433 uf_entry_t *ufp;
4434 uf_info_t *fip;
4435 enum { NAME_FD, NAME_OBJECT, NAME_ROOT, NAME_CWD, NAME_UNKNOWN } type;
4436 char *tmp;
4437 int idx;
4438 struct seg *seg;
4439 struct as *as = NULL;
4440 vattr_t vattr;
4441
4442 ASSERT(dpnp->pr_type == PR_PATHDIR);
4443
4444 /*
4445 * First, check if this is a numeric entry, in which case we have a
4446 * file descriptor.
4447 */
4448 fd = 0;
4449 type = NAME_FD;
4450 tmp = comp;
4451 while ((c = *tmp++) != '\0') {
4452 int ofd;
4453 if (c < '0' || c > '9') {
4454 type = NAME_UNKNOWN;
4455 break;
4456 }
4457 ofd = fd;
4458 fd = 10*fd + c - '0';
4459 if (fd/10 != ofd) { /* integer overflow */
4460 type = NAME_UNKNOWN;
4461 break;
4462 }
4463 }
4464
4465 /*
4466 * Next, see if it is one of the special values {root, cwd}.
4467 */
4468 if (type == NAME_UNKNOWN) {
4469 if (strcmp(comp, "root") == 0)
4470 type = NAME_ROOT;
4471 else if (strcmp(comp, "cwd") == 0)
4472 type = NAME_CWD;
4473 }
4474
4475 /*
4476 * Grab the necessary data from the process
4477 */
4478 if (prlock(dpnp, ZNO) != 0)
4479 return (NULL);
4480 p = dpnp->pr_common->prc_proc;
4481
4482 fip = P_FINFO(p);
4483
4484 switch (type) {
4485 case NAME_ROOT:
4486 if ((vp = PTOU(p)->u_rdir) == NULL)
4487 vp = p->p_zone->zone_rootvp;
4488 VN_HOLD(vp);
4489 break;
4490 case NAME_CWD:
4491 vp = PTOU(p)->u_cdir;
4492 VN_HOLD(vp);
4493 break;
4494 default:
4495 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) {
4496 prunlock(dpnp);
4497 return (NULL);
4498 }
4499 }
4500 mutex_exit(&p->p_lock);
4501
4502 /*
4503 * Determine if this is an object entry
4504 */
4505 if (type == NAME_UNKNOWN) {
4506 /*
4507 * Start with the inode index immediately after the number of
4508 * files.
4509 */
4510 mutex_enter(&fip->fi_lock);
4511 idx = fip->fi_nfiles + 4;
4512 mutex_exit(&fip->fi_lock);
4513
4514 if (strcmp(comp, "a.out") == 0) {
4515 if (p->p_execdir != NULL) {
4516 vp = p->p_execdir;
4517 VN_HOLD(vp);
4518 type = NAME_OBJECT;
4519 flags |= PR_AOUT;
4520 } else {
4521 vp = p->p_exec;
4522 VN_HOLD(vp);
4523 type = NAME_OBJECT;
4524 }
4525 } else {
4526 AS_LOCK_ENTER(as, RW_READER);
4527 if ((seg = AS_SEGFIRST(as)) != NULL) {
4528 do {
4529 /*
4530 * Manufacture a filename for the
4531 * "object" directory.
4532 */
4533 vattr.va_mask = AT_FSID|AT_NODEID;
4534 if (seg->s_ops == &segvn_ops &&
4535 SEGOP_GETVP(seg, seg->s_base, &vp)
4536 == 0 &&
4537 vp != NULL && vp->v_type == VREG &&
4538 VOP_GETATTR(vp, &vattr, 0, CRED(),
4539 NULL) == 0) {
4540 char name[64];
4541
4542 if (vp == p->p_exec)
4543 continue;
4544 idx++;
4545 pr_object_name(name, vp,
4546 &vattr);
4547 if (strcmp(name, comp) == 0)
4548 break;
4549 }
4550 } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
4551 }
4552
4553 if (seg == NULL) {
4554 vp = NULL;
4555 } else {
4556 VN_HOLD(vp);
4557 type = NAME_OBJECT;
4558 }
4559
4560 AS_LOCK_EXIT(as);
4561 }
4562 }
4563
4564
4565 switch (type) {
4566 case NAME_FD:
4567 mutex_enter(&fip->fi_lock);
4568 if (fd < fip->fi_nfiles) {
4569 UF_ENTER(ufp, fip, fd);
4570 if (ufp->uf_file != NULL) {
4571 vp = ufp->uf_file->f_vnode;
4572 VN_HOLD(vp);
4573 }
4574 UF_EXIT(ufp);
4575 }
4576 mutex_exit(&fip->fi_lock);
4577 idx = fd + 4;
4578 break;
4579 case NAME_ROOT:
4580 idx = 2;
4581 break;
4582 case NAME_CWD:
4583 idx = 3;
4584 break;
4585 case NAME_OBJECT:
4586 case NAME_UNKNOWN:
4587 /* Nothing to do */
4588 break;
4589 }
4590
4591 mutex_enter(&p->p_lock);
4592 prunlock(dpnp);
4593
4594 if (vp != NULL) {
4595 pnp = prgetnode(dp, PR_PATH);
4596
4597 pnp->pr_flags |= flags;
4598 pnp->pr_common = dpnp->pr_common;
4599 pnp->pr_pcommon = dpnp->pr_pcommon;
4600 pnp->pr_realvp = vp;
4601 pnp->pr_parent = dp; /* needed for prlookup */
4602 pnp->pr_ino = pmkino(idx, dpnp->pr_common->prc_slot, PR_PATH);
4603 VN_HOLD(dp);
4604 vp = PTOV(pnp);
4605 vp->v_type = VLNK;
4606 }
4607
4608 return (vp);
4609 }
4610
4611 /*
4612 * Look up one of the process's active templates.
4613 */
4614 static vnode_t *
pr_lookup_tmpldir(vnode_t * dp,char * comp)4615 pr_lookup_tmpldir(vnode_t *dp, char *comp)
4616 {
4617 prnode_t *dpnp = VTOP(dp);
4618 prnode_t *pnp;
4619 vnode_t *vp = NULL;
4620 proc_t *p;
4621 int i;
4622
4623 ASSERT(dpnp->pr_type == PR_TMPLDIR);
4624
4625 for (i = 0; i < ct_ntypes; i++)
4626 if (strcmp(comp, ct_types[i]->ct_type_name) == 0)
4627 break;
4628 if (i == ct_ntypes)
4629 return (NULL);
4630
4631 pnp = prgetnode(dp, PR_TMPL);
4632
4633 if (prlock(dpnp, ZNO) != 0) {
4634 prfreenode(pnp);
4635 return (NULL);
4636 }
4637 p = dpnp->pr_common->prc_proc;
4638 if ((p->p_flag & SSYS) || p->p_as == &kas ||
4639 (dpnp->pr_common->prc_flags & (PRC_DESTROY | PRC_LWP)) != PRC_LWP) {
4640 prunlock(dpnp);
4641 prfreenode(pnp);
4642 return (NULL);
4643 }
4644 if (ttolwp(dpnp->pr_common->prc_thread)->lwp_ct_active[i] != NULL) {
4645 pnp->pr_common = dpnp->pr_common;
4646 pnp->pr_pcommon = dpnp->pr_pcommon;
4647 pnp->pr_parent = dp;
4648 pnp->pr_cttype = i;
4649 VN_HOLD(dp);
4650 vp = PTOV(pnp);
4651 } else {
4652 prfreenode(pnp);
4653 }
4654 prunlock(dpnp);
4655
4656 return (vp);
4657 }
4658
4659 /*
4660 * Look up one of the contracts owned by the process.
4661 */
4662 static vnode_t *
pr_lookup_ctdir(vnode_t * dp,char * comp)4663 pr_lookup_ctdir(vnode_t *dp, char *comp)
4664 {
4665 prnode_t *dpnp = VTOP(dp);
4666 prnode_t *pnp;
4667 vnode_t *vp = NULL;
4668 proc_t *p;
4669 id_t id = 0;
4670 contract_t *ct;
4671 int c;
4672
4673 ASSERT(dpnp->pr_type == PR_CTDIR);
4674
4675 while ((c = *comp++) != '\0') {
4676 id_t oid;
4677 if (c < '0' || c > '9')
4678 return (NULL);
4679 oid = id;
4680 id = 10 * id + c - '0';
4681 if (id / 10 != oid) /* integer overflow */
4682 return (NULL);
4683 }
4684
4685 /*
4686 * Search all contracts; we'll filter below.
4687 */
4688 ct = contract_ptr(id, GLOBAL_ZONEUNIQID);
4689 if (ct == NULL)
4690 return (NULL);
4691
4692 pnp = prgetnode(dp, PR_CT);
4693
4694 if (prlock(dpnp, ZNO) != 0) {
4695 prfreenode(pnp);
4696 contract_rele(ct);
4697 return (NULL);
4698 }
4699 p = dpnp->pr_common->prc_proc;
4700 /*
4701 * We only allow lookups of contracts owned by this process, or,
4702 * if we are zsched and this is a zone's procfs, contracts on
4703 * stuff in the zone which are held by processes or contracts
4704 * outside the zone. (see logic in contract_status_common)
4705 */
4706 if ((ct->ct_owner != p) &&
4707 !(p == VTOZONE(dp)->zone_zsched && ct->ct_state < CTS_ORPHAN &&
4708 VTOZONE(dp)->zone_uniqid == contract_getzuniqid(ct) &&
4709 VTOZONE(dp)->zone_uniqid != GLOBAL_ZONEUNIQID &&
4710 ct->ct_czuniqid == GLOBAL_ZONEUNIQID)) {
4711 prunlock(dpnp);
4712 prfreenode(pnp);
4713 contract_rele(ct);
4714 return (NULL);
4715 }
4716 pnp->pr_common = dpnp->pr_common;
4717 pnp->pr_pcommon = dpnp->pr_pcommon;
4718 pnp->pr_contract = ct;
4719 pnp->pr_parent = dp;
4720 pnp->pr_ino = pmkino(id, pnp->pr_common->prc_slot, PR_CT);
4721 VN_HOLD(dp);
4722 prunlock(dpnp);
4723 vp = PTOV(pnp);
4724
4725 return (vp);
4726 }
4727
4728 /*
4729 * Construct an lwp vnode for the old /proc interface.
4730 * We stand on our head to make the /proc plumbing correct.
4731 */
4732 vnode_t *
prlwpnode(prnode_t * pnp,uint_t tid)4733 prlwpnode(prnode_t *pnp, uint_t tid)
4734 {
4735 char comp[12];
4736 vnode_t *dp;
4737 vnode_t *vp;
4738 prcommon_t *pcp;
4739 proc_t *p;
4740
4741 /*
4742 * Lookup the /proc/<pid>/lwp/<lwpid> directory vnode.
4743 */
4744 if (pnp->pr_type == PR_PIDFILE) {
4745 dp = pnp->pr_parent; /* /proc/<pid> */
4746 VN_HOLD(dp);
4747 vp = pr_lookup_piddir(dp, "lwp");
4748 VN_RELE(dp);
4749 if ((dp = vp) == NULL) /* /proc/<pid>/lwp */
4750 return (NULL);
4751 } else if (pnp->pr_type == PR_LWPIDFILE) {
4752 dp = pnp->pr_parent; /* /proc/<pid>/lwp/<lwpid> */
4753 dp = VTOP(dp)->pr_parent; /* /proc/<pid>/lwp */
4754 VN_HOLD(dp);
4755 } else {
4756 return (NULL);
4757 }
4758
4759 (void) pr_u32tos(tid, comp, sizeof (comp));
4760 vp = pr_lookup_lwpdir(dp, comp);
4761 VN_RELE(dp);
4762 if ((dp = vp) == NULL)
4763 return (NULL);
4764
4765 pnp = prgetnode(dp, PR_LWPIDFILE);
4766 vp = PTOV(pnp);
4767
4768 /*
4769 * prgetnode() initialized most of the prnode.
4770 * Finish the job.
4771 */
4772 pcp = VTOP(dp)->pr_common;
4773 pnp->pr_ino = ptoi(pcp->prc_pid);
4774 pnp->pr_common = pcp;
4775 pnp->pr_pcommon = VTOP(dp)->pr_pcommon;
4776 pnp->pr_parent = dp;
4777 /*
4778 * Link new vnode into list of all /proc vnodes for the process.
4779 */
4780 p = pr_p_lock(pnp);
4781 mutex_exit(&pr_pidlock);
4782 if (p == NULL) {
4783 VN_RELE(dp);
4784 prfreenode(pnp);
4785 vp = NULL;
4786 } else if (pcp->prc_thread == NULL) {
4787 prunlock(pnp);
4788 VN_RELE(dp);
4789 prfreenode(pnp);
4790 vp = NULL;
4791 } else {
4792 pnp->pr_next = p->p_plist;
4793 p->p_plist = vp;
4794 prunlock(pnp);
4795 }
4796
4797 return (vp);
4798 }
4799
4800 #if defined(DEBUG)
4801
4802 static uint32_t nprnode;
4803 static uint32_t nprcommon;
4804
4805 #define INCREMENT(x) atomic_inc_32(&x);
4806 #define DECREMENT(x) atomic_dec_32(&x);
4807
4808 #else
4809
4810 #define INCREMENT(x)
4811 #define DECREMENT(x)
4812
4813 #endif /* DEBUG */
4814
4815 /*
4816 * New /proc vnode required; allocate it and fill in most of the fields.
4817 */
4818 prnode_t *
prgetnode(vnode_t * dp,prnodetype_t type)4819 prgetnode(vnode_t *dp, prnodetype_t type)
4820 {
4821 prnode_t *pnp;
4822 prcommon_t *pcp;
4823 vnode_t *vp;
4824 ulong_t nfiles;
4825
4826 INCREMENT(nprnode);
4827 pnp = kmem_zalloc(sizeof (prnode_t), KM_SLEEP);
4828
4829 mutex_init(&pnp->pr_mutex, NULL, MUTEX_DEFAULT, NULL);
4830 pnp->pr_type = type;
4831
4832 pnp->pr_vnode = vn_alloc(KM_SLEEP);
4833
4834 vp = PTOV(pnp);
4835 vp->v_flag = VNOCACHE|VNOMAP|VNOSWAP|VNOMOUNT;
4836 vn_setops(vp, prvnodeops);
4837 vp->v_vfsp = dp->v_vfsp;
4838 vp->v_type = VPROC;
4839 vp->v_data = (caddr_t)pnp;
4840
4841 switch (type) {
4842 case PR_PIDDIR:
4843 case PR_LWPIDDIR:
4844 /*
4845 * We need a prcommon and a files array for each of these.
4846 */
4847 INCREMENT(nprcommon);
4848
4849 pcp = kmem_zalloc(sizeof (prcommon_t), KM_SLEEP);
4850 pcp->prc_refcnt = 1;
4851 pnp->pr_common = pcp;
4852 mutex_init(&pcp->prc_mutex, NULL, MUTEX_DEFAULT, NULL);
4853 cv_init(&pcp->prc_wait, NULL, CV_DEFAULT, NULL);
4854
4855 nfiles = (type == PR_PIDDIR)? NPIDDIRFILES : NLWPIDDIRFILES;
4856 pnp->pr_files =
4857 kmem_zalloc(nfiles * sizeof (vnode_t *), KM_SLEEP);
4858
4859 vp->v_type = VDIR;
4860 /*
4861 * Mode should be read-search by all, but we cannot so long
4862 * as we must support compatibility mode with old /proc.
4863 * Make /proc/<pid> be read by owner only, search by all.
4864 * Make /proc/<pid>/lwp/<lwpid> read-search by all. Also,
4865 * set VDIROPEN on /proc/<pid> so it can be opened for writing.
4866 */
4867 if (type == PR_PIDDIR) {
4868 /* kludge for old /proc interface */
4869 prnode_t *xpnp = prgetnode(dp, PR_PIDFILE);
4870 pnp->pr_pidfile = PTOV(xpnp);
4871 pnp->pr_mode = 0511;
4872 vp->v_flag |= VDIROPEN;
4873 } else {
4874 pnp->pr_mode = 0555;
4875 }
4876
4877 break;
4878
4879 case PR_CURDIR:
4880 case PR_ROOTDIR:
4881 case PR_FDDIR:
4882 case PR_FDINFODIR:
4883 case PR_OBJECTDIR:
4884 case PR_PATHDIR:
4885 case PR_CTDIR:
4886 case PR_TMPLDIR:
4887 vp->v_type = VDIR;
4888 pnp->pr_mode = 0500; /* read-search by owner only */
4889 break;
4890
4891 case PR_CT:
4892 vp->v_type = VLNK;
4893 pnp->pr_mode = 0500; /* read-search by owner only */
4894 break;
4895
4896 case PR_PATH:
4897 case PR_SELF:
4898 vp->v_type = VLNK;
4899 pnp->pr_mode = 0777;
4900 break;
4901
4902 case PR_LWPDIR:
4903 vp->v_type = VDIR;
4904 pnp->pr_mode = 0555; /* read-search by all */
4905 break;
4906
4907 case PR_AS:
4908 case PR_TMPL:
4909 pnp->pr_mode = 0600; /* read-write by owner only */
4910 break;
4911
4912 case PR_CTL:
4913 case PR_LWPCTL:
4914 pnp->pr_mode = 0200; /* write-only by owner only */
4915 break;
4916
4917 case PR_PIDFILE:
4918 case PR_LWPIDFILE:
4919 pnp->pr_mode = 0600; /* read-write by owner only */
4920 break;
4921
4922 case PR_LWPNAME:
4923 pnp->pr_mode = 0644; /* readable by all + owner can write */
4924 break;
4925
4926 case PR_PSINFO:
4927 case PR_LPSINFO:
4928 case PR_LWPSINFO:
4929 case PR_USAGE:
4930 case PR_LUSAGE:
4931 case PR_LWPUSAGE:
4932 pnp->pr_mode = 0444; /* read-only by all */
4933 break;
4934
4935 default:
4936 pnp->pr_mode = 0400; /* read-only by owner only */
4937 break;
4938 }
4939 vn_exists(vp);
4940 return (pnp);
4941 }
4942
4943 /*
4944 * Free the storage obtained from prgetnode().
4945 */
4946 void
prfreenode(prnode_t * pnp)4947 prfreenode(prnode_t *pnp)
4948 {
4949 vnode_t *vp;
4950 ulong_t nfiles;
4951
4952 vn_invalid(PTOV(pnp));
4953 vn_free(PTOV(pnp));
4954 mutex_destroy(&pnp->pr_mutex);
4955
4956 switch (pnp->pr_type) {
4957 case PR_PIDDIR:
4958 /* kludge for old /proc interface */
4959 if (pnp->pr_pidfile != NULL) {
4960 prfreenode(VTOP(pnp->pr_pidfile));
4961 pnp->pr_pidfile = NULL;
4962 }
4963 /* FALLTHROUGH */
4964 case PR_LWPIDDIR:
4965 /*
4966 * We allocated a prcommon and a files array for each of these.
4967 */
4968 prfreecommon(pnp->pr_common);
4969 nfiles = (pnp->pr_type == PR_PIDDIR)?
4970 NPIDDIRFILES : NLWPIDDIRFILES;
4971 kmem_free(pnp->pr_files, nfiles * sizeof (vnode_t *));
4972 break;
4973 default:
4974 break;
4975 }
4976 /*
4977 * If there is an underlying vnode, be sure
4978 * to release it after freeing the prnode.
4979 */
4980 vp = pnp->pr_realvp;
4981 kmem_free(pnp, sizeof (*pnp));
4982 DECREMENT(nprnode);
4983 if (vp != NULL) {
4984 VN_RELE(vp);
4985 }
4986 }
4987
4988 /*
4989 * Free a prcommon structure, if the reference count reaches zero.
4990 */
4991 static void
prfreecommon(prcommon_t * pcp)4992 prfreecommon(prcommon_t *pcp)
4993 {
4994 mutex_enter(&pcp->prc_mutex);
4995 ASSERT(pcp->prc_refcnt > 0);
4996 if (--pcp->prc_refcnt != 0)
4997 mutex_exit(&pcp->prc_mutex);
4998 else {
4999 mutex_exit(&pcp->prc_mutex);
5000
5001 ASSERT(pcp->prc_refcnt == 0);
5002 ASSERT(pcp->prc_selfopens == 0 && pcp->prc_writers == 0);
5003
5004 pollhead_clean(&pcp->prc_pollhead);
5005 mutex_destroy(&pcp->prc_mutex);
5006 cv_destroy(&pcp->prc_wait);
5007 kmem_free(pcp, sizeof (prcommon_t));
5008 DECREMENT(nprcommon);
5009 }
5010 }
5011
5012 /*
5013 * Array of readdir functions, indexed by /proc file type.
5014 */
5015 static int pr_readdir_notdir(), pr_readdir_procdir(), pr_readdir_piddir(),
5016 pr_readdir_objectdir(), pr_readdir_lwpdir(), pr_readdir_lwpiddir(),
5017 pr_readdir_fddir(), pr_readdir_fdinfodir(), pr_readdir_pathdir(),
5018 pr_readdir_tmpldir(), pr_readdir_ctdir();
5019
5020 static int (*pr_readdir_function[PR_NFILES])() = {
5021 pr_readdir_procdir, /* /proc */
5022 pr_readdir_notdir, /* /proc/self */
5023 pr_readdir_piddir, /* /proc/<pid> */
5024 pr_readdir_notdir, /* /proc/<pid>/as */
5025 pr_readdir_notdir, /* /proc/<pid>/ctl */
5026 pr_readdir_notdir, /* /proc/<pid>/status */
5027 pr_readdir_notdir, /* /proc/<pid>/lstatus */
5028 pr_readdir_notdir, /* /proc/<pid>/psinfo */
5029 pr_readdir_notdir, /* /proc/<pid>/lpsinfo */
5030 pr_readdir_notdir, /* /proc/<pid>/map */
5031 pr_readdir_notdir, /* /proc/<pid>/rmap */
5032 pr_readdir_notdir, /* /proc/<pid>/xmap */
5033 pr_readdir_notdir, /* /proc/<pid>/cred */
5034 pr_readdir_notdir, /* /proc/<pid>/sigact */
5035 pr_readdir_notdir, /* /proc/<pid>/auxv */
5036 #if defined(__x86)
5037 pr_readdir_notdir, /* /proc/<pid>/ldt */
5038 #endif
5039 pr_readdir_notdir, /* /proc/<pid>/usage */
5040 pr_readdir_notdir, /* /proc/<pid>/lusage */
5041 pr_readdir_notdir, /* /proc/<pid>/pagedata */
5042 pr_readdir_notdir, /* /proc/<pid>/watch */
5043 pr_readdir_notdir, /* /proc/<pid>/cwd */
5044 pr_readdir_notdir, /* /proc/<pid>/root */
5045 pr_readdir_fddir, /* /proc/<pid>/fd */
5046 pr_readdir_notdir, /* /proc/<pid>/fd/nn */
5047 pr_readdir_fdinfodir, /* /proc/<pid>/fdinfo */
5048 pr_readdir_notdir, /* /proc/<pid>/fdinfo/nn */
5049 pr_readdir_objectdir, /* /proc/<pid>/object */
5050 pr_readdir_notdir, /* /proc/<pid>/object/xxx */
5051 pr_readdir_lwpdir, /* /proc/<pid>/lwp */
5052 pr_readdir_lwpiddir, /* /proc/<pid>/lwp/<lwpid> */
5053 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpctl */
5054 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpname */
5055 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpstatus */
5056 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
5057 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpusage */
5058 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/xregs */
5059 pr_readdir_tmpldir, /* /proc/<pid>/lwp/<lwpid>/templates */
5060 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
5061 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/spymaster */
5062 #if defined(__sparc)
5063 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/gwindows */
5064 pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/asrs */
5065 #endif
5066 pr_readdir_notdir, /* /proc/<pid>/priv */
5067 pr_readdir_pathdir, /* /proc/<pid>/path */
5068 pr_readdir_notdir, /* /proc/<pid>/path/xxx */
5069 pr_readdir_ctdir, /* /proc/<pid>/contracts */
5070 pr_readdir_notdir, /* /proc/<pid>/contracts/<ctid> */
5071 pr_readdir_notdir, /* /proc/<pid>/secflags */
5072 pr_readdir_notdir, /* old process file */
5073 pr_readdir_notdir, /* old lwp file */
5074 pr_readdir_notdir, /* old pagedata file */
5075 };
5076
5077 /* ARGSUSED */
5078 static int
prreaddir(vnode_t * vp,uio_t * uiop,cred_t * cr,int * eofp,caller_context_t * ct,int flags)5079 prreaddir(vnode_t *vp, uio_t *uiop, cred_t *cr, int *eofp,
5080 caller_context_t *ct, int flags)
5081 {
5082 prnode_t *pnp = VTOP(vp);
5083
5084 ASSERT(pnp->pr_type < PR_NFILES);
5085
5086 /* XXX - Do we need to pass ct and flags? */
5087 return (pr_readdir_function[pnp->pr_type](pnp, uiop, eofp));
5088 }
5089
5090 /* ARGSUSED */
5091 static int
pr_readdir_notdir(prnode_t * pnp,uio_t * uiop,int * eofp)5092 pr_readdir_notdir(prnode_t *pnp, uio_t *uiop, int *eofp)
5093 {
5094 return (ENOTDIR);
5095 }
5096
5097 /* ARGSUSED */
5098 static int
pr_readdir_procdir(prnode_t * pnp,uio_t * uiop,int * eofp)5099 pr_readdir_procdir(prnode_t *pnp, uio_t *uiop, int *eofp)
5100 {
5101 zoneid_t zoneid;
5102 gfs_readdir_state_t gstate;
5103 int error, eof = 0;
5104 offset_t n;
5105
5106 ASSERT(pnp->pr_type == PR_PROCDIR);
5107
5108 zoneid = VTOZONE(PTOV(pnp))->zone_id;
5109
5110 if ((error = gfs_readdir_init(&gstate, PNSIZ, PRSDSIZE, uiop,
5111 PRROOTINO, PRROOTINO, 0)) != 0)
5112 return (error);
5113
5114 /*
5115 * Loop until user's request is satisfied or until all processes
5116 * have been examined.
5117 */
5118 while ((error = gfs_readdir_pred(&gstate, uiop, &n)) == 0) {
5119 uint_t pid;
5120 int pslot;
5121 proc_t *p;
5122
5123 /*
5124 * Find next entry. Skip processes not visible where
5125 * this /proc was mounted.
5126 */
5127 mutex_enter(&pidlock);
5128 while (n < v.v_proc &&
5129 ((p = pid_entry(n)) == NULL || p->p_stat == SIDL ||
5130 (zoneid != GLOBAL_ZONEID && p->p_zone->zone_id != zoneid) ||
5131 secpolicy_basic_procinfo(CRED(), p, curproc) != 0))
5132 n++;
5133
5134 /*
5135 * Stop when entire proc table has been examined.
5136 */
5137 if (n >= v.v_proc) {
5138 mutex_exit(&pidlock);
5139 eof = 1;
5140 break;
5141 }
5142
5143 ASSERT(p->p_stat != 0);
5144 pid = p->p_pid;
5145 pslot = p->p_slot;
5146 mutex_exit(&pidlock);
5147 error = gfs_readdir_emitn(&gstate, uiop, n,
5148 pmkino(0, pslot, PR_PIDDIR), pid);
5149 if (error)
5150 break;
5151 }
5152
5153 return (gfs_readdir_fini(&gstate, error, eofp, eof));
5154 }
5155
5156 /* ARGSUSED */
5157 static int
pr_readdir_piddir(prnode_t * pnp,uio_t * uiop,int * eofp)5158 pr_readdir_piddir(prnode_t *pnp, uio_t *uiop, int *eofp)
5159 {
5160 int zombie = ((pnp->pr_pcommon->prc_flags & PRC_DESTROY) != 0);
5161 prdirent_t dirent;
5162 prdirent_t *dirp;
5163 offset_t off;
5164 int error;
5165
5166 ASSERT(pnp->pr_type == PR_PIDDIR);
5167
5168 if (uiop->uio_offset < 0 ||
5169 uiop->uio_offset % sizeof (prdirent_t) != 0 ||
5170 uiop->uio_resid < sizeof (prdirent_t))
5171 return (EINVAL);
5172 if (pnp->pr_pcommon->prc_proc == NULL)
5173 return (ENOENT);
5174 if (uiop->uio_offset >= sizeof (piddir))
5175 goto out;
5176
5177 /*
5178 * Loop until user's request is satisfied, omitting some
5179 * files along the way if the process is a zombie.
5180 */
5181 for (dirp = &piddir[uiop->uio_offset / sizeof (prdirent_t)];
5182 uiop->uio_resid >= sizeof (prdirent_t) &&
5183 dirp < &piddir[NPIDDIRFILES+2];
5184 uiop->uio_offset = off + sizeof (prdirent_t), dirp++) {
5185 off = uiop->uio_offset;
5186 if (zombie) {
5187 switch (dirp->d_ino) {
5188 case PR_PIDDIR:
5189 case PR_PROCDIR:
5190 case PR_PSINFO:
5191 case PR_USAGE:
5192 break;
5193 default:
5194 continue;
5195 }
5196 }
5197 bcopy(dirp, &dirent, sizeof (prdirent_t));
5198 if (dirent.d_ino == PR_PROCDIR)
5199 dirent.d_ino = PRROOTINO;
5200 else
5201 dirent.d_ino = pmkino(0, pnp->pr_pcommon->prc_slot,
5202 dirent.d_ino);
5203 if ((error = uiomove((caddr_t)&dirent, sizeof (prdirent_t),
5204 UIO_READ, uiop)) != 0)
5205 return (error);
5206 }
5207 out:
5208 if (eofp)
5209 *eofp = (uiop->uio_offset >= sizeof (piddir));
5210 return (0);
5211 }
5212
5213 static void
rebuild_objdir(struct as * as)5214 rebuild_objdir(struct as *as)
5215 {
5216 struct seg *seg;
5217 vnode_t *vp;
5218 vattr_t vattr;
5219 vnode_t **dir;
5220 ulong_t nalloc;
5221 ulong_t nentries;
5222 int i, j;
5223 ulong_t nold, nnew;
5224
5225 ASSERT(AS_WRITE_HELD(as));
5226
5227 if (as->a_updatedir == 0 && as->a_objectdir != NULL)
5228 return;
5229 as->a_updatedir = 0;
5230
5231 if ((nalloc = avl_numnodes(&as->a_segtree)) == 0 ||
5232 (seg = AS_SEGFIRST(as)) == NULL) /* can't happen? */
5233 return;
5234
5235 /*
5236 * Allocate space for the new object directory.
5237 * (This is usually about two times too many entries.)
5238 */
5239 nalloc = (nalloc + 0xf) & ~0xf; /* multiple of 16 */
5240 dir = kmem_zalloc(nalloc * sizeof (vnode_t *), KM_SLEEP);
5241
5242 /* fill in the new directory with desired entries */
5243 nentries = 0;
5244 do {
5245 vattr.va_mask = AT_FSID|AT_NODEID;
5246 if (seg->s_ops == &segvn_ops &&
5247 SEGOP_GETVP(seg, seg->s_base, &vp) == 0 &&
5248 vp != NULL && vp->v_type == VREG &&
5249 VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) == 0) {
5250 for (i = 0; i < nentries; i++)
5251 if (vp == dir[i])
5252 break;
5253 if (i == nentries) {
5254 ASSERT(nentries < nalloc);
5255 dir[nentries++] = vp;
5256 }
5257 }
5258 } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
5259
5260 if (as->a_objectdir == NULL) { /* first time */
5261 as->a_objectdir = dir;
5262 as->a_sizedir = nalloc;
5263 return;
5264 }
5265
5266 /*
5267 * Null out all of the defunct entries in the old directory.
5268 */
5269 nold = 0;
5270 nnew = nentries;
5271 for (i = 0; i < as->a_sizedir; i++) {
5272 if ((vp = as->a_objectdir[i]) != NULL) {
5273 for (j = 0; j < nentries; j++) {
5274 if (vp == dir[j]) {
5275 dir[j] = NULL;
5276 nnew--;
5277 break;
5278 }
5279 }
5280 if (j == nentries)
5281 as->a_objectdir[i] = NULL;
5282 else
5283 nold++;
5284 }
5285 }
5286
5287 if (nold + nnew > as->a_sizedir) {
5288 /*
5289 * Reallocate the old directory to have enough
5290 * space for the old and new entries combined.
5291 * Round up to the next multiple of 16.
5292 */
5293 ulong_t newsize = (nold + nnew + 0xf) & ~0xf;
5294 vnode_t **newdir = kmem_zalloc(newsize * sizeof (vnode_t *),
5295 KM_SLEEP);
5296 bcopy(as->a_objectdir, newdir,
5297 as->a_sizedir * sizeof (vnode_t *));
5298 kmem_free(as->a_objectdir, as->a_sizedir * sizeof (vnode_t *));
5299 as->a_objectdir = newdir;
5300 as->a_sizedir = newsize;
5301 }
5302
5303 /*
5304 * Move all new entries to the old directory and
5305 * deallocate the space used by the new directory.
5306 */
5307 if (nnew) {
5308 for (i = 0, j = 0; i < nentries; i++) {
5309 if ((vp = dir[i]) == NULL)
5310 continue;
5311 for (; j < as->a_sizedir; j++) {
5312 if (as->a_objectdir[j] != NULL)
5313 continue;
5314 as->a_objectdir[j++] = vp;
5315 break;
5316 }
5317 }
5318 }
5319 kmem_free(dir, nalloc * sizeof (vnode_t *));
5320 }
5321
5322 /*
5323 * Return the vnode from a slot in the process's object directory.
5324 * The caller must have locked the process's address space.
5325 * The only caller is below, in pr_readdir_objectdir().
5326 */
5327 static vnode_t *
obj_entry(struct as * as,int slot)5328 obj_entry(struct as *as, int slot)
5329 {
5330 ASSERT(AS_LOCK_HELD(as));
5331 if (as->a_objectdir == NULL)
5332 return (NULL);
5333 ASSERT(slot < as->a_sizedir);
5334 return (as->a_objectdir[slot]);
5335 }
5336
5337 /* ARGSUSED */
5338 static int
pr_readdir_objectdir(prnode_t * pnp,uio_t * uiop,int * eofp)5339 pr_readdir_objectdir(prnode_t *pnp, uio_t *uiop, int *eofp)
5340 {
5341 gfs_readdir_state_t gstate;
5342 int error, eof = 0;
5343 offset_t n;
5344 int pslot;
5345 size_t objdirsize;
5346 proc_t *p;
5347 struct as *as;
5348 vnode_t *vp;
5349
5350 ASSERT(pnp->pr_type == PR_OBJECTDIR);
5351
5352 if ((error = prlock(pnp, ZNO)) != 0)
5353 return (error);
5354 p = pnp->pr_common->prc_proc;
5355 pslot = p->p_slot;
5356
5357 /*
5358 * We drop p_lock before grabbing the address space lock
5359 * in order to avoid a deadlock with the clock thread.
5360 * The process will not disappear and its address space
5361 * will not change because it is marked P_PR_LOCK.
5362 */
5363 mutex_exit(&p->p_lock);
5364
5365 if ((error = gfs_readdir_init(&gstate, 64, PRSDSIZE, uiop,
5366 pmkino(0, pslot, PR_PIDDIR),
5367 pmkino(0, pslot, PR_OBJECTDIR), 0)) != 0) {
5368 mutex_enter(&p->p_lock);
5369 prunlock(pnp);
5370 return (error);
5371 }
5372
5373 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) {
5374 as = NULL;
5375 objdirsize = 0;
5376 }
5377
5378 /*
5379 * Loop until user's request is satisfied or until
5380 * all mapped objects have been examined. Cannot hold
5381 * the address space lock for the following call as
5382 * gfs_readdir_pred() utimately causes a call to uiomove().
5383 */
5384 while ((error = gfs_readdir_pred(&gstate, uiop, &n)) == 0) {
5385 vattr_t vattr;
5386 char str[64];
5387
5388 /*
5389 * Set the correct size of the directory just
5390 * in case the process has changed it's address
5391 * space via mmap/munmap calls.
5392 */
5393 if (as != NULL) {
5394 AS_LOCK_ENTER(as, RW_WRITER);
5395 if (as->a_updatedir)
5396 rebuild_objdir(as);
5397 objdirsize = as->a_sizedir;
5398 }
5399
5400 /*
5401 * Find next object.
5402 */
5403 vattr.va_mask = AT_FSID | AT_NODEID;
5404 while (n < objdirsize && (((vp = obj_entry(as, n)) == NULL) ||
5405 (VOP_GETATTR(vp, &vattr, 0, CRED(), NULL)
5406 != 0))) {
5407 vattr.va_mask = AT_FSID | AT_NODEID;
5408 n++;
5409 }
5410
5411 if (as != NULL)
5412 AS_LOCK_EXIT(as);
5413
5414 /*
5415 * Stop when all objects have been reported.
5416 */
5417 if (n >= objdirsize) {
5418 eof = 1;
5419 break;
5420 }
5421
5422 if (vp == p->p_exec)
5423 (void) strcpy(str, "a.out");
5424 else
5425 pr_object_name(str, vp, &vattr);
5426
5427 error = gfs_readdir_emit(&gstate, uiop, n, vattr.va_nodeid,
5428 str, 0);
5429
5430 if (error)
5431 break;
5432 }
5433
5434 mutex_enter(&p->p_lock);
5435 prunlock(pnp);
5436
5437 return (gfs_readdir_fini(&gstate, error, eofp, eof));
5438 }
5439
5440 /* ARGSUSED */
5441 static int
pr_readdir_lwpdir(prnode_t * pnp,uio_t * uiop,int * eofp)5442 pr_readdir_lwpdir(prnode_t *pnp, uio_t *uiop, int *eofp)
5443 {
5444 gfs_readdir_state_t gstate;
5445 int error, eof = 0;
5446 offset_t tslot;
5447 proc_t *p;
5448 int pslot;
5449 lwpdir_t *lwpdir;
5450 int lwpdirsize;
5451
5452 ASSERT(pnp->pr_type == PR_LWPDIR);
5453
5454 p = pr_p_lock(pnp);
5455 mutex_exit(&pr_pidlock);
5456 if (p == NULL)
5457 return (ENOENT);
5458 ASSERT(p == pnp->pr_common->prc_proc);
5459 pslot = p->p_slot;
5460 lwpdir = p->p_lwpdir;
5461 lwpdirsize = p->p_lwpdir_sz;
5462
5463 /*
5464 * Drop p->p_lock so we can safely do uiomove().
5465 * The lwp directory will not change because
5466 * we have the process locked with P_PR_LOCK.
5467 */
5468 mutex_exit(&p->p_lock);
5469
5470
5471 if ((error = gfs_readdir_init(&gstate, PLNSIZ, PRSDSIZE, uiop,
5472 pmkino(0, pslot, PR_PIDDIR),
5473 pmkino(0, pslot, PR_LWPDIR), 0)) != 0) {
5474 mutex_enter(&p->p_lock);
5475 prunlock(pnp);
5476 return (error);
5477 }
5478
5479 /*
5480 * Loop until user's request is satisfied or until all lwps
5481 * have been examined.
5482 */
5483 while ((error = gfs_readdir_pred(&gstate, uiop, &tslot)) == 0) {
5484 lwpent_t *lep;
5485 uint_t tid;
5486
5487 /*
5488 * Find next LWP.
5489 */
5490 while (tslot < lwpdirsize &&
5491 ((lep = lwpdir[tslot].ld_entry) == NULL))
5492 tslot++;
5493 /*
5494 * Stop when all lwps have been reported.
5495 */
5496 if (tslot >= lwpdirsize) {
5497 eof = 1;
5498 break;
5499 }
5500
5501 tid = lep->le_lwpid;
5502 error = gfs_readdir_emitn(&gstate, uiop, tslot,
5503 pmkino(tslot, pslot, PR_LWPIDDIR), tid);
5504 if (error)
5505 break;
5506 }
5507
5508 mutex_enter(&p->p_lock);
5509 prunlock(pnp);
5510
5511 return (gfs_readdir_fini(&gstate, error, eofp, eof));
5512 }
5513
5514 /* ARGSUSED */
5515 static int
pr_readdir_lwpiddir(prnode_t * pnp,uio_t * uiop,int * eofp)5516 pr_readdir_lwpiddir(prnode_t *pnp, uio_t *uiop, int *eofp)
5517 {
5518 prcommon_t *pcp = pnp->pr_common;
5519 int zombie = ((pcp->prc_flags & PRC_DESTROY) != 0);
5520 prdirent_t dirent;
5521 prdirent_t *dirp;
5522 offset_t off;
5523 int error;
5524 int pslot;
5525 int tslot;
5526
5527 ASSERT(pnp->pr_type == PR_LWPIDDIR);
5528
5529 if (uiop->uio_offset < 0 ||
5530 uiop->uio_offset % sizeof (prdirent_t) != 0 ||
5531 uiop->uio_resid < sizeof (prdirent_t))
5532 return (EINVAL);
5533 if (pcp->prc_proc == NULL || pcp->prc_tslot == -1)
5534 return (ENOENT);
5535 if (uiop->uio_offset >= sizeof (lwpiddir))
5536 goto out;
5537
5538 /*
5539 * Loop until user's request is satisfied, omitting some files
5540 * along the way if the lwp is a zombie and also depending
5541 * on the data model of the process.
5542 */
5543 pslot = pcp->prc_slot;
5544 tslot = pcp->prc_tslot;
5545 for (dirp = &lwpiddir[uiop->uio_offset / sizeof (prdirent_t)];
5546 uiop->uio_resid >= sizeof (prdirent_t) &&
5547 dirp < &lwpiddir[NLWPIDDIRFILES+2];
5548 uiop->uio_offset = off + sizeof (prdirent_t), dirp++) {
5549 off = uiop->uio_offset;
5550 if (zombie) {
5551 switch (dirp->d_ino) {
5552 case PR_LWPIDDIR:
5553 case PR_LWPDIR:
5554 case PR_LWPSINFO:
5555 break;
5556 default:
5557 continue;
5558 }
5559 }
5560 #if defined(__sparc)
5561 /* the asrs file exists only for sparc v9 _LP64 processes */
5562 if (dirp->d_ino == PR_ASRS &&
5563 pcp->prc_datamodel != DATAMODEL_LP64)
5564 continue;
5565 #endif
5566 bcopy(dirp, &dirent, sizeof (prdirent_t));
5567 if (dirent.d_ino == PR_LWPDIR)
5568 dirent.d_ino = pmkino(0, pslot, dirp->d_ino);
5569 else
5570 dirent.d_ino = pmkino(tslot, pslot, dirp->d_ino);
5571 if ((error = uiomove((caddr_t)&dirent, sizeof (prdirent_t),
5572 UIO_READ, uiop)) != 0)
5573 return (error);
5574 }
5575 out:
5576 if (eofp)
5577 *eofp = (uiop->uio_offset >= sizeof (lwpiddir));
5578 return (0);
5579 }
5580
5581 /*
5582 * Helper function for reading a directory which lists open file desciptors
5583 */
5584 static int
pr_readdir_fdlist(prnode_t * pnp,uio_t * uiop,int * eofp,prnodetype_t dirtype,prnodetype_t entrytype)5585 pr_readdir_fdlist(prnode_t *pnp, uio_t *uiop, int *eofp,
5586 prnodetype_t dirtype, prnodetype_t entrytype)
5587 {
5588 gfs_readdir_state_t gstate;
5589 int error, eof = 0;
5590 offset_t n;
5591 proc_t *p;
5592 int pslot;
5593 int fddirsize;
5594 uf_info_t *fip;
5595
5596 if ((error = prlock(pnp, ZNO)) != 0)
5597 return (error);
5598 p = pnp->pr_common->prc_proc;
5599 pslot = p->p_slot;
5600 fip = P_FINFO(p);
5601 mutex_exit(&p->p_lock);
5602
5603 if ((error = gfs_readdir_init(&gstate, PLNSIZ, PRSDSIZE, uiop,
5604 pmkino(0, pslot, PR_PIDDIR), pmkino(0, pslot, dirtype), 0)) != 0) {
5605 mutex_enter(&p->p_lock);
5606 prunlock(pnp);
5607 return (error);
5608 }
5609
5610 mutex_enter(&fip->fi_lock);
5611 if ((p->p_flag & SSYS) || p->p_as == &kas)
5612 fddirsize = 0;
5613 else
5614 fddirsize = fip->fi_nfiles;
5615
5616 /*
5617 * Loop until user's request is satisfied or until
5618 * all file descriptors have been examined.
5619 */
5620 while ((error = gfs_readdir_pred(&gstate, uiop, &n)) == 0) {
5621 /*
5622 * Find next fd.
5623 */
5624 while (n < fddirsize && fip->fi_list[n].uf_file == NULL)
5625 n++;
5626 /*
5627 * Stop when all fds have been reported.
5628 */
5629 if (n >= fddirsize) {
5630 eof = 1;
5631 break;
5632 }
5633
5634 error = gfs_readdir_emitn(&gstate, uiop, n,
5635 pmkino(n, pslot, entrytype), n);
5636 if (error)
5637 break;
5638 }
5639
5640 mutex_exit(&fip->fi_lock);
5641 mutex_enter(&p->p_lock);
5642 prunlock(pnp);
5643
5644 return (gfs_readdir_fini(&gstate, error, eofp, eof));
5645 }
5646
5647 static int
pr_readdir_fddir(prnode_t * pnp,uio_t * uiop,int * eofp)5648 pr_readdir_fddir(prnode_t *pnp, uio_t *uiop, int *eofp)
5649 {
5650
5651 ASSERT(pnp->pr_type == PR_FDDIR);
5652
5653 return (pr_readdir_fdlist(pnp, uiop, eofp, pnp->pr_type, PR_FD));
5654 }
5655
5656 static int
pr_readdir_fdinfodir(prnode_t * pnp,uio_t * uiop,int * eofp)5657 pr_readdir_fdinfodir(prnode_t *pnp, uio_t *uiop, int *eofp)
5658 {
5659
5660 ASSERT(pnp->pr_type == PR_FDINFODIR);
5661
5662 return (pr_readdir_fdlist(pnp, uiop, eofp, pnp->pr_type, PR_FDINFO));
5663 }
5664
5665 /* ARGSUSED */
5666 static int
pr_readdir_pathdir(prnode_t * pnp,uio_t * uiop,int * eofp)5667 pr_readdir_pathdir(prnode_t *pnp, uio_t *uiop, int *eofp)
5668 {
5669 longlong_t bp[DIRENT64_RECLEN(64) / sizeof (longlong_t)];
5670 dirent64_t *dirent = (dirent64_t *)bp;
5671 int reclen;
5672 ssize_t oresid;
5673 offset_t off, idx;
5674 int error = 0;
5675 proc_t *p;
5676 int fd, obj;
5677 int pslot;
5678 int fddirsize;
5679 uf_info_t *fip;
5680 struct as *as = NULL;
5681 size_t objdirsize;
5682 vattr_t vattr;
5683 vnode_t *vp;
5684
5685 ASSERT(pnp->pr_type == PR_PATHDIR);
5686
5687 if (uiop->uio_offset < 0 ||
5688 uiop->uio_resid <= 0 ||
5689 (uiop->uio_offset % PRSDSIZE) != 0)
5690 return (EINVAL);
5691 oresid = uiop->uio_resid;
5692 bzero(bp, sizeof (bp));
5693
5694 if ((error = prlock(pnp, ZNO)) != 0)
5695 return (error);
5696 p = pnp->pr_common->prc_proc;
5697 fip = P_FINFO(p);
5698 pslot = p->p_slot;
5699 mutex_exit(&p->p_lock);
5700
5701 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) {
5702 as = NULL;
5703 objdirsize = 0;
5704 } else {
5705 AS_LOCK_ENTER(as, RW_WRITER);
5706 if (as->a_updatedir)
5707 rebuild_objdir(as);
5708 objdirsize = as->a_sizedir;
5709 AS_LOCK_EXIT(as);
5710 as = NULL;
5711 }
5712
5713 mutex_enter(&fip->fi_lock);
5714 if ((p->p_flag & SSYS) || p->p_as == &kas)
5715 fddirsize = 0;
5716 else
5717 fddirsize = fip->fi_nfiles;
5718
5719 for (; uiop->uio_resid > 0; uiop->uio_offset = off + PRSDSIZE) {
5720 /*
5721 * There are 4 special files in the path directory: ".", "..",
5722 * "root", and "cwd". We handle those specially here.
5723 */
5724 off = uiop->uio_offset;
5725 idx = off / PRSDSIZE;
5726 if (off == 0) { /* "." */
5727 dirent->d_ino = pmkino(0, pslot, PR_PATHDIR);
5728 dirent->d_name[0] = '.';
5729 dirent->d_name[1] = '\0';
5730 reclen = DIRENT64_RECLEN(1);
5731 } else if (idx == 1) { /* ".." */
5732 dirent->d_ino = pmkino(0, pslot, PR_PIDDIR);
5733 dirent->d_name[0] = '.';
5734 dirent->d_name[1] = '.';
5735 dirent->d_name[2] = '\0';
5736 reclen = DIRENT64_RECLEN(2);
5737 } else if (idx == 2) { /* "root" */
5738 dirent->d_ino = pmkino(idx, pslot, PR_PATH);
5739 (void) strcpy(dirent->d_name, "root");
5740 reclen = DIRENT64_RECLEN(4);
5741 } else if (idx == 3) { /* "cwd" */
5742 dirent->d_ino = pmkino(idx, pslot, PR_PATH);
5743 (void) strcpy(dirent->d_name, "cwd");
5744 reclen = DIRENT64_RECLEN(3);
5745 } else if (idx < 4 + fddirsize) {
5746 /*
5747 * In this case, we have one of the file descriptors.
5748 */
5749 fd = idx - 4;
5750 if (fip->fi_list[fd].uf_file == NULL)
5751 continue;
5752 dirent->d_ino = pmkino(idx, pslot, PR_PATH);
5753 (void) pr_u32tos(fd, dirent->d_name, PLNSIZ+1);
5754 reclen = DIRENT64_RECLEN(PLNSIZ);
5755 } else if (idx < 4 + fddirsize + objdirsize) {
5756 if (fip != NULL) {
5757 mutex_exit(&fip->fi_lock);
5758 fip = NULL;
5759 }
5760
5761 /*
5762 * We drop p_lock before grabbing the address space lock
5763 * in order to avoid a deadlock with the clock thread.
5764 * The process will not disappear and its address space
5765 * will not change because it is marked P_PR_LOCK.
5766 */
5767 if (as == NULL) {
5768 as = p->p_as;
5769 AS_LOCK_ENTER(as, RW_WRITER);
5770 }
5771
5772 if (as->a_updatedir) {
5773 rebuild_objdir(as);
5774 objdirsize = as->a_sizedir;
5775 }
5776
5777 obj = idx - 4 - fddirsize;
5778 if ((vp = obj_entry(as, obj)) == NULL)
5779 continue;
5780 vattr.va_mask = AT_FSID|AT_NODEID;
5781 if (VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) != 0)
5782 continue;
5783 if (vp == p->p_exec)
5784 (void) strcpy(dirent->d_name, "a.out");
5785 else
5786 pr_object_name(dirent->d_name, vp, &vattr);
5787 dirent->d_ino = pmkino(idx, pslot, PR_PATH);
5788 reclen = DIRENT64_RECLEN(strlen(dirent->d_name));
5789 } else {
5790 break;
5791 }
5792
5793 dirent->d_off = uiop->uio_offset + PRSDSIZE;
5794 dirent->d_reclen = (ushort_t)reclen;
5795 if (reclen > uiop->uio_resid) {
5796 /*
5797 * Error if no entries have been returned yet.
5798 */
5799 if (uiop->uio_resid == oresid)
5800 error = EINVAL;
5801 break;
5802 }
5803 /*
5804 * Drop the address space lock to do the uiomove().
5805 */
5806 if (as != NULL)
5807 AS_LOCK_EXIT(as);
5808
5809 error = uiomove((caddr_t)dirent, reclen, UIO_READ, uiop);
5810 if (as != NULL)
5811 AS_LOCK_ENTER(as, RW_WRITER);
5812
5813 if (error)
5814 break;
5815 }
5816
5817 if (error == 0 && eofp)
5818 *eofp = (uiop->uio_offset >= (fddirsize + 2) * PRSDSIZE);
5819
5820 if (fip != NULL)
5821 mutex_exit(&fip->fi_lock);
5822 if (as != NULL)
5823 AS_LOCK_EXIT(as);
5824 mutex_enter(&p->p_lock);
5825 prunlock(pnp);
5826 return (error);
5827 }
5828
5829 static int
pr_readdir_tmpldir(prnode_t * pnp,uio_t * uiop,int * eofp)5830 pr_readdir_tmpldir(prnode_t *pnp, uio_t *uiop, int *eofp)
5831 {
5832 proc_t *p;
5833 int pslot, tslot;
5834 gfs_readdir_state_t gstate;
5835 int error, eof = 0;
5836 offset_t n;
5837
5838 ASSERT(pnp->pr_type == PR_TMPLDIR);
5839
5840 if ((error = prlock(pnp, ZNO)) != 0)
5841 return (error);
5842 p = pnp->pr_common->prc_proc;
5843 pslot = pnp->pr_common->prc_slot;
5844 tslot = pnp->pr_common->prc_tslot;
5845 mutex_exit(&p->p_lock);
5846
5847 if ((error = gfs_readdir_init(&gstate, PRDIRSIZE, PRSDSIZE, uiop,
5848 pmkino(tslot, pslot, PR_LWPDIR),
5849 pmkino(tslot, pslot, PR_TMPLDIR), 0)) != 0) {
5850 mutex_enter(&p->p_lock);
5851 prunlock(pnp);
5852 return (error);
5853 }
5854
5855 while ((error = gfs_readdir_pred(&gstate, uiop, &n)) == 0) {
5856 /*
5857 * Check for an active template. Reading a directory's
5858 * contents is already racy, so we don't bother taking
5859 * any locks.
5860 */
5861 while (n < ct_ntypes &&
5862 pnp->pr_common->prc_thread->t_lwp->lwp_ct_active[n] == NULL)
5863 n++;
5864 /*
5865 * Stop when all types have been reported.
5866 */
5867 if (n >= ct_ntypes) {
5868 eof = 1;
5869 break;
5870 }
5871 /*
5872 * The pmkino invocation below will need to be updated
5873 * when we create our fifth contract type.
5874 */
5875 ASSERT(ct_ntypes <= 4);
5876 error = gfs_readdir_emit(&gstate, uiop, n,
5877 pmkino((tslot << 2) | n, pslot, PR_TMPL),
5878 ct_types[n]->ct_type_name, 0);
5879 if (error)
5880 break;
5881 }
5882
5883 mutex_enter(&p->p_lock);
5884 prunlock(pnp);
5885
5886 return (gfs_readdir_fini(&gstate, error, eofp, eof));
5887 }
5888
5889 static int
pr_readdir_ctdir(prnode_t * pnp,uio_t * uiop,int * eofp)5890 pr_readdir_ctdir(prnode_t *pnp, uio_t *uiop, int *eofp)
5891 {
5892 proc_t *p;
5893 int pslot;
5894 gfs_readdir_state_t gstate;
5895 int error, eof = 0;
5896 offset_t n;
5897 uint64_t zid;
5898
5899 ASSERT(pnp->pr_type == PR_CTDIR);
5900
5901 if ((error = prlock(pnp, ZNO)) != 0)
5902 return (error);
5903 p = pnp->pr_common->prc_proc;
5904 pslot = p->p_slot;
5905 mutex_exit(&p->p_lock);
5906
5907 if ((error = gfs_readdir_init(&gstate, PRDIRSIZE, PRSDSIZE, uiop,
5908 pmkino(0, pslot, PR_PIDDIR), pmkino(0, pslot, PR_CTDIR), 0)) != 0) {
5909 mutex_enter(&p->p_lock);
5910 prunlock(pnp);
5911 return (error);
5912 }
5913
5914 zid = VTOZONE(pnp->pr_vnode)->zone_uniqid;
5915 while ((error = gfs_readdir_pred(&gstate, uiop, &n)) == 0) {
5916 id_t next = contract_plookup(p, n, zid);
5917 if (next == -1) {
5918 eof = 1;
5919 break;
5920 }
5921 error = gfs_readdir_emitn(&gstate, uiop, next,
5922 pmkino(next, pslot, PR_CT), next);
5923 if (error)
5924 break;
5925 }
5926
5927 mutex_enter(&p->p_lock);
5928 prunlock(pnp);
5929
5930 return (gfs_readdir_fini(&gstate, error, eofp, eof));
5931 }
5932
5933 /* ARGSUSED */
5934 static int
prfsync(vnode_t * vp,int syncflag,cred_t * cr,caller_context_t * ct)5935 prfsync(vnode_t *vp, int syncflag, cred_t *cr, caller_context_t *ct)
5936 {
5937 return (0);
5938 }
5939
5940 /*
5941 * Utility: remove a /proc vnode from a linked list, threaded through pr_next.
5942 */
5943 static void
pr_list_unlink(vnode_t * pvp,vnode_t ** listp)5944 pr_list_unlink(vnode_t *pvp, vnode_t **listp)
5945 {
5946 vnode_t *vp;
5947 prnode_t *pnp;
5948
5949 while ((vp = *listp) != NULL) {
5950 pnp = VTOP(vp);
5951 if (vp == pvp) {
5952 *listp = pnp->pr_next;
5953 pnp->pr_next = NULL;
5954 break;
5955 }
5956 listp = &pnp->pr_next;
5957 }
5958 }
5959
5960 /* ARGSUSED */
5961 static void
prinactive(vnode_t * vp,cred_t * cr,caller_context_t * ct)5962 prinactive(vnode_t *vp, cred_t *cr, caller_context_t *ct)
5963 {
5964 prnode_t *pnp = VTOP(vp);
5965 prnodetype_t type = pnp->pr_type;
5966 proc_t *p;
5967 vnode_t *dp;
5968 vnode_t *ovp = NULL;
5969 prnode_t *opnp = NULL;
5970
5971 switch (type) {
5972 case PR_OBJECT:
5973 case PR_FD:
5974 case PR_FDINFO:
5975 case PR_SELF:
5976 case PR_PATH:
5977 /* These are not linked into the usual lists */
5978 ASSERT(vp->v_count == 1);
5979 if ((dp = pnp->pr_parent) != NULL)
5980 VN_RELE(dp);
5981 prfreenode(pnp);
5982 return;
5983 default:
5984 break;
5985 }
5986
5987 mutex_enter(&pr_pidlock);
5988 if (pnp->pr_pcommon == NULL)
5989 p = NULL;
5990 else if ((p = pnp->pr_pcommon->prc_proc) != NULL)
5991 mutex_enter(&p->p_lock);
5992 mutex_enter(&vp->v_lock);
5993
5994 if (type == PR_PROCDIR || vp->v_count > 1) {
5995 VN_RELE_LOCKED(vp);
5996 mutex_exit(&vp->v_lock);
5997 if (p != NULL)
5998 mutex_exit(&p->p_lock);
5999 mutex_exit(&pr_pidlock);
6000 return;
6001 }
6002
6003 if ((dp = pnp->pr_parent) != NULL) {
6004 prnode_t *dpnp;
6005
6006 switch (type) {
6007 case PR_PIDFILE:
6008 case PR_LWPIDFILE:
6009 case PR_OPAGEDATA:
6010 break;
6011 default:
6012 dpnp = VTOP(dp);
6013 mutex_enter(&dpnp->pr_mutex);
6014 if (dpnp->pr_files != NULL &&
6015 dpnp->pr_files[pnp->pr_index] == vp)
6016 dpnp->pr_files[pnp->pr_index] = NULL;
6017 mutex_exit(&dpnp->pr_mutex);
6018 break;
6019 }
6020 pnp->pr_parent = NULL;
6021 }
6022
6023 ASSERT(vp->v_count == 1);
6024
6025 /*
6026 * If we allocated an old /proc/pid node, free it too.
6027 */
6028 if (pnp->pr_pidfile != NULL) {
6029 ASSERT(type == PR_PIDDIR);
6030 ovp = pnp->pr_pidfile;
6031 opnp = VTOP(ovp);
6032 ASSERT(opnp->pr_type == PR_PIDFILE);
6033 pnp->pr_pidfile = NULL;
6034 }
6035
6036 mutex_exit(&pr_pidlock);
6037
6038 if (p != NULL) {
6039 /*
6040 * Remove the vnodes from the lists of
6041 * /proc vnodes for the process.
6042 */
6043 int slot;
6044
6045 switch (type) {
6046 case PR_PIDDIR:
6047 pr_list_unlink(vp, &p->p_trace);
6048 break;
6049 case PR_LWPIDDIR:
6050 if ((slot = pnp->pr_common->prc_tslot) != -1) {
6051 lwpent_t *lep = p->p_lwpdir[slot].ld_entry;
6052 pr_list_unlink(vp, &lep->le_trace);
6053 }
6054 break;
6055 default:
6056 pr_list_unlink(vp, &p->p_plist);
6057 break;
6058 }
6059 if (ovp != NULL)
6060 pr_list_unlink(ovp, &p->p_plist);
6061 mutex_exit(&p->p_lock);
6062 }
6063
6064 mutex_exit(&vp->v_lock);
6065
6066 if (type == PR_CT && pnp->pr_contract != NULL) {
6067 contract_rele(pnp->pr_contract);
6068 pnp->pr_contract = NULL;
6069 }
6070
6071 if (opnp != NULL)
6072 prfreenode(opnp);
6073 prfreenode(pnp);
6074 if (dp != NULL) {
6075 VN_RELE(dp);
6076 }
6077 }
6078
6079 /* ARGSUSED */
6080 static int
prseek(vnode_t * vp,offset_t ooff,offset_t * noffp,caller_context_t * ct)6081 prseek(vnode_t *vp, offset_t ooff, offset_t *noffp, caller_context_t *ct)
6082 {
6083 return (0);
6084 }
6085
6086 /*
6087 * We use the p_execdir member of proc_t to expand the %d token in core file
6088 * paths (the directory path for the executable that dumped core; see
6089 * coreadm(8) for details). We'd like gcore(1) to be able to expand %d in
6090 * the same way as core dumping from the kernel, but there's no convenient
6091 * and comprehensible way to export the path name for p_execdir. To solve
6092 * this, we try to find the actual path to the executable that was used. In
6093 * pr_lookup_pathdir(), we mark the a.out path name vnode with the PR_AOUT
6094 * flag, and use that here to indicate that more work is needed beyond the
6095 * call to vnodetopath().
6096 */
6097 static int
prreadlink_lookup(prnode_t * pnp,char * buf,size_t size,cred_t * cr)6098 prreadlink_lookup(prnode_t *pnp, char *buf, size_t size, cred_t *cr)
6099 {
6100 proc_t *p;
6101 vnode_t *vp, *execvp, *vrootp;
6102 int ret;
6103 size_t len;
6104 dirent64_t *dp;
6105 size_t dlen = DIRENT64_RECLEN(MAXPATHLEN);
6106 char *dbuf;
6107
6108 p = curproc;
6109 mutex_enter(&p->p_lock);
6110 if ((vrootp = PTOU(p)->u_rdir) == NULL)
6111 vrootp = rootdir;
6112 VN_HOLD(vrootp);
6113 mutex_exit(&p->p_lock);
6114
6115 ret = vnodetopath(vrootp, pnp->pr_realvp, buf, size, cr);
6116
6117 /*
6118 * If PR_AOUT isn't set, then we looked up the path for the vnode;
6119 * otherwise, we looked up the path for (what we believe to be) the
6120 * containing directory.
6121 */
6122 if ((pnp->pr_flags & PR_AOUT) == 0) {
6123 VN_RELE(vrootp);
6124 return (ret);
6125 }
6126
6127 /*
6128 * Fail if there's a problem locking the process. This will only
6129 * occur if the process is changing so the information we would
6130 * report would already be invalid.
6131 */
6132 if (prlock(pnp, ZNO) != 0) {
6133 VN_RELE(vrootp);
6134 return (EIO);
6135 }
6136
6137 p = pnp->pr_common->prc_proc;
6138 mutex_exit(&p->p_lock);
6139
6140 execvp = p->p_exec;
6141 VN_HOLD(execvp);
6142
6143 /*
6144 * If our initial lookup of the directory failed, fall back to
6145 * the path name information for p_exec.
6146 */
6147 if (ret != 0) {
6148 mutex_enter(&p->p_lock);
6149 prunlock(pnp);
6150 ret = vnodetopath(vrootp, execvp, buf, size, cr);
6151 VN_RELE(execvp);
6152 VN_RELE(vrootp);
6153 return (ret);
6154 }
6155
6156 len = strlen(buf);
6157
6158 /*
6159 * We use u_comm as a guess for the last component of the full
6160 * executable path name. If there isn't going to be enough space
6161 * we fall back to using the p_exec so that we can have _an_
6162 * answer even if it's not perfect.
6163 */
6164 if (strlen(PTOU(p)->u_comm) + len + 1 < size) {
6165 buf[len] = '/';
6166 (void) strcpy(buf + len + 1, PTOU(p)->u_comm);
6167 mutex_enter(&p->p_lock);
6168 prunlock(pnp);
6169
6170 /*
6171 * Do a forward lookup of our u_comm guess.
6172 */
6173 if (lookupnameat(buf + len + 1, UIO_SYSSPACE, FOLLOW, NULLVPP,
6174 &vp, pnp->pr_realvp) == 0) {
6175 if (vn_compare(vp, execvp)) {
6176 VN_RELE(vp);
6177 VN_RELE(execvp);
6178 VN_RELE(vrootp);
6179 return (0);
6180 }
6181
6182 VN_RELE(vp);
6183 }
6184 } else {
6185 mutex_enter(&p->p_lock);
6186 prunlock(pnp);
6187 }
6188
6189 dbuf = kmem_alloc(dlen, KM_SLEEP);
6190
6191 /*
6192 * Try to find a matching vnode by iterating through the directory's
6193 * entries. If that fails, fall back to the path information for
6194 * p_exec.
6195 */
6196 if ((ret = dirfindvp(vrootp, pnp->pr_realvp, execvp, cr, dbuf,
6197 dlen, &dp)) == 0 && strlen(dp->d_name) + len + 1 < size) {
6198 buf[len] = '/';
6199 (void) strcpy(buf + len + 1, dp->d_name);
6200 } else {
6201 ret = vnodetopath(vrootp, execvp, buf, size, cr);
6202 }
6203
6204 kmem_free(dbuf, dlen);
6205 VN_RELE(execvp);
6206 VN_RELE(vrootp);
6207
6208 return (ret);
6209 }
6210
6211 /* ARGSUSED */
6212 static int
prreadlink(vnode_t * vp,uio_t * uiop,cred_t * cr,caller_context_t * ctp)6213 prreadlink(vnode_t *vp, uio_t *uiop, cred_t *cr, caller_context_t *ctp)
6214 {
6215 prnode_t *pnp = VTOP(vp);
6216 char *buf;
6217 int ret = EINVAL;
6218 char idbuf[16];
6219 int length, rlength;
6220 contract_t *ct;
6221
6222 switch (pnp->pr_type) {
6223 case PR_SELF:
6224 (void) snprintf(idbuf, sizeof (idbuf), "%d", curproc->p_pid);
6225 ret = uiomove(idbuf, strlen(idbuf), UIO_READ, uiop);
6226 break;
6227 case PR_OBJECT:
6228 case PR_FD:
6229 case PR_CURDIR:
6230 case PR_ROOTDIR:
6231 if (pnp->pr_realvp->v_type == VDIR)
6232 ret = 0;
6233 break;
6234 case PR_PATH:
6235 buf = kmem_alloc(MAXPATHLEN, KM_SLEEP);
6236
6237 if ((ret = prreadlink_lookup(pnp, buf, MAXPATHLEN, cr)) == 0)
6238 ret = uiomove(buf, strlen(buf), UIO_READ, uiop);
6239
6240 kmem_free(buf, MAXPATHLEN);
6241 break;
6242 case PR_CT:
6243 ASSERT(pnp->pr_contract != NULL);
6244 ct = pnp->pr_contract;
6245 length = sizeof (CTFS_ROOT "//") + sizeof (idbuf) +
6246 strlen(ct->ct_type->ct_type_name);
6247 buf = kmem_alloc(length, KM_SLEEP);
6248 rlength = snprintf(buf, length, CTFS_ROOT "/%s/%d",
6249 ct->ct_type->ct_type_name, ct->ct_id);
6250 ASSERT(rlength < length);
6251 ret = uiomove(buf, rlength, UIO_READ, uiop);
6252 kmem_free(buf, length);
6253 break;
6254 default:
6255 break;
6256 }
6257
6258 return (ret);
6259 }
6260
6261 /*ARGSUSED2*/
6262 static int
prcmp(vnode_t * vp1,vnode_t * vp2,caller_context_t * ct)6263 prcmp(vnode_t *vp1, vnode_t *vp2, caller_context_t *ct)
6264 {
6265 prnode_t *pp1, *pp2;
6266
6267 if (vp1 == vp2)
6268 return (1);
6269
6270 if (!vn_matchops(vp1, prvnodeops) || !vn_matchops(vp2, prvnodeops))
6271 return (0);
6272
6273 pp1 = VTOP(vp1);
6274 pp2 = VTOP(vp2);
6275
6276 if (pp1->pr_type != pp2->pr_type)
6277 return (0);
6278 if (pp1->pr_type == PR_PROCDIR)
6279 return (1);
6280 if (pp1->pr_ino || pp2->pr_ino)
6281 return (pp2->pr_ino == pp1->pr_ino);
6282
6283 if (pp1->pr_common == NULL || pp2->pr_common == NULL)
6284 return (0);
6285
6286 return (pp1->pr_common->prc_slot == pp2->pr_common->prc_slot &&
6287 pp1->pr_common->prc_tslot == pp2->pr_common->prc_tslot);
6288 }
6289
6290 static int
prrealvp(vnode_t * vp,vnode_t ** vpp,caller_context_t * ct)6291 prrealvp(vnode_t *vp, vnode_t **vpp, caller_context_t *ct)
6292 {
6293 vnode_t *rvp;
6294
6295 if ((rvp = VTOP(vp)->pr_realvp) != NULL) {
6296 vp = rvp;
6297 if (VOP_REALVP(vp, &rvp, ct) == 0)
6298 vp = rvp;
6299 }
6300
6301 *vpp = vp;
6302 return (0);
6303 }
6304
6305 /*
6306 * Return the answer requested to poll().
6307 * POLLIN, POLLRDNORM, and POLLOUT are recognized as in fs_poll().
6308 * In addition, these have special meaning for /proc files:
6309 * POLLPRI process or lwp stopped on an event of interest
6310 * POLLERR /proc file descriptor is invalid
6311 * POLLHUP process or lwp has terminated
6312 */
6313 /*ARGSUSED5*/
6314 static int
prpoll(vnode_t * vp,short events,int anyyet,short * reventsp,pollhead_t ** phpp,caller_context_t * ct)6315 prpoll(vnode_t *vp, short events, int anyyet, short *reventsp,
6316 pollhead_t **phpp, caller_context_t *ct)
6317 {
6318 prnode_t *pnp = VTOP(vp);
6319 prcommon_t *pcp = pnp->pr_common;
6320 pollhead_t *php = &pcp->prc_pollhead;
6321 proc_t *p;
6322 short revents;
6323 int error;
6324 int lockstate;
6325
6326 ASSERT(pnp->pr_type < PR_NFILES);
6327
6328 /*
6329 * Support for old /proc interface.
6330 */
6331 if (pnp->pr_pidfile != NULL) {
6332 vp = pnp->pr_pidfile;
6333 pnp = VTOP(vp);
6334 ASSERT(pnp->pr_type == PR_PIDFILE);
6335 ASSERT(pnp->pr_common == pcp);
6336 }
6337
6338 *reventsp = revents = 0;
6339 *phpp = (pollhead_t *)NULL;
6340
6341 if (vp->v_type == VDIR) {
6342 *reventsp |= POLLNVAL;
6343 return (0);
6344 }
6345
6346 /* avoid deadlock with prnotify() */
6347 if (pollunlock(&lockstate) != 0) {
6348 *reventsp = POLLNVAL;
6349 return (0);
6350 }
6351
6352 if ((error = prlock(pnp, ZNO)) != 0) {
6353 pollrelock(lockstate);
6354 switch (error) {
6355 case ENOENT: /* process or lwp died */
6356 *reventsp = POLLHUP;
6357 error = 0;
6358 break;
6359 case EAGAIN: /* invalidated */
6360 *reventsp = POLLERR;
6361 error = 0;
6362 break;
6363 }
6364 return (error);
6365 }
6366
6367 /*
6368 * We have the process marked locked (P_PR_LOCK) and we are holding
6369 * its p->p_lock. We want to unmark the process but retain
6370 * exclusive control w.r.t. other /proc controlling processes
6371 * before reacquiring the polling locks.
6372 *
6373 * prunmark() does this for us. It unmarks the process
6374 * but retains p->p_lock so we still have exclusive control.
6375 * We will drop p->p_lock at the end to relinquish control.
6376 *
6377 * We cannot call prunlock() at the end to relinquish control
6378 * because prunlock(), like prunmark(), may drop and reacquire
6379 * p->p_lock and that would lead to a lock order violation
6380 * w.r.t. the polling locks we are about to reacquire.
6381 */
6382 p = pcp->prc_proc;
6383 ASSERT(p != NULL);
6384 prunmark(p);
6385
6386 pollrelock(lockstate); /* reacquire dropped poll locks */
6387
6388 if ((p->p_flag & SSYS) || p->p_as == &kas)
6389 revents = POLLNVAL;
6390 else {
6391 short ev;
6392
6393 if ((ev = (events & (POLLIN|POLLRDNORM))) != 0)
6394 revents |= ev;
6395 /*
6396 * POLLWRNORM (same as POLLOUT) really should not be
6397 * used to indicate that the process or lwp stopped.
6398 * However, USL chose to use POLLWRNORM rather than
6399 * POLLPRI to indicate this, so we just accept either
6400 * requested event to indicate stopped. (grr...)
6401 */
6402 if ((ev = (events & (POLLPRI|POLLOUT|POLLWRNORM))) != 0) {
6403 kthread_t *t;
6404
6405 if (pcp->prc_flags & PRC_LWP) {
6406 t = pcp->prc_thread;
6407 ASSERT(t != NULL);
6408 thread_lock(t);
6409 } else {
6410 t = prchoose(p); /* returns locked t */
6411 ASSERT(t != NULL);
6412 }
6413
6414 if (ISTOPPED(t) || VSTOPPED(t))
6415 revents |= ev;
6416 thread_unlock(t);
6417 }
6418 }
6419
6420 *reventsp = revents;
6421 if ((!anyyet && revents == 0) || (events & POLLET)) {
6422 /*
6423 * Arrange to wake up the polling lwp when
6424 * the target process/lwp stops or terminates
6425 * or when the file descriptor becomes invalid.
6426 */
6427 pcp->prc_flags |= PRC_POLL;
6428 *phpp = php;
6429 }
6430 mutex_exit(&p->p_lock);
6431 return (0);
6432 }
6433
6434 /* in prioctl.c */
6435 extern int prioctl(vnode_t *, int, intptr_t, int, cred_t *, int *,
6436 caller_context_t *);
6437
6438 /*
6439 * /proc vnode operations vector
6440 */
6441 const fs_operation_def_t pr_vnodeops_template[] = {
6442 VOPNAME_OPEN, { .vop_open = propen },
6443 VOPNAME_CLOSE, { .vop_close = prclose },
6444 VOPNAME_READ, { .vop_read = prread },
6445 VOPNAME_WRITE, { .vop_write = prwrite },
6446 VOPNAME_IOCTL, { .vop_ioctl = prioctl },
6447 VOPNAME_GETATTR, { .vop_getattr = prgetattr },
6448 VOPNAME_ACCESS, { .vop_access = praccess },
6449 VOPNAME_LOOKUP, { .vop_lookup = prlookup },
6450 VOPNAME_CREATE, { .vop_create = prcreate },
6451 VOPNAME_READDIR, { .vop_readdir = prreaddir },
6452 VOPNAME_READLINK, { .vop_readlink = prreadlink },
6453 VOPNAME_FSYNC, { .vop_fsync = prfsync },
6454 VOPNAME_INACTIVE, { .vop_inactive = prinactive },
6455 VOPNAME_SEEK, { .vop_seek = prseek },
6456 VOPNAME_CMP, { .vop_cmp = prcmp },
6457 VOPNAME_FRLOCK, { .error = fs_error },
6458 VOPNAME_REALVP, { .vop_realvp = prrealvp },
6459 VOPNAME_POLL, { .vop_poll = prpoll },
6460 VOPNAME_DISPOSE, { .error = fs_error },
6461 VOPNAME_SHRLOCK, { .error = fs_error },
6462 NULL, NULL
6463 };
6464