xref: /freebsd/sys/kern/kern_proc.c (revision 2cdbd5eec4e32beddb3adcca014dda56debc6f5b)
1 /*
2  * Copyright (c) 1982, 1986, 1989, 1991, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *	This product includes software developed by the University of
16  *	California, Berkeley and its contributors.
17  * 4. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  *	@(#)kern_proc.c	8.7 (Berkeley) 2/14/95
34  * $FreeBSD$
35  */
36 
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/kernel.h>
40 #include <sys/sysctl.h>
41 #include <sys/malloc.h>
42 #include <sys/proc.h>
43 #include <sys/filedesc.h>
44 #include <sys/tty.h>
45 #include <sys/signalvar.h>
46 #include <vm/vm.h>
47 #include <sys/lock.h>
48 #include <vm/pmap.h>
49 #include <vm/vm_map.h>
50 #include <sys/user.h>
51 #include <vm/vm_zone.h>
52 
53 static MALLOC_DEFINE(M_PGRP, "pgrp", "process group header");
54 MALLOC_DEFINE(M_SESSION, "session", "session header");
55 static MALLOC_DEFINE(M_PROC, "proc", "Proc structures");
56 MALLOC_DEFINE(M_SUBPROC, "subproc", "Proc sub-structures");
57 
58 static void pgdelete	__P((struct pgrp *));
59 
60 /*
61  * Structure associated with user cacheing.
62  */
63 struct uidinfo {
64 	LIST_ENTRY(uidinfo) ui_hash;
65 	uid_t	ui_uid;
66 	long	ui_proccnt;
67 	rlim_t	ui_sbsize;
68 };
69 #define	UIHASH(uid)	(&uihashtbl[(uid) & uihash])
70 static LIST_HEAD(uihashhead, uidinfo) *uihashtbl;
71 static u_long uihash;		/* size of hash table - 1 */
72 
73 static void	orphanpg __P((struct pgrp *pg));
74 
75 static struct uidinfo	*uifind(uid_t uid);
76 static struct uidinfo	*uicreate(uid_t uid);
77 static int 	uifree(struct uidinfo *uip);
78 
79 /*
80  * Other process lists
81  */
82 struct pidhashhead *pidhashtbl;
83 u_long pidhash;
84 struct pgrphashhead *pgrphashtbl;
85 u_long pgrphash;
86 struct proclist allproc;
87 struct proclist zombproc;
88 vm_zone_t proc_zone;
89 
90 /*
91  * Initialize global process hashing structures.
92  */
93 void
94 procinit()
95 {
96 
97 	LIST_INIT(&allproc);
98 	LIST_INIT(&zombproc);
99 	pidhashtbl = hashinit(maxproc / 4, M_PROC, &pidhash);
100 	pgrphashtbl = hashinit(maxproc / 4, M_PROC, &pgrphash);
101 	uihashtbl = hashinit(maxproc / 16, M_PROC, &uihash);
102 	proc_zone = zinit("PROC", sizeof (struct proc), 0, 0, 5);
103 }
104 
105 /*
106  * find/create a uidinfo struct for the uid passed in
107  */
108 static struct uidinfo *
109 uifind(uid)
110 	uid_t uid;
111 {
112 	struct uihashhead *uipp;
113 	struct uidinfo *uip;
114 
115 	uipp = UIHASH(uid);
116 	LIST_FOREACH(uip, uipp, ui_hash)
117 		if (uip->ui_uid == uid)
118 			break;
119 
120 	return (uip);
121 }
122 
123 static struct uidinfo *
124 uicreate(uid)
125 	uid_t uid;
126 {
127 	struct uidinfo *uip, *norace;
128 
129 	MALLOC(uip, struct uidinfo *, sizeof(*uip), M_PROC, M_NOWAIT);
130 	if (uip == NULL) {
131 		MALLOC(uip, struct uidinfo *, sizeof(*uip), M_PROC, M_WAITOK);
132 		/*
133 		 * if we M_WAITOK we must look afterwards or risk
134 		 * redundant entries
135 		 */
136 		norace = uifind(uid);
137 		if (norace != NULL) {
138 			FREE(uip, M_PROC);
139 			return (norace);
140 		}
141 	}
142 	LIST_INSERT_HEAD(UIHASH(uid), uip, ui_hash);
143 	uip->ui_uid = uid;
144 	uip->ui_proccnt = 0;
145 	uip->ui_sbsize = 0;
146 	return (uip);
147 }
148 
149 static int
150 uifree(uip)
151 	struct uidinfo *uip;
152 {
153 
154 	if (uip->ui_sbsize == 0 && uip->ui_proccnt == 0) {
155 		LIST_REMOVE(uip, ui_hash);
156 		FREE(uip, M_PROC);
157 		return (1);
158 	}
159 	return (0);
160 }
161 
162 /*
163  * Change the count associated with number of processes
164  * a given user is using.  When 'max' is 0, don't enforce a limit
165  */
166 int
167 chgproccnt(uid, diff, max)
168 	uid_t	uid;
169 	int	diff;
170 	int	max;
171 {
172 	struct uidinfo *uip;
173 
174 	uip = uifind(uid);
175 	if (diff < 0)
176 		KASSERT(uip != NULL, ("reducing proccnt: lost count, uid = %d", uid));
177 	if (uip == NULL)
178 		uip = uicreate(uid);
179 	/* don't allow them to exceed max, but allow subtraction */
180 	if (diff > 0 && uip->ui_proccnt + diff > max && max != 0) {
181 		(void)uifree(uip);
182 		return (0);
183 	}
184 	uip->ui_proccnt += diff;
185 	(void)uifree(uip);
186 	return (1);
187 }
188 
189 /*
190  * Change the total socket buffer size a user has used.
191  */
192 int
193 chgsbsize(uid, diff, max)
194 	uid_t	uid;
195 	rlim_t	diff;
196 	rlim_t	max;
197 {
198 	struct uidinfo *uip;
199 
200 	uip = uifind(uid);
201 	if (diff < 0)
202 		KASSERT(uip != NULL, ("reducing sbsize: lost count, uid = %d", uid));
203 	if (uip == NULL)
204 		uip = uicreate(uid);
205 	/* don't allow them to exceed max, but allow subtraction */
206 	if (diff > 0 && uip->ui_sbsize + diff > max) {
207 		(void)uifree(uip);
208 		return (0);
209 	}
210 	uip->ui_sbsize += diff;
211 	(void)uifree(uip);
212 	return (1);
213 }
214 
215 /*
216  * Is p an inferior of the current process?
217  */
218 int
219 inferior(p)
220 	register struct proc *p;
221 {
222 
223 	for (; p != curproc; p = p->p_pptr)
224 		if (p->p_pid == 0)
225 			return (0);
226 	return (1);
227 }
228 
229 /*
230  * Locate a process by number
231  */
232 struct proc *
233 pfind(pid)
234 	register pid_t pid;
235 {
236 	register struct proc *p;
237 
238 	LIST_FOREACH(p, PIDHASH(pid), p_hash)
239 		if (p->p_pid == pid)
240 			return (p);
241 	return (NULL);
242 }
243 
244 /*
245  * Locate a process group by number
246  */
247 struct pgrp *
248 pgfind(pgid)
249 	register pid_t pgid;
250 {
251 	register struct pgrp *pgrp;
252 
253 	LIST_FOREACH(pgrp, PGRPHASH(pgid), pg_hash)
254 		if (pgrp->pg_id == pgid)
255 			return (pgrp);
256 	return (NULL);
257 }
258 
259 /*
260  * Move p to a new or existing process group (and session)
261  */
262 int
263 enterpgrp(p, pgid, mksess)
264 	register struct proc *p;
265 	pid_t pgid;
266 	int mksess;
267 {
268 	register struct pgrp *pgrp = pgfind(pgid);
269 
270 	KASSERT(pgrp == NULL || !mksess,
271 	    ("enterpgrp: setsid into non-empty pgrp"));
272 	KASSERT(!SESS_LEADER(p),
273 	    ("enterpgrp: session leader attempted setpgrp"));
274 
275 	if (pgrp == NULL) {
276 		pid_t savepid = p->p_pid;
277 		struct proc *np;
278 		/*
279 		 * new process group
280 		 */
281 		KASSERT(p->p_pid == pgid,
282 		    ("enterpgrp: new pgrp and pid != pgid"));
283 		MALLOC(pgrp, struct pgrp *, sizeof(struct pgrp), M_PGRP,
284 		    M_WAITOK);
285 		if ((np = pfind(savepid)) == NULL || np != p)
286 			return (ESRCH);
287 		if (mksess) {
288 			register struct session *sess;
289 
290 			/*
291 			 * new session
292 			 */
293 			MALLOC(sess, struct session *, sizeof(struct session),
294 			    M_SESSION, M_WAITOK);
295 			sess->s_leader = p;
296 			sess->s_sid = p->p_pid;
297 			sess->s_count = 1;
298 			sess->s_ttyvp = NULL;
299 			sess->s_ttyp = NULL;
300 			bcopy(p->p_session->s_login, sess->s_login,
301 			    sizeof(sess->s_login));
302 			p->p_flag &= ~P_CONTROLT;
303 			pgrp->pg_session = sess;
304 			KASSERT(p == curproc,
305 			    ("enterpgrp: mksession and p != curproc"));
306 		} else {
307 			pgrp->pg_session = p->p_session;
308 			pgrp->pg_session->s_count++;
309 		}
310 		pgrp->pg_id = pgid;
311 		LIST_INIT(&pgrp->pg_members);
312 		LIST_INSERT_HEAD(PGRPHASH(pgid), pgrp, pg_hash);
313 		pgrp->pg_jobc = 0;
314 		SLIST_INIT(&pgrp->pg_sigiolst);
315 	} else if (pgrp == p->p_pgrp)
316 		return (0);
317 
318 	/*
319 	 * Adjust eligibility of affected pgrps to participate in job control.
320 	 * Increment eligibility counts before decrementing, otherwise we
321 	 * could reach 0 spuriously during the first call.
322 	 */
323 	fixjobc(p, pgrp, 1);
324 	fixjobc(p, p->p_pgrp, 0);
325 
326 	LIST_REMOVE(p, p_pglist);
327 	if (LIST_EMPTY(&p->p_pgrp->pg_members))
328 		pgdelete(p->p_pgrp);
329 	p->p_pgrp = pgrp;
330 	LIST_INSERT_HEAD(&pgrp->pg_members, p, p_pglist);
331 	return (0);
332 }
333 
334 /*
335  * remove process from process group
336  */
337 int
338 leavepgrp(p)
339 	register struct proc *p;
340 {
341 
342 	LIST_REMOVE(p, p_pglist);
343 	if (LIST_EMPTY(&p->p_pgrp->pg_members))
344 		pgdelete(p->p_pgrp);
345 	p->p_pgrp = 0;
346 	return (0);
347 }
348 
349 /*
350  * delete a process group
351  */
352 static void
353 pgdelete(pgrp)
354 	register struct pgrp *pgrp;
355 {
356 
357 	/*
358 	 * Reset any sigio structures pointing to us as a result of
359 	 * F_SETOWN with our pgid.
360 	 */
361 	funsetownlst(&pgrp->pg_sigiolst);
362 
363 	if (pgrp->pg_session->s_ttyp != NULL &&
364 	    pgrp->pg_session->s_ttyp->t_pgrp == pgrp)
365 		pgrp->pg_session->s_ttyp->t_pgrp = NULL;
366 	LIST_REMOVE(pgrp, pg_hash);
367 	if (--pgrp->pg_session->s_count == 0)
368 		FREE(pgrp->pg_session, M_SESSION);
369 	FREE(pgrp, M_PGRP);
370 }
371 
372 /*
373  * Adjust pgrp jobc counters when specified process changes process group.
374  * We count the number of processes in each process group that "qualify"
375  * the group for terminal job control (those with a parent in a different
376  * process group of the same session).  If that count reaches zero, the
377  * process group becomes orphaned.  Check both the specified process'
378  * process group and that of its children.
379  * entering == 0 => p is leaving specified group.
380  * entering == 1 => p is entering specified group.
381  */
382 void
383 fixjobc(p, pgrp, entering)
384 	register struct proc *p;
385 	register struct pgrp *pgrp;
386 	int entering;
387 {
388 	register struct pgrp *hispgrp;
389 	register struct session *mysession = pgrp->pg_session;
390 
391 	/*
392 	 * Check p's parent to see whether p qualifies its own process
393 	 * group; if so, adjust count for p's process group.
394 	 */
395 	if ((hispgrp = p->p_pptr->p_pgrp) != pgrp &&
396 	    hispgrp->pg_session == mysession) {
397 		if (entering)
398 			pgrp->pg_jobc++;
399 		else if (--pgrp->pg_jobc == 0)
400 			orphanpg(pgrp);
401 	}
402 
403 	/*
404 	 * Check this process' children to see whether they qualify
405 	 * their process groups; if so, adjust counts for children's
406 	 * process groups.
407 	 */
408 	LIST_FOREACH(p, &p->p_children, p_sibling)
409 		if ((hispgrp = p->p_pgrp) != pgrp &&
410 		    hispgrp->pg_session == mysession &&
411 		    p->p_stat != SZOMB) {
412 			if (entering)
413 				hispgrp->pg_jobc++;
414 			else if (--hispgrp->pg_jobc == 0)
415 				orphanpg(hispgrp);
416 		}
417 }
418 
419 /*
420  * A process group has become orphaned;
421  * if there are any stopped processes in the group,
422  * hang-up all process in that group.
423  */
424 static void
425 orphanpg(pg)
426 	struct pgrp *pg;
427 {
428 	register struct proc *p;
429 
430 	LIST_FOREACH(p, &pg->pg_members, p_pglist) {
431 		if (p->p_stat == SSTOP) {
432 			LIST_FOREACH(p, &pg->pg_members, p_pglist) {
433 				psignal(p, SIGHUP);
434 				psignal(p, SIGCONT);
435 			}
436 			return;
437 		}
438 	}
439 }
440 
441 #include "opt_ddb.h"
442 #ifdef DDB
443 #include <ddb/ddb.h>
444 
445 DB_SHOW_COMMAND(pgrpdump, pgrpdump)
446 {
447 	register struct pgrp *pgrp;
448 	register struct proc *p;
449 	register int i;
450 
451 	for (i = 0; i <= pgrphash; i++) {
452 		if (!LIST_EMPTY(&pgrphashtbl[i])) {
453 			printf("\tindx %d\n", i);
454 			LIST_FOREACH(pgrp, &pgrphashtbl[i], pg_hash) {
455 				printf(
456 			"\tpgrp %p, pgid %ld, sess %p, sesscnt %d, mem %p\n",
457 				    (void *)pgrp, (long)pgrp->pg_id,
458 				    (void *)pgrp->pg_session,
459 				    pgrp->pg_session->s_count,
460 				    (void *)LIST_FIRST(&pgrp->pg_members));
461 				LIST_FOREACH(p, &pgrp->pg_members, p_pglist) {
462 					printf("\t\tpid %ld addr %p pgrp %p\n",
463 					    (long)p->p_pid, (void *)p,
464 					    (void *)p->p_pgrp);
465 				}
466 			}
467 		}
468 	}
469 }
470 #endif /* DDB */
471 
472 /*
473  * Fill in an eproc structure for the specified process.
474  */
475 void
476 fill_eproc(p, ep)
477 	register struct proc *p;
478 	register struct eproc *ep;
479 {
480 	register struct tty *tp;
481 
482 	bzero(ep, sizeof(*ep));
483 
484 	ep->e_paddr = p;
485 	if (p->p_cred) {
486 		ep->e_pcred = *p->p_cred;
487 		if (p->p_ucred)
488 			ep->e_ucred = *p->p_ucred;
489 	}
490 	if (p->p_procsig) {
491 		ep->e_procsig = *p->p_procsig;
492 	}
493 	if (p->p_stat != SIDL && p->p_stat != SZOMB && p->p_vmspace != NULL) {
494 		register struct vmspace *vm = p->p_vmspace;
495 		ep->e_vm = *vm;
496 		ep->e_vm.vm_rssize = vmspace_resident_count(vm); /*XXX*/
497 	}
498 	if ((p->p_flag & P_INMEM) && p->p_stats)
499 		ep->e_stats = *p->p_stats;
500 	if (p->p_pptr)
501 		ep->e_ppid = p->p_pptr->p_pid;
502 	if (p->p_pgrp) {
503 		ep->e_pgid = p->p_pgrp->pg_id;
504 		ep->e_jobc = p->p_pgrp->pg_jobc;
505 		ep->e_sess = p->p_pgrp->pg_session;
506 
507 		if (ep->e_sess) {
508 			bcopy(ep->e_sess->s_login, ep->e_login, sizeof(ep->e_login));
509 			if (ep->e_sess->s_ttyvp)
510 				ep->e_flag = EPROC_CTTY;
511 			if (p->p_session && SESS_LEADER(p))
512 				ep->e_flag |= EPROC_SLEADER;
513 		}
514 	}
515 	if ((p->p_flag & P_CONTROLT) &&
516 	    (ep->e_sess != NULL) &&
517 	    ((tp = ep->e_sess->s_ttyp) != NULL)) {
518 		ep->e_tdev = dev2udev(tp->t_dev);
519 		ep->e_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
520 		ep->e_tsess = tp->t_session;
521 	} else
522 		ep->e_tdev = NOUDEV;
523 	if (p->p_wmesg) {
524 		strncpy(ep->e_wmesg, p->p_wmesg, WMESGLEN);
525 		ep->e_wmesg[WMESGLEN] = 0;
526 	}
527 }
528 
529 static struct proc *
530 zpfind(pid_t pid)
531 {
532 	struct proc *p;
533 
534 	LIST_FOREACH(p, &zombproc, p_list)
535 		if (p->p_pid == pid)
536 			return (p);
537 	return (NULL);
538 }
539 
540 
541 static int
542 sysctl_out_proc(struct proc *p, struct sysctl_req *req, int doingzomb)
543 {
544 	struct eproc eproc;
545 	int error;
546 	pid_t pid = p->p_pid;
547 
548 	fill_eproc(p, &eproc);
549 	error = SYSCTL_OUT(req,(caddr_t)p, sizeof(struct proc));
550 	if (error)
551 		return (error);
552 	error = SYSCTL_OUT(req,(caddr_t)&eproc, sizeof(eproc));
553 	if (error)
554 		return (error);
555 	if (!doingzomb && pid && (pfind(pid) != p))
556 		return EAGAIN;
557 	if (doingzomb && zpfind(pid) != p)
558 		return EAGAIN;
559 	return (0);
560 }
561 
562 static int
563 sysctl_kern_proc(SYSCTL_HANDLER_ARGS)
564 {
565 	int *name = (int*) arg1;
566 	u_int namelen = arg2;
567 	struct proc *p;
568 	int doingzomb;
569 	int error = 0;
570 
571 	if (oidp->oid_number == KERN_PROC_PID) {
572 		if (namelen != 1)
573 			return (EINVAL);
574 		p = pfind((pid_t)name[0]);
575 		if (!p)
576 			return (0);
577 		if (!PRISON_CHECK(curproc, p))
578 			return (0);
579 		error = sysctl_out_proc(p, req, 0);
580 		return (error);
581 	}
582 	if (oidp->oid_number == KERN_PROC_ALL && !namelen)
583 		;
584 	else if (oidp->oid_number != KERN_PROC_ALL && namelen == 1)
585 		;
586 	else
587 		return (EINVAL);
588 
589 	if (!req->oldptr) {
590 		/* overestimate by 5 procs */
591 		error = SYSCTL_OUT(req, 0, sizeof (struct kinfo_proc) * 5);
592 		if (error)
593 			return (error);
594 	}
595 	for (doingzomb=0 ; doingzomb < 2 ; doingzomb++) {
596 		if (!doingzomb)
597 			p = LIST_FIRST(&allproc);
598 		else
599 			p = LIST_FIRST(&zombproc);
600 		for (; p != 0; p = LIST_NEXT(p, p_list)) {
601 			/*
602 			 * Skip embryonic processes.
603 			 */
604 			if (p->p_stat == SIDL)
605 				continue;
606 			/*
607 			 * TODO - make more efficient (see notes below).
608 			 * do by session.
609 			 */
610 			switch (oidp->oid_number) {
611 
612 			case KERN_PROC_PGRP:
613 				/* could do this by traversing pgrp */
614 				if (p->p_pgrp == NULL ||
615 				    p->p_pgrp->pg_id != (pid_t)name[0])
616 					continue;
617 				break;
618 
619 			case KERN_PROC_TTY:
620 				if ((p->p_flag & P_CONTROLT) == 0 ||
621 				    p->p_session == NULL ||
622 				    p->p_session->s_ttyp == NULL ||
623 				    dev2udev(p->p_session->s_ttyp->t_dev) !=
624 					(udev_t)name[0])
625 					continue;
626 				break;
627 
628 			case KERN_PROC_UID:
629 				if (p->p_ucred == NULL ||
630 				    p->p_ucred->cr_uid != (uid_t)name[0])
631 					continue;
632 				break;
633 
634 			case KERN_PROC_RUID:
635 				if (p->p_ucred == NULL ||
636 				    p->p_cred->p_ruid != (uid_t)name[0])
637 					continue;
638 				break;
639 			}
640 
641 			if (!PRISON_CHECK(curproc, p))
642 				continue;
643 
644 			error = sysctl_out_proc(p, req, doingzomb);
645 			if (error)
646 				return (error);
647 		}
648 	}
649 	return (0);
650 }
651 
652 /*
653  * This sysctl allows a process to retrieve the argument list or process
654  * title for another process without groping around in the address space
655  * of the other process.  It also allow a process to set its own "process
656  * title to a string of its own choice.
657  */
658 static int
659 sysctl_kern_proc_args(SYSCTL_HANDLER_ARGS)
660 {
661 	int *name = (int*) arg1;
662 	u_int namelen = arg2;
663 	struct proc *p;
664 	struct pargs *pa;
665 	int error = 0;
666 
667 	if (namelen != 1)
668 		return (EINVAL);
669 
670 	p = pfind((pid_t)name[0]);
671 	if (!p)
672 		return (0);
673 
674 	if ((!ps_argsopen) && p_trespass(curproc, p))
675 		return (0);
676 
677 	if (req->newptr && curproc != p)
678 		return (EPERM);
679 
680 	if (req->oldptr && p->p_args != NULL)
681 		error = SYSCTL_OUT(req, p->p_args->ar_args, p->p_args->ar_length);
682 	if (req->newptr == NULL)
683 		return (error);
684 
685 	if (p->p_args && --p->p_args->ar_ref == 0)
686 		FREE(p->p_args, M_PARGS);
687 	p->p_args = NULL;
688 
689 	if (req->newlen + sizeof(struct pargs) > ps_arg_cache_limit)
690 		return (error);
691 
692 	MALLOC(pa, struct pargs *, sizeof(struct pargs) + req->newlen,
693 	    M_PARGS, M_WAITOK);
694 	pa->ar_ref = 1;
695 	pa->ar_length = req->newlen;
696 	error = SYSCTL_IN(req, pa->ar_args, req->newlen);
697 	if (!error)
698 		p->p_args = pa;
699 	else
700 		FREE(pa, M_PARGS);
701 	return (error);
702 }
703 
704 SYSCTL_NODE(_kern, KERN_PROC, proc, CTLFLAG_RD,  0, "Process table");
705 
706 SYSCTL_PROC(_kern_proc, KERN_PROC_ALL, all, CTLFLAG_RD|CTLTYPE_STRUCT,
707 	0, 0, sysctl_kern_proc, "S,proc", "Return entire process table");
708 
709 SYSCTL_NODE(_kern_proc, KERN_PROC_PGRP, pgrp, CTLFLAG_RD,
710 	sysctl_kern_proc, "Process table");
711 
712 SYSCTL_NODE(_kern_proc, KERN_PROC_TTY, tty, CTLFLAG_RD,
713 	sysctl_kern_proc, "Process table");
714 
715 SYSCTL_NODE(_kern_proc, KERN_PROC_UID, uid, CTLFLAG_RD,
716 	sysctl_kern_proc, "Process table");
717 
718 SYSCTL_NODE(_kern_proc, KERN_PROC_RUID, ruid, CTLFLAG_RD,
719 	sysctl_kern_proc, "Process table");
720 
721 SYSCTL_NODE(_kern_proc, KERN_PROC_PID, pid, CTLFLAG_RD,
722 	sysctl_kern_proc, "Process table");
723 
724 SYSCTL_NODE(_kern_proc, KERN_PROC_ARGS, args, CTLFLAG_RW | CTLFLAG_ANYBODY,
725 	sysctl_kern_proc_args, "Process argument list");
726