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