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/lock.h> 41 #include <sys/malloc.h> 42 #include <sys/mutex.h> 43 #include <sys/proc.h> 44 #include <sys/sysctl.h> 45 #include <sys/filedesc.h> 46 #include <sys/tty.h> 47 #include <sys/signalvar.h> 48 #include <sys/sx.h> 49 #include <sys/user.h> 50 #include <sys/jail.h> 51 52 #include <vm/vm.h> 53 #include <vm/pmap.h> 54 #include <vm/vm_map.h> 55 #include <vm/vm_zone.h> 56 57 static MALLOC_DEFINE(M_PGRP, "pgrp", "process group header"); 58 MALLOC_DEFINE(M_SESSION, "session", "session header"); 59 static MALLOC_DEFINE(M_PROC, "proc", "Proc structures"); 60 MALLOC_DEFINE(M_SUBPROC, "subproc", "Proc sub-structures"); 61 62 int ps_showallprocs = 1; 63 SYSCTL_INT(_kern, OID_AUTO, ps_showallprocs, CTLFLAG_RW, 64 &ps_showallprocs, 0, ""); 65 66 static void pgdelete __P((struct pgrp *)); 67 68 static void orphanpg __P((struct pgrp *pg)); 69 70 /* 71 * Other process lists 72 */ 73 struct pidhashhead *pidhashtbl; 74 u_long pidhash; 75 struct pgrphashhead *pgrphashtbl; 76 u_long pgrphash; 77 struct proclist allproc; 78 struct proclist zombproc; 79 struct sx allproc_lock; 80 struct sx proctree_lock; 81 vm_zone_t proc_zone; 82 vm_zone_t ithread_zone; 83 84 /* 85 * Initialize global process hashing structures. 86 */ 87 void 88 procinit() 89 { 90 int i, j; 91 92 sx_init(&allproc_lock, "allproc"); 93 sx_init(&proctree_lock, "proctree"); 94 LIST_INIT(&allproc); 95 LIST_INIT(&zombproc); 96 pidhashtbl = hashinit(maxproc / 4, M_PROC, &pidhash); 97 pgrphashtbl = hashinit(maxproc / 4, M_PROC, &pgrphash); 98 proc_zone = zinit("PROC", sizeof (struct proc), 0, 0, 5); 99 uihashinit(); 100 /* 101 * This should really be a compile time warning, but I do 102 * not know of any way to do that... 103 */ 104 if (sizeof(struct kinfo_proc) != KINFO_PROC_SIZE) { 105 printf("This message will repeat for the next 20 seconds\n"); 106 for (i = 0; i < 20; i++) { 107 printf("WARNING: size of kinfo_proc (%ld) should be %d!!!\n", 108 (long)sizeof(struct kinfo_proc), KINFO_PROC_SIZE); 109 printf("The kinfo_proc structure was changed "); 110 printf("incorrectly in <sys/user.h>\n"); 111 for (j = 0; j < 0x7ffffff; j++); 112 } 113 114 } 115 } 116 117 /* 118 * link up a process structure and it's inbuilt threads etc. 119 */ 120 void 121 proc_linkup(struct proc *p) 122 { 123 struct thread *td; 124 125 td = &p->p_thread; 126 127 /**** lists headed in the proc structure ****/ 128 /* ALL KSEGRPs in this process */ 129 TAILQ_INIT( &p->p_ksegrps); /* all ksegrps in proc */ 130 TAILQ_INSERT_HEAD(&p->p_ksegrps, &p->p_ksegrp, kg_ksegrp); 131 132 /* All threads in this process (an optimisation) */ 133 TAILQ_INIT( &p->p_threads); /* all threads in proc */ 134 TAILQ_INSERT_HEAD(&p->p_threads, &p->p_thread, td_plist); 135 136 /**** Lists headed in the KSEGROUP structure ****/ 137 /* all thread in this ksegroup */ 138 TAILQ_INIT( &p->p_ksegrp.kg_threads); 139 TAILQ_INSERT_HEAD(&p->p_ksegrp.kg_threads, &p->p_thread, td_kglist); 140 141 /* All runnable threads not assigned to a particular KSE */ 142 /* XXXKSE THIS MAY GO AWAY.. KSEs are never unassigned */ 143 TAILQ_INIT( &p->p_ksegrp.kg_runq); /* links with td_runq */ 144 145 /* All threads presently not runnable (Thread starts this way) */ 146 TAILQ_INIT( &p->p_ksegrp.kg_slpq); /* links with td_runq */ 147 TAILQ_INSERT_HEAD(&p->p_ksegrp.kg_slpq, &p->p_thread, td_runq); 148 /*p->p_thread.td_flags &= ~TDF_ONRUNQ;*/ 149 150 /* all KSEs in this ksegroup */ 151 TAILQ_INIT( &p->p_ksegrp.kg_kseq); /* all kses in ksegrp */ 152 TAILQ_INSERT_HEAD(&p->p_ksegrp.kg_kseq, &p->p_kse, ke_kglist); 153 154 /* KSE starts out idle *//* XXXKSE */ 155 TAILQ_INIT( &p->p_ksegrp.kg_rq); /* all kses in ksegrp */ 156 TAILQ_INIT( &p->p_ksegrp.kg_iq); /* all kses in ksegrp */ 157 #if 0 158 TAILQ_INSERT_HEAD(&p->p_ksegrp.kg_iq, &p->p_kse, ke_kgrlist); 159 #endif /* is running, not idle */ 160 /*p->p_kse.ke_flags &= &KEF_ONRUNQ;*/ 161 162 /**** Lists headed in the KSE structure ****/ 163 /* runnable threads assigned to this kse */ 164 TAILQ_INIT( &p->p_kse.ke_runq); /* links with td_runq */ 165 166 p->p_thread.td_proc = p; 167 p->p_kse.ke_proc = p; 168 p->p_ksegrp.kg_proc = p; 169 170 p->p_thread.td_ksegrp = &p->p_ksegrp; 171 p->p_kse.ke_ksegrp = &p->p_ksegrp; 172 173 p->p_thread.td_last_kse = &p->p_kse; 174 p->p_thread.td_kse = &p->p_kse; 175 176 p->p_kse.ke_thread = &p->p_thread; 177 178 p->p_ksegrp.kg_runnable = 1; 179 p->p_ksegrp.kg_kses = 1; 180 p->p_ksegrp.kg_runq_kses = 1; /* XXXKSE change name */ 181 } 182 183 /* 184 * Is p an inferior of the current process? 185 */ 186 int 187 inferior(p) 188 register struct proc *p; 189 { 190 int rval; 191 192 PROC_LOCK_ASSERT(p, MA_OWNED); 193 if (p == curproc) 194 return (1); 195 if (p->p_pid == 0) 196 return (0); 197 PROC_LOCK(p->p_pptr); 198 rval = inferior(p->p_pptr); 199 PROC_UNLOCK(p->p_pptr); 200 return (rval); 201 } 202 203 /* 204 * Locate a process by number 205 */ 206 struct proc * 207 pfind(pid) 208 register pid_t pid; 209 { 210 register struct proc *p; 211 212 sx_slock(&allproc_lock); 213 LIST_FOREACH(p, PIDHASH(pid), p_hash) 214 if (p->p_pid == pid) { 215 PROC_LOCK(p); 216 break; 217 } 218 sx_sunlock(&allproc_lock); 219 return (p); 220 } 221 222 /* 223 * Locate a process group by number 224 */ 225 struct pgrp * 226 pgfind(pgid) 227 register pid_t pgid; 228 { 229 register struct pgrp *pgrp; 230 231 LIST_FOREACH(pgrp, PGRPHASH(pgid), pg_hash) 232 if (pgrp->pg_id == pgid) 233 return (pgrp); 234 return (NULL); 235 } 236 237 /* 238 * Move p to a new or existing process group (and session) 239 */ 240 int 241 enterpgrp(p, pgid, mksess) 242 register struct proc *p; 243 pid_t pgid; 244 int mksess; 245 { 246 register struct pgrp *pgrp = pgfind(pgid); 247 struct pgrp *savegrp; 248 249 KASSERT(pgrp == NULL || !mksess, 250 ("enterpgrp: setsid into non-empty pgrp")); 251 KASSERT(!SESS_LEADER(p), 252 ("enterpgrp: session leader attempted setpgrp")); 253 254 if (pgrp == NULL) { 255 pid_t savepid = p->p_pid; 256 struct proc *np; 257 /* 258 * new process group 259 */ 260 KASSERT(p->p_pid == pgid, 261 ("enterpgrp: new pgrp and pid != pgid")); 262 if ((np = pfind(savepid)) == NULL || np != p) { 263 if (np != NULL) 264 PROC_UNLOCK(np); 265 return (ESRCH); 266 } 267 PROC_UNLOCK(np); 268 MALLOC(pgrp, struct pgrp *, sizeof(struct pgrp), M_PGRP, 269 M_WAITOK); 270 if (mksess) { 271 register struct session *sess; 272 273 /* 274 * new session 275 */ 276 MALLOC(sess, struct session *, sizeof(struct session), 277 M_SESSION, M_WAITOK); 278 sess->s_leader = p; 279 sess->s_sid = p->p_pid; 280 sess->s_count = 1; 281 sess->s_ttyvp = NULL; 282 sess->s_ttyp = NULL; 283 bcopy(p->p_session->s_login, sess->s_login, 284 sizeof(sess->s_login)); 285 PROC_LOCK(p); 286 p->p_flag &= ~P_CONTROLT; 287 PROC_UNLOCK(p); 288 pgrp->pg_session = sess; 289 KASSERT(p == curproc, 290 ("enterpgrp: mksession and p != curproc")); 291 } else { 292 pgrp->pg_session = p->p_session; 293 pgrp->pg_session->s_count++; 294 } 295 pgrp->pg_id = pgid; 296 LIST_INIT(&pgrp->pg_members); 297 LIST_INSERT_HEAD(PGRPHASH(pgid), pgrp, pg_hash); 298 pgrp->pg_jobc = 0; 299 SLIST_INIT(&pgrp->pg_sigiolst); 300 } else if (pgrp == p->p_pgrp) 301 return (0); 302 303 /* 304 * Adjust eligibility of affected pgrps to participate in job control. 305 * Increment eligibility counts before decrementing, otherwise we 306 * could reach 0 spuriously during the first call. 307 */ 308 fixjobc(p, pgrp, 1); 309 fixjobc(p, p->p_pgrp, 0); 310 311 PROC_LOCK(p); 312 LIST_REMOVE(p, p_pglist); 313 savegrp = p->p_pgrp; 314 p->p_pgrp = pgrp; 315 LIST_INSERT_HEAD(&pgrp->pg_members, p, p_pglist); 316 PROC_UNLOCK(p); 317 if (LIST_EMPTY(&savegrp->pg_members)) 318 pgdelete(savegrp); 319 return (0); 320 } 321 322 /* 323 * remove process from process group 324 */ 325 int 326 leavepgrp(p) 327 register struct proc *p; 328 { 329 struct pgrp *savegrp; 330 331 PROC_LOCK(p); 332 LIST_REMOVE(p, p_pglist); 333 savegrp = p->p_pgrp; 334 p->p_pgrp = NULL; 335 PROC_UNLOCK(p); 336 if (LIST_EMPTY(&savegrp->pg_members)) 337 pgdelete(savegrp); 338 return (0); 339 } 340 341 /* 342 * delete a process group 343 */ 344 static void 345 pgdelete(pgrp) 346 register struct pgrp *pgrp; 347 { 348 349 /* 350 * Reset any sigio structures pointing to us as a result of 351 * F_SETOWN with our pgid. 352 */ 353 funsetownlst(&pgrp->pg_sigiolst); 354 355 if (pgrp->pg_session->s_ttyp != NULL && 356 pgrp->pg_session->s_ttyp->t_pgrp == pgrp) 357 pgrp->pg_session->s_ttyp->t_pgrp = NULL; 358 LIST_REMOVE(pgrp, pg_hash); 359 if (--pgrp->pg_session->s_count == 0) 360 FREE(pgrp->pg_session, M_SESSION); 361 FREE(pgrp, M_PGRP); 362 } 363 364 /* 365 * Adjust pgrp jobc counters when specified process changes process group. 366 * We count the number of processes in each process group that "qualify" 367 * the group for terminal job control (those with a parent in a different 368 * process group of the same session). If that count reaches zero, the 369 * process group becomes orphaned. Check both the specified process' 370 * process group and that of its children. 371 * entering == 0 => p is leaving specified group. 372 * entering == 1 => p is entering specified group. 373 */ 374 void 375 fixjobc(p, pgrp, entering) 376 register struct proc *p; 377 register struct pgrp *pgrp; 378 int entering; 379 { 380 register struct pgrp *hispgrp; 381 register struct session *mysession = pgrp->pg_session; 382 383 /* 384 * Check p's parent to see whether p qualifies its own process 385 * group; if so, adjust count for p's process group. 386 */ 387 sx_slock(&proctree_lock); 388 if ((hispgrp = p->p_pptr->p_pgrp) != pgrp && 389 hispgrp->pg_session == mysession) { 390 if (entering) 391 pgrp->pg_jobc++; 392 else if (--pgrp->pg_jobc == 0) 393 orphanpg(pgrp); 394 } 395 396 /* 397 * Check this process' children to see whether they qualify 398 * their process groups; if so, adjust counts for children's 399 * process groups. 400 */ 401 LIST_FOREACH(p, &p->p_children, p_sibling) 402 if ((hispgrp = p->p_pgrp) != pgrp && 403 hispgrp->pg_session == mysession && 404 p->p_stat != SZOMB) { 405 if (entering) 406 hispgrp->pg_jobc++; 407 else if (--hispgrp->pg_jobc == 0) 408 orphanpg(hispgrp); 409 } 410 sx_sunlock(&proctree_lock); 411 } 412 413 /* 414 * A process group has become orphaned; 415 * if there are any stopped processes in the group, 416 * hang-up all process in that group. 417 */ 418 static void 419 orphanpg(pg) 420 struct pgrp *pg; 421 { 422 register struct proc *p; 423 424 mtx_lock_spin(&sched_lock); 425 LIST_FOREACH(p, &pg->pg_members, p_pglist) { 426 if (p->p_stat == SSTOP) { 427 mtx_unlock_spin(&sched_lock); 428 LIST_FOREACH(p, &pg->pg_members, p_pglist) { 429 PROC_LOCK(p); 430 psignal(p, SIGHUP); 431 psignal(p, SIGCONT); 432 PROC_UNLOCK(p); 433 } 434 return; 435 } 436 } 437 mtx_unlock_spin(&sched_lock); 438 } 439 440 #include "opt_ddb.h" 441 #ifdef DDB 442 #include <ddb/ddb.h> 443 444 DB_SHOW_COMMAND(pgrpdump, pgrpdump) 445 { 446 register struct pgrp *pgrp; 447 register struct proc *p; 448 register int i; 449 450 for (i = 0; i <= pgrphash; i++) { 451 if (!LIST_EMPTY(&pgrphashtbl[i])) { 452 printf("\tindx %d\n", i); 453 LIST_FOREACH(pgrp, &pgrphashtbl[i], pg_hash) { 454 printf( 455 "\tpgrp %p, pgid %ld, sess %p, sesscnt %d, mem %p\n", 456 (void *)pgrp, (long)pgrp->pg_id, 457 (void *)pgrp->pg_session, 458 pgrp->pg_session->s_count, 459 (void *)LIST_FIRST(&pgrp->pg_members)); 460 LIST_FOREACH(p, &pgrp->pg_members, p_pglist) { 461 printf("\t\tpid %ld addr %p pgrp %p\n", 462 (long)p->p_pid, (void *)p, 463 (void *)p->p_pgrp); 464 } 465 } 466 } 467 } 468 } 469 #endif /* DDB */ 470 471 /* 472 * Fill in an kinfo_proc structure for the specified process. 473 */ 474 void 475 fill_kinfo_proc(p, kp) 476 struct proc *p; 477 struct kinfo_proc *kp; 478 { 479 struct thread *td; 480 struct tty *tp; 481 struct session *sp; 482 483 bzero(kp, sizeof(*kp)); 484 485 kp->ki_structsize = sizeof(*kp); 486 kp->ki_paddr = p; 487 PROC_LOCK(p); 488 kp->ki_addr =/* p->p_addr; */0; /* XXXKSE */ 489 kp->ki_args = p->p_args; 490 kp->ki_tracep = p->p_tracep; 491 kp->ki_textvp = p->p_textvp; 492 kp->ki_fd = p->p_fd; 493 kp->ki_vmspace = p->p_vmspace; 494 if (p->p_ucred) { 495 kp->ki_uid = p->p_ucred->cr_uid; 496 kp->ki_ruid = p->p_ucred->cr_ruid; 497 kp->ki_svuid = p->p_ucred->cr_svuid; 498 /* XXX bde doesn't like KI_NGROUPS */ 499 kp->ki_ngroups = min(p->p_ucred->cr_ngroups, KI_NGROUPS); 500 bcopy(p->p_ucred->cr_groups, kp->ki_groups, 501 kp->ki_ngroups * sizeof(gid_t)); 502 kp->ki_rgid = p->p_ucred->cr_rgid; 503 kp->ki_svgid = p->p_ucred->cr_svgid; 504 } 505 if (p->p_procsig) { 506 kp->ki_sigignore = p->p_procsig->ps_sigignore; 507 kp->ki_sigcatch = p->p_procsig->ps_sigcatch; 508 } 509 mtx_lock_spin(&sched_lock); 510 if (p->p_stat != SIDL && p->p_stat != SZOMB && p->p_vmspace != NULL) { 511 struct vmspace *vm = p->p_vmspace; 512 513 kp->ki_size = vm->vm_map.size; 514 kp->ki_rssize = vmspace_resident_count(vm); /*XXX*/ 515 if (p->p_sflag & PS_INMEM) 516 kp->ki_rssize += UAREA_PAGES; 517 FOREACH_THREAD_IN_PROC(p, td) /* XXXKSE: thread swapout check */ 518 kp->ki_rssize += KSTACK_PAGES; 519 kp->ki_swrss = vm->vm_swrss; 520 kp->ki_tsize = vm->vm_tsize; 521 kp->ki_dsize = vm->vm_dsize; 522 kp->ki_ssize = vm->vm_ssize; 523 } 524 if ((p->p_sflag & PS_INMEM) && p->p_stats) { 525 kp->ki_start = p->p_stats->p_start; 526 kp->ki_rusage = p->p_stats->p_ru; 527 kp->ki_childtime.tv_sec = p->p_stats->p_cru.ru_utime.tv_sec + 528 p->p_stats->p_cru.ru_stime.tv_sec; 529 kp->ki_childtime.tv_usec = p->p_stats->p_cru.ru_utime.tv_usec + 530 p->p_stats->p_cru.ru_stime.tv_usec; 531 } 532 if (p->p_thread.td_wmesg != NULL) 533 strncpy(kp->ki_wmesg, p->p_thread.td_wmesg, sizeof(kp->ki_wmesg) - 1); 534 if (p->p_stat == SMTX) { 535 kp->ki_kiflag |= KI_MTXBLOCK; 536 strncpy(kp->ki_mtxname, p->p_thread.td_mtxname, 537 sizeof(kp->ki_mtxname) - 1); 538 } 539 kp->ki_stat = p->p_stat; 540 kp->ki_sflag = p->p_sflag; 541 kp->ki_swtime = p->p_swtime; 542 kp->ki_traceflag = p->p_traceflag; 543 kp->ki_pid = p->p_pid; 544 /* vvv XXXKSE */ 545 kp->ki_runtime = p->p_runtime; 546 kp->ki_pctcpu = p->p_kse.ke_pctcpu; 547 kp->ki_estcpu = p->p_ksegrp.kg_estcpu; 548 kp->ki_slptime = p->p_ksegrp.kg_slptime; 549 kp->ki_wchan = p->p_thread.td_wchan; 550 kp->ki_pri = p->p_ksegrp.kg_pri; 551 kp->ki_nice = p->p_ksegrp.kg_nice; 552 kp->ki_rqindex = p->p_kse.ke_rqindex; 553 kp->ki_oncpu = p->p_kse.ke_oncpu; 554 kp->ki_lastcpu = p->p_thread.td_lastcpu; 555 kp->ki_tdflags = p->p_thread.td_flags; 556 kp->ki_pcb = p->p_thread.td_pcb; 557 kp->ki_kstack = (void *)p->p_thread.td_kstack; 558 /* ^^^ XXXKSE */ 559 mtx_unlock_spin(&sched_lock); 560 sp = NULL; 561 if (p->p_pgrp) { 562 kp->ki_pgid = p->p_pgrp->pg_id; 563 kp->ki_jobc = p->p_pgrp->pg_jobc; 564 sp = p->p_pgrp->pg_session; 565 566 if (sp != NULL) { 567 kp->ki_sid = sp->s_sid; 568 strncpy(kp->ki_login, sp->s_login, 569 sizeof(kp->ki_login) - 1); 570 if (sp->s_ttyvp) 571 kp->ki_kiflag = KI_CTTY; 572 if (SESS_LEADER(p)) 573 kp->ki_kiflag |= KI_SLEADER; 574 } 575 } 576 if ((p->p_flag & P_CONTROLT) && sp && ((tp = sp->s_ttyp) != NULL)) { 577 kp->ki_tdev = dev2udev(tp->t_dev); 578 kp->ki_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID; 579 if (tp->t_session) 580 kp->ki_tsid = tp->t_session->s_sid; 581 } else 582 kp->ki_tdev = NOUDEV; 583 if (p->p_comm[0] != '\0') { 584 strncpy(kp->ki_comm, p->p_comm, sizeof(kp->ki_comm) - 1); 585 strncpy(kp->ki_ocomm, p->p_comm, sizeof(kp->ki_ocomm) - 1); 586 } 587 kp->ki_siglist = p->p_siglist; 588 kp->ki_sigmask = p->p_sigmask; 589 kp->ki_xstat = p->p_xstat; 590 kp->ki_acflag = p->p_acflag; 591 kp->ki_flag = p->p_flag; 592 /* If jailed(p->p_ucred), emulate the old P_JAILED flag. */ 593 if (jailed(p->p_ucred)) 594 kp->ki_flag |= P_JAILED; 595 kp->ki_lock = p->p_lock; 596 if (p->p_pptr) 597 kp->ki_ppid = p->p_pptr->p_pid; 598 PROC_UNLOCK(p); 599 } 600 601 /* 602 * Locate a zombie process by number 603 */ 604 struct proc * 605 zpfind(pid_t pid) 606 { 607 struct proc *p; 608 609 sx_slock(&allproc_lock); 610 LIST_FOREACH(p, &zombproc, p_list) 611 if (p->p_pid == pid) { 612 PROC_LOCK(p); 613 break; 614 } 615 sx_sunlock(&allproc_lock); 616 return (p); 617 } 618 619 620 static int 621 sysctl_out_proc(struct proc *p, struct sysctl_req *req, int doingzomb) 622 { 623 struct kinfo_proc kinfo_proc; 624 int error; 625 struct proc *np; 626 pid_t pid = p->p_pid; 627 628 fill_kinfo_proc(p, &kinfo_proc); 629 error = SYSCTL_OUT(req, (caddr_t)&kinfo_proc, sizeof(kinfo_proc)); 630 if (error) 631 return (error); 632 if (doingzomb) 633 np = zpfind(pid); 634 else { 635 if (pid == 0) 636 return (0); 637 np = pfind(pid); 638 } 639 if (np == NULL) 640 return EAGAIN; 641 if (np != p) { 642 PROC_UNLOCK(np); 643 return EAGAIN; 644 } 645 PROC_UNLOCK(np); 646 return (0); 647 } 648 649 static int 650 sysctl_kern_proc(SYSCTL_HANDLER_ARGS) 651 { 652 int *name = (int*) arg1; 653 u_int namelen = arg2; 654 struct proc *p; 655 int doingzomb; 656 int error = 0; 657 658 if (oidp->oid_number == KERN_PROC_PID) { 659 if (namelen != 1) 660 return (EINVAL); 661 p = pfind((pid_t)name[0]); 662 if (!p) 663 return (0); 664 if (p_cansee(curproc, p)) { 665 PROC_UNLOCK(p); 666 return (0); 667 } 668 PROC_UNLOCK(p); 669 error = sysctl_out_proc(p, req, 0); 670 return (error); 671 } 672 if (oidp->oid_number == KERN_PROC_ALL && !namelen) 673 ; 674 else if (oidp->oid_number != KERN_PROC_ALL && namelen == 1) 675 ; 676 else 677 return (EINVAL); 678 679 if (!req->oldptr) { 680 /* overestimate by 5 procs */ 681 error = SYSCTL_OUT(req, 0, sizeof (struct kinfo_proc) * 5); 682 if (error) 683 return (error); 684 } 685 sx_slock(&allproc_lock); 686 for (doingzomb=0 ; doingzomb < 2 ; doingzomb++) { 687 if (!doingzomb) 688 p = LIST_FIRST(&allproc); 689 else 690 p = LIST_FIRST(&zombproc); 691 for (; p != 0; p = LIST_NEXT(p, p_list)) { 692 /* 693 * Show a user only appropriate processes. 694 */ 695 if (p_cansee(curproc, p)) 696 continue; 697 /* 698 * Skip embryonic processes. 699 */ 700 if (p->p_stat == SIDL) 701 continue; 702 /* 703 * TODO - make more efficient (see notes below). 704 * do by session. 705 */ 706 switch (oidp->oid_number) { 707 708 case KERN_PROC_PGRP: 709 /* could do this by traversing pgrp */ 710 if (p->p_pgrp == NULL || 711 p->p_pgrp->pg_id != (pid_t)name[0]) 712 continue; 713 break; 714 715 case KERN_PROC_TTY: 716 if ((p->p_flag & P_CONTROLT) == 0 || 717 p->p_session == NULL || 718 p->p_session->s_ttyp == NULL || 719 dev2udev(p->p_session->s_ttyp->t_dev) != 720 (udev_t)name[0]) 721 continue; 722 break; 723 724 case KERN_PROC_UID: 725 if (p->p_ucred == NULL || 726 p->p_ucred->cr_uid != (uid_t)name[0]) 727 continue; 728 break; 729 730 case KERN_PROC_RUID: 731 if (p->p_ucred == NULL || 732 p->p_ucred->cr_ruid != (uid_t)name[0]) 733 continue; 734 break; 735 } 736 737 if (p_cansee(curproc, p)) 738 continue; 739 740 error = sysctl_out_proc(p, req, doingzomb); 741 if (error) { 742 sx_sunlock(&allproc_lock); 743 return (error); 744 } 745 } 746 } 747 sx_sunlock(&allproc_lock); 748 return (0); 749 } 750 751 /* 752 * This sysctl allows a process to retrieve the argument list or process 753 * title for another process without groping around in the address space 754 * of the other process. It also allow a process to set its own "process 755 * title to a string of its own choice. 756 */ 757 static int 758 sysctl_kern_proc_args(SYSCTL_HANDLER_ARGS) 759 { 760 int *name = (int*) arg1; 761 u_int namelen = arg2; 762 struct proc *p; 763 struct pargs *pa; 764 int error = 0; 765 766 if (namelen != 1) 767 return (EINVAL); 768 769 p = pfind((pid_t)name[0]); 770 if (!p) 771 return (0); 772 773 if ((!ps_argsopen) && p_cansee(curproc, p)) { 774 PROC_UNLOCK(p); 775 return (0); 776 } 777 PROC_UNLOCK(p); 778 779 if (req->newptr && curproc != p) 780 return (EPERM); 781 782 if (req->oldptr && p->p_args != NULL) 783 error = SYSCTL_OUT(req, p->p_args->ar_args, p->p_args->ar_length); 784 if (req->newptr == NULL) 785 return (error); 786 787 PROC_LOCK(p); 788 pa = p->p_args; 789 p->p_args = NULL; 790 PROC_UNLOCK(p); 791 if (pa != NULL && --pa->ar_ref == 0) 792 FREE(pa, M_PARGS); 793 794 if (req->newlen + sizeof(struct pargs) > ps_arg_cache_limit) 795 return (error); 796 797 MALLOC(pa, struct pargs *, sizeof(struct pargs) + req->newlen, 798 M_PARGS, M_WAITOK); 799 pa->ar_ref = 1; 800 pa->ar_length = req->newlen; 801 error = SYSCTL_IN(req, pa->ar_args, req->newlen); 802 if (!error) { 803 PROC_LOCK(p); 804 p->p_args = pa; 805 PROC_UNLOCK(p); 806 } else 807 FREE(pa, M_PARGS); 808 return (error); 809 } 810 811 SYSCTL_NODE(_kern, KERN_PROC, proc, CTLFLAG_RD, 0, "Process table"); 812 813 SYSCTL_PROC(_kern_proc, KERN_PROC_ALL, all, CTLFLAG_RD|CTLTYPE_STRUCT, 814 0, 0, sysctl_kern_proc, "S,proc", "Return entire process table"); 815 816 SYSCTL_NODE(_kern_proc, KERN_PROC_PGRP, pgrp, CTLFLAG_RD, 817 sysctl_kern_proc, "Process table"); 818 819 SYSCTL_NODE(_kern_proc, KERN_PROC_TTY, tty, CTLFLAG_RD, 820 sysctl_kern_proc, "Process table"); 821 822 SYSCTL_NODE(_kern_proc, KERN_PROC_UID, uid, CTLFLAG_RD, 823 sysctl_kern_proc, "Process table"); 824 825 SYSCTL_NODE(_kern_proc, KERN_PROC_RUID, ruid, CTLFLAG_RD, 826 sysctl_kern_proc, "Process table"); 827 828 SYSCTL_NODE(_kern_proc, KERN_PROC_PID, pid, CTLFLAG_RD, 829 sysctl_kern_proc, "Process table"); 830 831 SYSCTL_NODE(_kern_proc, KERN_PROC_ARGS, args, CTLFLAG_RW | CTLFLAG_ANYBODY, 832 sysctl_kern_proc_args, "Process argument list"); 833