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