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