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