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