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