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