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