1 /*- 2 * Copyright (c) 2014 John Baldwin 3 * Copyright (c) 2014, 2016 The FreeBSD Foundation 4 * 5 * Portions of this software were developed by Konstantin Belousov 6 * under sponsorship from the FreeBSD Foundation. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 #include "opt_ktrace.h" 31 32 #include <sys/param.h> 33 #include <sys/_unrhdr.h> 34 #include <sys/systm.h> 35 #include <sys/capsicum.h> 36 #include <sys/lock.h> 37 #include <sys/malloc.h> 38 #include <sys/mman.h> 39 #include <sys/mutex.h> 40 #include <sys/priv.h> 41 #include <sys/proc.h> 42 #include <sys/procctl.h> 43 #include <sys/ptrace.h> 44 #include <sys/sx.h> 45 #include <sys/syscallsubr.h> 46 #include <sys/sysproto.h> 47 #include <sys/wait.h> 48 49 #include <vm/vm.h> 50 #include <vm/pmap.h> 51 #include <vm/vm_map.h> 52 #include <vm/vm_extern.h> 53 #include <vm/uma.h> 54 55 static int 56 protect_setchild(struct thread *td, struct proc *p, int flags) 57 { 58 59 PROC_LOCK_ASSERT(p, MA_OWNED); 60 if (p->p_flag & P_SYSTEM || p_cansched(td, p) != 0) 61 return (0); 62 if (flags & PPROT_SET) { 63 p->p_flag |= P_PROTECTED; 64 if (flags & PPROT_INHERIT) 65 p->p_flag2 |= P2_INHERIT_PROTECTED; 66 } else { 67 p->p_flag &= ~P_PROTECTED; 68 p->p_flag2 &= ~P2_INHERIT_PROTECTED; 69 } 70 return (1); 71 } 72 73 static int 74 protect_setchildren(struct thread *td, struct proc *top, int flags) 75 { 76 struct proc *p; 77 int ret; 78 79 p = top; 80 ret = 0; 81 sx_assert(&proctree_lock, SX_LOCKED); 82 for (;;) { 83 ret |= protect_setchild(td, p, flags); 84 PROC_UNLOCK(p); 85 /* 86 * If this process has children, descend to them next, 87 * otherwise do any siblings, and if done with this level, 88 * follow back up the tree (but not past top). 89 */ 90 if (!LIST_EMPTY(&p->p_children)) 91 p = LIST_FIRST(&p->p_children); 92 else for (;;) { 93 if (p == top) { 94 PROC_LOCK(p); 95 return (ret); 96 } 97 if (LIST_NEXT(p, p_sibling)) { 98 p = LIST_NEXT(p, p_sibling); 99 break; 100 } 101 p = p->p_pptr; 102 } 103 PROC_LOCK(p); 104 } 105 } 106 107 static int 108 protect_set(struct thread *td, struct proc *p, void *data) 109 { 110 int error, flags, ret; 111 112 flags = *(int *)data; 113 switch (PPROT_OP(flags)) { 114 case PPROT_SET: 115 case PPROT_CLEAR: 116 break; 117 default: 118 return (EINVAL); 119 } 120 121 if ((PPROT_FLAGS(flags) & ~(PPROT_DESCEND | PPROT_INHERIT)) != 0) 122 return (EINVAL); 123 124 error = priv_check(td, PRIV_VM_MADV_PROTECT); 125 if (error) 126 return (error); 127 128 if (flags & PPROT_DESCEND) 129 ret = protect_setchildren(td, p, flags); 130 else 131 ret = protect_setchild(td, p, flags); 132 if (ret == 0) 133 return (EPERM); 134 return (0); 135 } 136 137 static struct proc * 138 get_reaper_or_p(struct proc *p) 139 { 140 sx_assert(&proctree_lock, SX_LOCKED); 141 return ((p->p_treeflag & P_TREE_REAPER) == 0 ? p->p_reaper : p); 142 } 143 144 static int 145 reap_acquire(struct thread *td, struct proc *p, void *data __unused) 146 { 147 148 sx_assert(&proctree_lock, SX_XLOCKED); 149 if (p != td->td_proc) 150 return (EPERM); 151 if ((p->p_treeflag & P_TREE_REAPER) != 0) 152 return (EBUSY); 153 p->p_treeflag |= P_TREE_REAPER; 154 /* 155 * We do not reattach existing children and the whole tree 156 * under them to us, since p->p_reaper already seen them. 157 */ 158 return (0); 159 } 160 161 static int 162 reap_release(struct thread *td, struct proc *p, void *data __unused) 163 { 164 165 sx_assert(&proctree_lock, SX_XLOCKED); 166 if (p != td->td_proc) 167 return (EPERM); 168 if (p == initproc) 169 return (EINVAL); 170 if ((p->p_treeflag & P_TREE_REAPER) == 0) 171 return (EINVAL); 172 reaper_abandon_children(p, false); 173 return (0); 174 } 175 176 static int 177 reap_status(struct thread *td, struct proc *p, void *data) 178 { 179 struct proc *reap, *p2, *first_p; 180 struct procctl_reaper_status *rs; 181 182 rs = data; 183 sx_assert(&proctree_lock, SX_LOCKED); 184 reap = get_reaper_or_p(p); 185 if (reap == p) 186 rs->rs_flags |= REAPER_STATUS_OWNED; 187 if (reap == initproc) 188 rs->rs_flags |= REAPER_STATUS_REALINIT; 189 rs->rs_reaper = reap->p_pid; 190 rs->rs_descendants = 0; 191 rs->rs_children = 0; 192 if (!LIST_EMPTY(&reap->p_reaplist)) { 193 first_p = LIST_FIRST(&reap->p_children); 194 if (first_p == NULL) 195 first_p = LIST_FIRST(&reap->p_reaplist); 196 rs->rs_pid = first_p->p_pid; 197 LIST_FOREACH(p2, &reap->p_reaplist, p_reapsibling) { 198 if (proc_realparent(p2) == reap) 199 rs->rs_children++; 200 rs->rs_descendants++; 201 } 202 } else { 203 rs->rs_pid = -1; 204 } 205 return (0); 206 } 207 208 static int 209 reap_getpids_count(struct proc **reapp, struct proc *p, 210 const struct procctl_reaper_pids *rp) 211 { 212 struct proc *reap, *p2; 213 int n; 214 215 sx_assert(&proctree_lock, SX_LOCKED); 216 217 reap = get_reaper_or_p(p); 218 n = 0; 219 LIST_FOREACH(p2, &reap->p_reaplist, p_reapsibling) 220 n++; 221 if (rp->rp_count < n) 222 n = rp->rp_count; 223 *reapp = reap; 224 return (n); 225 } 226 227 static int 228 reap_getpids(struct thread *td, struct proc *p, void *data) 229 { 230 struct proc *reap, *p2; 231 struct procctl_reaper_pidinfo *pi, *pip; 232 struct procctl_reaper_pids *rp; 233 u_int i, n, n1; 234 int error; 235 236 rp = data; 237 sx_assert(&proctree_lock, SX_LOCKED); 238 PROC_UNLOCK(p); 239 i = 0; 240 for (;;) { 241 n1 = reap_getpids_count(&reap, p, rp); 242 sx_unlock(&proctree_lock); 243 pi = mallocarray(n1, sizeof(*pi), M_TEMP, M_WAITOK); 244 sx_slock(&proctree_lock); 245 n = reap_getpids_count(&reap, p, rp); 246 if (n <= n1) 247 break; 248 free(pi, M_TEMP); 249 } 250 251 LIST_FOREACH(p2, &reap->p_reaplist, p_reapsibling) { 252 if (i == n) 253 break; 254 pip = &pi[i]; 255 bzero(pip, sizeof(*pip)); 256 pip->pi_pid = p2->p_pid; 257 pip->pi_subtree = p2->p_reapsubtree; 258 pip->pi_flags = REAPER_PIDINFO_VALID; 259 if (proc_realparent(p2) == reap) 260 pip->pi_flags |= REAPER_PIDINFO_CHILD; 261 if ((p2->p_treeflag & P_TREE_REAPER) != 0) 262 pip->pi_flags |= REAPER_PIDINFO_REAPER; 263 if ((p2->p_flag & P_STOPPED) != 0) 264 pip->pi_flags |= REAPER_PIDINFO_STOPPED; 265 if (p2->p_state == PRS_ZOMBIE) 266 pip->pi_flags |= REAPER_PIDINFO_ZOMBIE; 267 else if ((p2->p_flag & P_WEXIT) != 0) 268 pip->pi_flags |= REAPER_PIDINFO_EXITING; 269 i++; 270 } 271 sx_sunlock(&proctree_lock); 272 error = copyout(pi, rp->rp_pids, i * sizeof(*pi)); 273 free(pi, M_TEMP); 274 sx_slock(&proctree_lock); 275 PROC_LOCK(p); 276 return (error); 277 } 278 279 struct reap_kill_proc_work { 280 struct ucred *cr; 281 struct proc *target; 282 ksiginfo_t *ksi; 283 struct procctl_reaper_kill *rk; 284 int *error; 285 }; 286 287 static void 288 reap_kill_proc_locked(struct reap_kill_proc_work *w) 289 { 290 int error; 291 292 PROC_LOCK_ASSERT(w->target, MA_OWNED); 293 PROC_ASSERT_HELD(w->target); 294 295 error = cr_cansignal(w->cr, w->target, w->rk->rk_sig); 296 if (error != 0) { 297 /* 298 * Hide ESRCH errors to ensure that this function 299 * cannot be used as an oracle for process visibility. 300 */ 301 if (error != ESRCH && *w->error == 0) { 302 w->rk->rk_fpid = w->target->p_pid; 303 *w->error = error; 304 } 305 return; 306 } 307 308 (void)pksignal(w->target, w->rk->rk_sig, w->ksi); 309 w->rk->rk_killed++; 310 *w->error = error; 311 } 312 313 static void 314 reap_kill_proc(struct reap_kill_proc_work *w, bool *proctree_dropped) 315 { 316 struct pgrp *pgrp; 317 int xlocked; 318 319 sx_assert(&proctree_lock, SX_LOCKED); 320 xlocked = sx_xlocked(&proctree_lock); 321 PROC_LOCK_ASSERT(w->target, MA_OWNED); 322 PROC_ASSERT_HELD(w->target); 323 324 /* Sync with forks. */ 325 for (;;) { 326 /* 327 * Short-circuit handling of the exiting process, do 328 * not wait for it to single-thread (hold prevents it 329 * from exiting further). This avoids 330 * locking pg_killsx for it, and reduces the 331 * proctree_lock contention. 332 */ 333 if ((w->target->p_flag2 & P2_WEXIT) != 0) 334 return; 335 336 pgrp = w->target->p_pgrp; 337 if (pgrp == NULL || sx_try_xlock(&pgrp->pg_killsx)) 338 break; 339 340 PROC_UNLOCK(w->target); 341 sx_unlock(&proctree_lock); 342 /* This is safe because pgrp zone is nofree. */ 343 sx_xlock(&pgrp->pg_killsx); 344 sx_xunlock(&pgrp->pg_killsx); 345 *proctree_dropped = true; 346 if (xlocked) 347 sx_xlock(&proctree_lock); 348 else 349 sx_slock(&proctree_lock); 350 PROC_LOCK(w->target); 351 } 352 353 reap_kill_proc_locked(w); 354 355 if (pgrp != NULL) 356 sx_xunlock(&pgrp->pg_killsx); 357 } 358 359 struct reap_kill_tracker { 360 struct proc *parent; 361 TAILQ_ENTRY(reap_kill_tracker) link; 362 }; 363 364 TAILQ_HEAD(reap_kill_tracker_head, reap_kill_tracker); 365 366 static void 367 reap_kill_sched(struct reap_kill_tracker_head *tracker, struct proc *p2) 368 { 369 struct reap_kill_tracker *t; 370 371 PROC_TREE_REF(p2); 372 t = malloc(sizeof(struct reap_kill_tracker), M_TEMP, M_WAITOK); 373 t->parent = p2; 374 TAILQ_INSERT_TAIL(tracker, t, link); 375 } 376 377 static void 378 reap_kill_sched_free(struct reap_kill_tracker *t) 379 { 380 PROC_TREE_UNREF(t->parent); 381 free(t, M_TEMP); 382 } 383 384 static void 385 reap_kill_children(struct thread *td, struct proc *reaper, 386 struct procctl_reaper_kill *rk, ksiginfo_t *ksi, int *error) 387 { 388 struct proc *p2; 389 int error1; 390 391 LIST_FOREACH(p2, &reaper->p_children, p_sibling) { 392 PROC_LOCK(p2); 393 if ((p2->p_flag2 & P2_WEXIT) == 0) { 394 error1 = p_cansignal(td, p2, rk->rk_sig); 395 if (error1 != 0) { 396 if (*error == ESRCH) { 397 rk->rk_fpid = p2->p_pid; 398 *error = error1; 399 } 400 401 /* 402 * Do not end the loop on error, 403 * signal everything we can. 404 */ 405 } else { 406 (void)pksignal(p2, rk->rk_sig, ksi); 407 rk->rk_killed++; 408 } 409 } 410 PROC_UNLOCK(p2); 411 } 412 } 413 414 static bool 415 reap_kill_subtree_once(struct thread *td, struct proc *p, struct proc **reaperp, 416 struct unrhdr *pids, struct reap_kill_proc_work *w) 417 { 418 struct reap_kill_tracker_head tracker; 419 struct reap_kill_tracker *t; 420 struct proc *p2, *reaper, *old_reaper; 421 bool proctree_dropped, res; 422 423 res = false; 424 TAILQ_INIT(&tracker); 425 reaper = *reaperp; 426 reap_kill_sched(&tracker, reaper); 427 while ((t = TAILQ_FIRST(&tracker)) != NULL) { 428 TAILQ_REMOVE(&tracker, t, link); 429 430 again: 431 /* 432 * Since reap_kill_proc() drops proctree_lock sx, it 433 * is possible that the tracked reaper is no longer. 434 * In this case the subtree is reparented to the new 435 * reaper, which should handle it. 436 */ 437 if ((t->parent->p_treeflag & P_TREE_REAPER) == 0) { 438 reap_kill_sched_free(t); 439 res = true; 440 continue; 441 } 442 443 LIST_FOREACH(p2, &t->parent->p_reaplist, p_reapsibling) { 444 if (t->parent == reaper && 445 (w->rk->rk_flags & REAPER_KILL_SUBTREE) != 0 && 446 p2->p_reapsubtree != w->rk->rk_subtree) 447 continue; 448 if ((p2->p_treeflag & P_TREE_REAPER) != 0) 449 reap_kill_sched(&tracker, p2); 450 451 /* 452 * Handle possible pid reuse. If we recorded 453 * p2 as killed but its p_flag2 does not 454 * confirm it, that means that the process 455 * terminated and its id was reused by other 456 * process in the reaper subtree. 457 * 458 * Unlocked read of p2->p_flag2 is fine, it is 459 * our thread that set the tested flag. 460 */ 461 if (alloc_unr_specific(pids, p2->p_pid) != p2->p_pid && 462 (atomic_load_int(&p2->p_flag2) & 463 (P2_REAPKILLED | P2_WEXIT)) != 0) 464 continue; 465 466 proctree_dropped = false; 467 PROC_LOCK(p2); 468 if ((p2->p_flag2 & P2_WEXIT) == 0) { 469 _PHOLD(p2); 470 471 /* 472 * sapblk ensures that only one thread 473 * in the system sets this flag. 474 */ 475 p2->p_flag2 |= P2_REAPKILLED; 476 477 w->target = p2; 478 reap_kill_proc(w, &proctree_dropped); 479 _PRELE(p2); 480 } 481 PROC_UNLOCK(p2); 482 res = true; 483 if (proctree_dropped) { 484 old_reaper = reaper; 485 reaper = get_reaper_or_p(p); 486 if (old_reaper != reaper) { 487 *reaperp = reaper; 488 PROC_TREE_REF(reaper); 489 PROC_TREE_UNREF(old_reaper); 490 reap_kill_sched(&tracker, reaper); 491 /* 492 * Already scheduled kill 493 * actions should be kept on 494 * the schedule, the processes 495 * are inherited by the new 496 * reaper. 497 */ 498 } 499 goto again; 500 } 501 } 502 reap_kill_sched_free(t); 503 } 504 return (res); 505 } 506 507 static void 508 reap_kill_subtree(struct thread *td, struct proc *p, struct proc **reaperp, 509 struct reap_kill_proc_work *w) 510 { 511 struct unrhdr pids; 512 void *ihandle; 513 struct proc *p2; 514 int pid; 515 516 /* 517 * pids records processes which were already signalled, to 518 * avoid doubling signals to them if iteration needs to be 519 * repeated. 520 */ 521 init_unrhdr(&pids, 1, PID_MAX, UNR_NO_MTX); 522 PROC_LOCK(td->td_proc); 523 if ((td->td_proc->p_flag2 & P2_WEXIT) != 0) { 524 PROC_UNLOCK(td->td_proc); 525 goto out; 526 } 527 PROC_UNLOCK(td->td_proc); 528 while (reap_kill_subtree_once(td, p, reaperp, &pids, w)) 529 ; 530 531 ihandle = create_iter_unr(&pids); 532 while ((pid = next_iter_unr(ihandle)) != -1) { 533 p2 = pfind(pid); 534 if (p2 != NULL) { 535 p2->p_flag2 &= ~P2_REAPKILLED; 536 PROC_UNLOCK(p2); 537 } 538 } 539 free_iter_unr(ihandle); 540 541 out: 542 clean_unrhdr(&pids); 543 clear_unrhdr(&pids); 544 } 545 546 static bool 547 reap_kill_sapblk(struct thread *td __unused, void *data) 548 { 549 struct procctl_reaper_kill *rk; 550 551 rk = data; 552 return ((rk->rk_flags & REAPER_KILL_CHILDREN) == 0); 553 } 554 555 static int 556 reap_kill(struct thread *td, struct proc *p, void *data) 557 { 558 struct reap_kill_proc_work w; 559 struct proc *reaper; 560 ksiginfo_t ksi; 561 struct procctl_reaper_kill *rk; 562 int error; 563 564 rk = data; 565 sx_assert(&proctree_lock, SX_LOCKED); 566 if (CAP_TRACING(td)) 567 ktrcapfail(CAPFAIL_SIGNAL, &rk->rk_sig); 568 if (IN_CAPABILITY_MODE(td)) 569 return (ECAPMODE); 570 if (rk->rk_sig <= 0 || rk->rk_sig > _SIG_MAXSIG || 571 (rk->rk_flags & ~(REAPER_KILL_CHILDREN | 572 REAPER_KILL_SUBTREE)) != 0 || (rk->rk_flags & 573 (REAPER_KILL_CHILDREN | REAPER_KILL_SUBTREE)) == 574 (REAPER_KILL_CHILDREN | REAPER_KILL_SUBTREE)) 575 return (EINVAL); 576 PROC_UNLOCK(p); 577 reaper = get_reaper_or_p(p); 578 579 ksiginfo_init(&ksi); 580 ksi.ksi_signo = rk->rk_sig; 581 ksi.ksi_code = SI_USER; 582 ksi.ksi_pid = td->td_proc->p_pid; 583 ksi.ksi_uid = td->td_ucred->cr_ruid; 584 error = ESRCH; 585 rk->rk_killed = 0; 586 rk->rk_fpid = -1; 587 if ((rk->rk_flags & REAPER_KILL_CHILDREN) != 0) { 588 reap_kill_children(td, reaper, rk, &ksi, &error); 589 } else { 590 w.cr = crhold(td->td_ucred); 591 w.ksi = &ksi; 592 w.rk = rk; 593 w.error = &error; 594 PROC_TREE_REF(reaper); 595 reap_kill_subtree(td, p, &reaper, &w); 596 PROC_TREE_UNREF(reaper); 597 crfree(w.cr); 598 } 599 PROC_LOCK(p); 600 return (error); 601 } 602 603 static int 604 trace_ctl(struct thread *td, struct proc *p, void *data) 605 { 606 int state; 607 608 PROC_LOCK_ASSERT(p, MA_OWNED); 609 state = *(int *)data; 610 611 /* 612 * Ktrace changes p_traceflag from or to zero under the 613 * process lock, so the test does not need to acquire ktrace 614 * mutex. 615 */ 616 if ((p->p_flag & P_TRACED) != 0 || p->p_traceflag != 0) 617 return (EBUSY); 618 619 switch (state) { 620 case PROC_TRACE_CTL_ENABLE: 621 if (td->td_proc != p) 622 return (EPERM); 623 p->p_flag2 &= ~(P2_NOTRACE | P2_NOTRACE_EXEC); 624 break; 625 case PROC_TRACE_CTL_DISABLE_EXEC: 626 p->p_flag2 |= P2_NOTRACE_EXEC | P2_NOTRACE; 627 break; 628 case PROC_TRACE_CTL_DISABLE: 629 if ((p->p_flag2 & P2_NOTRACE_EXEC) != 0) { 630 KASSERT((p->p_flag2 & P2_NOTRACE) != 0, 631 ("dandling P2_NOTRACE_EXEC")); 632 if (td->td_proc != p) 633 return (EPERM); 634 p->p_flag2 &= ~P2_NOTRACE_EXEC; 635 } else { 636 p->p_flag2 |= P2_NOTRACE; 637 } 638 break; 639 default: 640 return (EINVAL); 641 } 642 return (0); 643 } 644 645 static int 646 trace_status(struct thread *td, struct proc *p, void *data) 647 { 648 int *status; 649 650 status = data; 651 if ((p->p_flag2 & P2_NOTRACE) != 0) { 652 KASSERT((p->p_flag & P_TRACED) == 0, 653 ("%d traced but tracing disabled", p->p_pid)); 654 *status = -1; 655 } else if ((p->p_flag & P_TRACED) != 0) { 656 *status = p->p_pptr->p_pid; 657 } else { 658 *status = 0; 659 } 660 return (0); 661 } 662 663 static int 664 trapcap_ctl(struct thread *td, struct proc *p, void *data) 665 { 666 int state; 667 668 PROC_LOCK_ASSERT(p, MA_OWNED); 669 state = *(int *)data; 670 671 switch (state) { 672 case PROC_TRAPCAP_CTL_ENABLE: 673 p->p_flag2 |= P2_TRAPCAP; 674 break; 675 case PROC_TRAPCAP_CTL_DISABLE: 676 p->p_flag2 &= ~P2_TRAPCAP; 677 break; 678 default: 679 return (EINVAL); 680 } 681 return (0); 682 } 683 684 static int 685 trapcap_status(struct thread *td, struct proc *p, void *data) 686 { 687 int *status; 688 689 status = data; 690 *status = (p->p_flag2 & P2_TRAPCAP) != 0 ? PROC_TRAPCAP_CTL_ENABLE : 691 PROC_TRAPCAP_CTL_DISABLE; 692 return (0); 693 } 694 695 static int 696 no_new_privs_ctl(struct thread *td, struct proc *p, void *data) 697 { 698 int state; 699 700 PROC_LOCK_ASSERT(p, MA_OWNED); 701 state = *(int *)data; 702 703 if (state != PROC_NO_NEW_PRIVS_ENABLE) 704 return (EINVAL); 705 p->p_flag2 |= P2_NO_NEW_PRIVS; 706 return (0); 707 } 708 709 static int 710 no_new_privs_status(struct thread *td, struct proc *p, void *data) 711 { 712 713 *(int *)data = (p->p_flag2 & P2_NO_NEW_PRIVS) != 0 ? 714 PROC_NO_NEW_PRIVS_ENABLE : PROC_NO_NEW_PRIVS_DISABLE; 715 return (0); 716 } 717 718 static int 719 protmax_ctl(struct thread *td, struct proc *p, void *data) 720 { 721 int state; 722 723 PROC_LOCK_ASSERT(p, MA_OWNED); 724 state = *(int *)data; 725 726 switch (state) { 727 case PROC_PROTMAX_FORCE_ENABLE: 728 p->p_flag2 &= ~P2_PROTMAX_DISABLE; 729 p->p_flag2 |= P2_PROTMAX_ENABLE; 730 break; 731 case PROC_PROTMAX_FORCE_DISABLE: 732 p->p_flag2 |= P2_PROTMAX_DISABLE; 733 p->p_flag2 &= ~P2_PROTMAX_ENABLE; 734 break; 735 case PROC_PROTMAX_NOFORCE: 736 p->p_flag2 &= ~(P2_PROTMAX_ENABLE | P2_PROTMAX_DISABLE); 737 break; 738 default: 739 return (EINVAL); 740 } 741 return (0); 742 } 743 744 static int 745 protmax_status(struct thread *td, struct proc *p, void *data) 746 { 747 int d; 748 749 switch (p->p_flag2 & (P2_PROTMAX_ENABLE | P2_PROTMAX_DISABLE)) { 750 case 0: 751 d = PROC_PROTMAX_NOFORCE; 752 break; 753 case P2_PROTMAX_ENABLE: 754 d = PROC_PROTMAX_FORCE_ENABLE; 755 break; 756 case P2_PROTMAX_DISABLE: 757 d = PROC_PROTMAX_FORCE_DISABLE; 758 break; 759 } 760 if (kern_mmap_maxprot(p, PROT_READ) == PROT_READ) 761 d |= PROC_PROTMAX_ACTIVE; 762 *(int *)data = d; 763 return (0); 764 } 765 766 static int 767 aslr_ctl(struct thread *td, struct proc *p, void *data) 768 { 769 int state; 770 771 PROC_LOCK_ASSERT(p, MA_OWNED); 772 state = *(int *)data; 773 774 switch (state) { 775 case PROC_ASLR_FORCE_ENABLE: 776 p->p_flag2 &= ~P2_ASLR_DISABLE; 777 p->p_flag2 |= P2_ASLR_ENABLE; 778 break; 779 case PROC_ASLR_FORCE_DISABLE: 780 p->p_flag2 |= P2_ASLR_DISABLE; 781 p->p_flag2 &= ~P2_ASLR_ENABLE; 782 break; 783 case PROC_ASLR_NOFORCE: 784 p->p_flag2 &= ~(P2_ASLR_ENABLE | P2_ASLR_DISABLE); 785 break; 786 default: 787 return (EINVAL); 788 } 789 return (0); 790 } 791 792 static int 793 aslr_status(struct thread *td, struct proc *p, void *data) 794 { 795 struct vmspace *vm; 796 int d; 797 798 switch (p->p_flag2 & (P2_ASLR_ENABLE | P2_ASLR_DISABLE)) { 799 case 0: 800 d = PROC_ASLR_NOFORCE; 801 break; 802 case P2_ASLR_ENABLE: 803 d = PROC_ASLR_FORCE_ENABLE; 804 break; 805 case P2_ASLR_DISABLE: 806 d = PROC_ASLR_FORCE_DISABLE; 807 break; 808 } 809 PROC_UNLOCK(p); 810 vm = vmspace_acquire_ref(p); 811 if (vm != NULL) { 812 if ((vm->vm_map.flags & MAP_ASLR) != 0) 813 d |= PROC_ASLR_ACTIVE; 814 vmspace_free(vm); 815 } 816 *(int *)data = d; 817 PROC_LOCK(p); 818 return (0); 819 } 820 821 static int 822 stackgap_ctl(struct thread *td, struct proc *p, void *data) 823 { 824 int state; 825 826 PROC_LOCK_ASSERT(p, MA_OWNED); 827 state = *(int *)data; 828 829 if ((state & ~(PROC_STACKGAP_ENABLE | PROC_STACKGAP_DISABLE | 830 PROC_STACKGAP_ENABLE_EXEC | PROC_STACKGAP_DISABLE_EXEC)) != 0) 831 return (EINVAL); 832 switch (state & (PROC_STACKGAP_ENABLE | PROC_STACKGAP_DISABLE)) { 833 case PROC_STACKGAP_ENABLE: 834 if ((p->p_flag2 & P2_STKGAP_DISABLE) != 0) 835 return (EINVAL); 836 break; 837 case PROC_STACKGAP_DISABLE: 838 p->p_flag2 |= P2_STKGAP_DISABLE; 839 break; 840 case 0: 841 break; 842 default: 843 return (EINVAL); 844 } 845 switch (state & (PROC_STACKGAP_ENABLE_EXEC | 846 PROC_STACKGAP_DISABLE_EXEC)) { 847 case PROC_STACKGAP_ENABLE_EXEC: 848 p->p_flag2 &= ~P2_STKGAP_DISABLE_EXEC; 849 break; 850 case PROC_STACKGAP_DISABLE_EXEC: 851 p->p_flag2 |= P2_STKGAP_DISABLE_EXEC; 852 break; 853 case 0: 854 break; 855 default: 856 return (EINVAL); 857 } 858 return (0); 859 } 860 861 static int 862 stackgap_status(struct thread *td, struct proc *p, void *data) 863 { 864 int d; 865 866 PROC_LOCK_ASSERT(p, MA_OWNED); 867 868 d = (p->p_flag2 & P2_STKGAP_DISABLE) != 0 ? PROC_STACKGAP_DISABLE : 869 PROC_STACKGAP_ENABLE; 870 d |= (p->p_flag2 & P2_STKGAP_DISABLE_EXEC) != 0 ? 871 PROC_STACKGAP_DISABLE_EXEC : PROC_STACKGAP_ENABLE_EXEC; 872 *(int *)data = d; 873 return (0); 874 } 875 876 static int 877 wxmap_ctl(struct thread *td, struct proc *p, void *data) 878 { 879 struct vmspace *vm; 880 vm_map_t map; 881 int error, state; 882 883 PROC_LOCK_ASSERT(p, MA_OWNED); 884 state = *(int *)data; 885 error = 0; 886 887 switch (state) { 888 case PROC_WX_MAPPINGS_PERMIT: 889 PROC_UNLOCK(p); 890 error = proc_vmspace_ref(td, p, PRVM_BLOCK_EXEC | 891 PRVM_CHECK_DEBUG, &vm); 892 if (error == 0) { 893 map = &vm->vm_map; 894 vm_map_lock(map); 895 map->flags &= ~MAP_WXORX; 896 vm_map_unlock(map); 897 PROC_LOCK(p); 898 p->p_flag2 |= P2_WXORX_DISABLE; 899 PROC_UNLOCK(p); 900 proc_vmspace_unref(td, p, PRVM_BLOCK_EXEC | 901 PRVM_CHECK_DEBUG, vm); 902 } 903 PROC_LOCK(p); 904 break; 905 case PROC_WX_MAPPINGS_DISALLOW_EXEC: 906 p->p_flag2 |= P2_WXORX_ENABLE_EXEC; 907 break; 908 default: 909 error = EINVAL; 910 break; 911 } 912 913 return (error); 914 } 915 916 static int 917 wxmap_status(struct thread *td, struct proc *p, void *data) 918 { 919 struct vmspace *vm; 920 int d; 921 922 PROC_LOCK_ASSERT(p, MA_OWNED); 923 924 d = 0; 925 if ((p->p_flag2 & P2_WXORX_DISABLE) != 0) 926 d |= PROC_WX_MAPPINGS_PERMIT; 927 if ((p->p_flag2 & P2_WXORX_ENABLE_EXEC) != 0) 928 d |= PROC_WX_MAPPINGS_DISALLOW_EXEC; 929 PROC_UNLOCK(p); 930 vm = vmspace_acquire_ref(p); 931 if (vm != NULL) { 932 if ((vm->vm_map.flags & MAP_WXORX) != 0) 933 d |= PROC_WXORX_ENFORCE; 934 vmspace_free(vm); 935 } 936 *(int *)data = d; 937 PROC_LOCK(p); 938 return (0); 939 } 940 941 static int 942 pdeathsig_ctl(struct thread *td, struct proc *p, void *data) 943 { 944 int signum; 945 946 signum = *(int *)data; 947 if (p != td->td_proc || (signum != 0 && !_SIG_VALID(signum))) 948 return (EINVAL); 949 p->p_pdeathsig = signum; 950 return (0); 951 } 952 953 static int 954 pdeathsig_status(struct thread *td, struct proc *p, void *data) 955 { 956 if (p != td->td_proc) 957 return (EINVAL); 958 *(int *)data = p->p_pdeathsig; 959 return (0); 960 } 961 962 static int 963 logsigexit_ctl(struct thread *td, struct proc *p, void *data) 964 { 965 int state; 966 967 PROC_LOCK_ASSERT(p, MA_OWNED); 968 state = *(int *)data; 969 970 switch (state) { 971 case PROC_LOGSIGEXIT_CTL_NOFORCE: 972 p->p_flag2 &= ~(P2_LOGSIGEXIT_CTL | P2_LOGSIGEXIT_ENABLE); 973 break; 974 case PROC_LOGSIGEXIT_CTL_FORCE_ENABLE: 975 p->p_flag2 |= P2_LOGSIGEXIT_CTL | P2_LOGSIGEXIT_ENABLE; 976 break; 977 case PROC_LOGSIGEXIT_CTL_FORCE_DISABLE: 978 p->p_flag2 |= P2_LOGSIGEXIT_CTL; 979 p->p_flag2 &= ~P2_LOGSIGEXIT_ENABLE; 980 break; 981 default: 982 return (EINVAL); 983 } 984 return (0); 985 } 986 987 static int 988 logsigexit_status(struct thread *td, struct proc *p, void *data) 989 { 990 int state; 991 992 if ((p->p_flag2 & P2_LOGSIGEXIT_CTL) == 0) 993 state = PROC_LOGSIGEXIT_CTL_NOFORCE; 994 else if ((p->p_flag2 & P2_LOGSIGEXIT_ENABLE) != 0) 995 state = PROC_LOGSIGEXIT_CTL_FORCE_ENABLE; 996 else 997 state = PROC_LOGSIGEXIT_CTL_FORCE_DISABLE; 998 *(int *)data = state; 999 return (0); 1000 } 1001 1002 enum { 1003 PCTL_SLOCKED, 1004 PCTL_XLOCKED, 1005 PCTL_UNLOCKED, 1006 }; 1007 1008 struct procctl_cmd_info { 1009 int lock_tree; 1010 bool one_proc : 1; 1011 bool esrch_is_einval : 1; 1012 bool copyout_on_error : 1; 1013 bool no_nonnull_data : 1; 1014 bool need_candebug : 1; 1015 int copyin_sz; 1016 int copyout_sz; 1017 int (*exec)(struct thread *, struct proc *, void *); 1018 bool (*sapblk)(struct thread *, void *); 1019 }; 1020 static const struct procctl_cmd_info procctl_cmds_info[] = { 1021 [PROC_SPROTECT] = 1022 { .lock_tree = PCTL_SLOCKED, .one_proc = false, 1023 .esrch_is_einval = false, .no_nonnull_data = false, 1024 .need_candebug = false, 1025 .copyin_sz = sizeof(int), .copyout_sz = 0, 1026 .exec = protect_set, .copyout_on_error = false, }, 1027 [PROC_REAP_ACQUIRE] = 1028 { .lock_tree = PCTL_XLOCKED, .one_proc = true, 1029 .esrch_is_einval = false, .no_nonnull_data = true, 1030 .need_candebug = false, 1031 .copyin_sz = 0, .copyout_sz = 0, 1032 .exec = reap_acquire, .copyout_on_error = false, }, 1033 [PROC_REAP_RELEASE] = 1034 { .lock_tree = PCTL_XLOCKED, .one_proc = true, 1035 .esrch_is_einval = false, .no_nonnull_data = true, 1036 .need_candebug = false, 1037 .copyin_sz = 0, .copyout_sz = 0, 1038 .exec = reap_release, .copyout_on_error = false, }, 1039 [PROC_REAP_STATUS] = 1040 { .lock_tree = PCTL_SLOCKED, .one_proc = true, 1041 .esrch_is_einval = false, .no_nonnull_data = false, 1042 .need_candebug = false, 1043 .copyin_sz = 0, 1044 .copyout_sz = sizeof(struct procctl_reaper_status), 1045 .exec = reap_status, .copyout_on_error = false, }, 1046 [PROC_REAP_GETPIDS] = 1047 { .lock_tree = PCTL_SLOCKED, .one_proc = true, 1048 .esrch_is_einval = false, .no_nonnull_data = false, 1049 .need_candebug = false, 1050 .copyin_sz = sizeof(struct procctl_reaper_pids), 1051 .copyout_sz = 0, 1052 .exec = reap_getpids, .copyout_on_error = false, }, 1053 [PROC_REAP_KILL] = 1054 { .lock_tree = PCTL_SLOCKED, .one_proc = true, 1055 .esrch_is_einval = false, .no_nonnull_data = false, 1056 .need_candebug = false, 1057 .copyin_sz = sizeof(struct procctl_reaper_kill), 1058 .copyout_sz = sizeof(struct procctl_reaper_kill), 1059 .exec = reap_kill, .copyout_on_error = true, 1060 .sapblk = reap_kill_sapblk, }, 1061 [PROC_TRACE_CTL] = 1062 { .lock_tree = PCTL_SLOCKED, .one_proc = false, 1063 .esrch_is_einval = false, .no_nonnull_data = false, 1064 .need_candebug = true, 1065 .copyin_sz = sizeof(int), .copyout_sz = 0, 1066 .exec = trace_ctl, .copyout_on_error = false, }, 1067 [PROC_TRACE_STATUS] = 1068 { .lock_tree = PCTL_UNLOCKED, .one_proc = true, 1069 .esrch_is_einval = false, .no_nonnull_data = false, 1070 .need_candebug = false, 1071 .copyin_sz = 0, .copyout_sz = sizeof(int), 1072 .exec = trace_status, .copyout_on_error = false, }, 1073 [PROC_TRAPCAP_CTL] = 1074 { .lock_tree = PCTL_SLOCKED, .one_proc = false, 1075 .esrch_is_einval = false, .no_nonnull_data = false, 1076 .need_candebug = true, 1077 .copyin_sz = sizeof(int), .copyout_sz = 0, 1078 .exec = trapcap_ctl, .copyout_on_error = false, }, 1079 [PROC_TRAPCAP_STATUS] = 1080 { .lock_tree = PCTL_UNLOCKED, .one_proc = true, 1081 .esrch_is_einval = false, .no_nonnull_data = false, 1082 .need_candebug = false, 1083 .copyin_sz = 0, .copyout_sz = sizeof(int), 1084 .exec = trapcap_status, .copyout_on_error = false, }, 1085 [PROC_PDEATHSIG_CTL] = 1086 { .lock_tree = PCTL_UNLOCKED, .one_proc = true, 1087 .esrch_is_einval = true, .no_nonnull_data = false, 1088 .need_candebug = false, 1089 .copyin_sz = sizeof(int), .copyout_sz = 0, 1090 .exec = pdeathsig_ctl, .copyout_on_error = false, }, 1091 [PROC_PDEATHSIG_STATUS] = 1092 { .lock_tree = PCTL_UNLOCKED, .one_proc = true, 1093 .esrch_is_einval = true, .no_nonnull_data = false, 1094 .need_candebug = false, 1095 .copyin_sz = 0, .copyout_sz = sizeof(int), 1096 .exec = pdeathsig_status, .copyout_on_error = false, }, 1097 [PROC_ASLR_CTL] = 1098 { .lock_tree = PCTL_UNLOCKED, .one_proc = true, 1099 .esrch_is_einval = false, .no_nonnull_data = false, 1100 .need_candebug = true, 1101 .copyin_sz = sizeof(int), .copyout_sz = 0, 1102 .exec = aslr_ctl, .copyout_on_error = false, }, 1103 [PROC_ASLR_STATUS] = 1104 { .lock_tree = PCTL_UNLOCKED, .one_proc = true, 1105 .esrch_is_einval = false, .no_nonnull_data = false, 1106 .need_candebug = false, 1107 .copyin_sz = 0, .copyout_sz = sizeof(int), 1108 .exec = aslr_status, .copyout_on_error = false, }, 1109 [PROC_PROTMAX_CTL] = 1110 { .lock_tree = PCTL_UNLOCKED, .one_proc = true, 1111 .esrch_is_einval = false, .no_nonnull_data = false, 1112 .need_candebug = true, 1113 .copyin_sz = sizeof(int), .copyout_sz = 0, 1114 .exec = protmax_ctl, .copyout_on_error = false, }, 1115 [PROC_PROTMAX_STATUS] = 1116 { .lock_tree = PCTL_UNLOCKED, .one_proc = true, 1117 .esrch_is_einval = false, .no_nonnull_data = false, 1118 .need_candebug = false, 1119 .copyin_sz = 0, .copyout_sz = sizeof(int), 1120 .exec = protmax_status, .copyout_on_error = false, }, 1121 [PROC_STACKGAP_CTL] = 1122 { .lock_tree = PCTL_UNLOCKED, .one_proc = true, 1123 .esrch_is_einval = false, .no_nonnull_data = false, 1124 .need_candebug = true, 1125 .copyin_sz = sizeof(int), .copyout_sz = 0, 1126 .exec = stackgap_ctl, .copyout_on_error = false, }, 1127 [PROC_STACKGAP_STATUS] = 1128 { .lock_tree = PCTL_UNLOCKED, .one_proc = true, 1129 .esrch_is_einval = false, .no_nonnull_data = false, 1130 .need_candebug = false, 1131 .copyin_sz = 0, .copyout_sz = sizeof(int), 1132 .exec = stackgap_status, .copyout_on_error = false, }, 1133 [PROC_NO_NEW_PRIVS_CTL] = 1134 { .lock_tree = PCTL_SLOCKED, .one_proc = true, 1135 .esrch_is_einval = false, .no_nonnull_data = false, 1136 .need_candebug = true, 1137 .copyin_sz = sizeof(int), .copyout_sz = 0, 1138 .exec = no_new_privs_ctl, .copyout_on_error = false, }, 1139 [PROC_NO_NEW_PRIVS_STATUS] = 1140 { .lock_tree = PCTL_UNLOCKED, .one_proc = true, 1141 .esrch_is_einval = false, .no_nonnull_data = false, 1142 .need_candebug = false, 1143 .copyin_sz = 0, .copyout_sz = sizeof(int), 1144 .exec = no_new_privs_status, .copyout_on_error = false, }, 1145 [PROC_WXMAP_CTL] = 1146 { .lock_tree = PCTL_UNLOCKED, .one_proc = true, 1147 .esrch_is_einval = false, .no_nonnull_data = false, 1148 .need_candebug = true, 1149 .copyin_sz = sizeof(int), .copyout_sz = 0, 1150 .exec = wxmap_ctl, .copyout_on_error = false, }, 1151 [PROC_WXMAP_STATUS] = 1152 { .lock_tree = PCTL_UNLOCKED, .one_proc = true, 1153 .esrch_is_einval = false, .no_nonnull_data = false, 1154 .need_candebug = false, 1155 .copyin_sz = 0, .copyout_sz = sizeof(int), 1156 .exec = wxmap_status, .copyout_on_error = false, }, 1157 [PROC_LOGSIGEXIT_CTL] = 1158 { .lock_tree = PCTL_SLOCKED, .one_proc = true, 1159 .esrch_is_einval = false, .no_nonnull_data = false, 1160 .need_candebug = true, 1161 .copyin_sz = sizeof(int), .copyout_sz = 0, 1162 .exec = logsigexit_ctl, .copyout_on_error = false, }, 1163 [PROC_LOGSIGEXIT_STATUS] = 1164 { .lock_tree = PCTL_UNLOCKED, .one_proc = true, 1165 .esrch_is_einval = false, .no_nonnull_data = false, 1166 .need_candebug = false, 1167 .copyin_sz = 0, .copyout_sz = sizeof(int), 1168 .exec = logsigexit_status, .copyout_on_error = false, }, 1169 }; 1170 1171 int 1172 sys_procctl(struct thread *td, struct procctl_args *uap) 1173 { 1174 union { 1175 struct procctl_reaper_status rs; 1176 struct procctl_reaper_pids rp; 1177 struct procctl_reaper_kill rk; 1178 int flags; 1179 } x; 1180 const struct procctl_cmd_info *cmd_info; 1181 int error, error1; 1182 1183 if (uap->com >= PROC_PROCCTL_MD_MIN) 1184 return (cpu_procctl(td, uap->idtype, uap->id, 1185 uap->com, uap->data)); 1186 if (uap->com <= 0 || uap->com >= nitems(procctl_cmds_info)) 1187 return (EINVAL); 1188 cmd_info = &procctl_cmds_info[uap->com]; 1189 bzero(&x, sizeof(x)); 1190 1191 if (cmd_info->copyin_sz > 0) { 1192 error = copyin(uap->data, &x, cmd_info->copyin_sz); 1193 if (error != 0) 1194 return (error); 1195 } else if (cmd_info->no_nonnull_data && uap->data != NULL) { 1196 return (EINVAL); 1197 } 1198 1199 error = kern_procctl(td, uap->idtype, uap->id, uap->com, &x); 1200 1201 if (cmd_info->copyout_sz > 0 && (error == 0 || 1202 cmd_info->copyout_on_error)) { 1203 error1 = copyout(&x, uap->data, cmd_info->copyout_sz); 1204 if (error == 0) 1205 error = error1; 1206 } 1207 return (error); 1208 } 1209 1210 static int 1211 kern_procctl_single(struct thread *td, struct proc *p, int com, void *data) 1212 { 1213 int error; 1214 1215 PROC_LOCK_ASSERT(p, MA_OWNED); 1216 if ((p->p_flag & P_WEXIT) != 0) 1217 return (ESRCH); 1218 _PHOLD(p); 1219 error = procctl_cmds_info[com].exec(td, p, data); 1220 _PRELE(p); 1221 return (error); 1222 } 1223 1224 int 1225 kern_procctl(struct thread *td, idtype_t idtype, id_t id, int com, void *data) 1226 { 1227 struct pgrp *pg; 1228 struct proc *p; 1229 const struct procctl_cmd_info *cmd_info; 1230 int error, first_error, ok; 1231 bool sapblk; 1232 1233 MPASS(com > 0 && com < nitems(procctl_cmds_info)); 1234 cmd_info = &procctl_cmds_info[com]; 1235 if (idtype != P_PID && cmd_info->one_proc) 1236 return (EINVAL); 1237 1238 sapblk = false; 1239 if (cmd_info->sapblk != NULL) { 1240 sapblk = cmd_info->sapblk(td, data); 1241 if (sapblk && !stop_all_proc_block()) 1242 return (ERESTART); 1243 } 1244 1245 switch (cmd_info->lock_tree) { 1246 case PCTL_XLOCKED: 1247 sx_xlock(&proctree_lock); 1248 break; 1249 case PCTL_SLOCKED: 1250 sx_slock(&proctree_lock); 1251 break; 1252 default: 1253 break; 1254 } 1255 1256 switch (idtype) { 1257 case P_PID: 1258 if (id == 0) { 1259 p = td->td_proc; 1260 error = 0; 1261 PROC_LOCK(p); 1262 } else { 1263 p = pfind(id); 1264 if (p == NULL) { 1265 error = cmd_info->esrch_is_einval ? 1266 EINVAL : ESRCH; 1267 break; 1268 } 1269 error = cmd_info->need_candebug ? p_candebug(td, p) : 1270 p_cansee(td, p); 1271 } 1272 if (error == 0) 1273 error = kern_procctl_single(td, p, com, data); 1274 PROC_UNLOCK(p); 1275 break; 1276 case P_PGID: 1277 /* 1278 * Attempt to apply the operation to all members of the 1279 * group. Ignore processes in the group that can't be 1280 * seen. Ignore errors so long as at least one process is 1281 * able to complete the request successfully. 1282 */ 1283 pg = pgfind(id); 1284 if (pg == NULL) { 1285 error = ESRCH; 1286 break; 1287 } 1288 PGRP_UNLOCK(pg); 1289 ok = 0; 1290 first_error = 0; 1291 LIST_FOREACH(p, &pg->pg_members, p_pglist) { 1292 PROC_LOCK(p); 1293 if (p->p_state == PRS_NEW || 1294 p->p_state == PRS_ZOMBIE || 1295 (cmd_info->need_candebug ? p_candebug(td, p) : 1296 p_cansee(td, p)) != 0) { 1297 PROC_UNLOCK(p); 1298 continue; 1299 } 1300 error = kern_procctl_single(td, p, com, data); 1301 PROC_UNLOCK(p); 1302 if (error == 0) 1303 ok = 1; 1304 else if (first_error == 0) 1305 first_error = error; 1306 } 1307 if (ok) 1308 error = 0; 1309 else if (first_error != 0) 1310 error = first_error; 1311 else 1312 /* 1313 * Was not able to see any processes in the 1314 * process group. 1315 */ 1316 error = ESRCH; 1317 break; 1318 default: 1319 error = EINVAL; 1320 break; 1321 } 1322 1323 switch (cmd_info->lock_tree) { 1324 case PCTL_XLOCKED: 1325 sx_xunlock(&proctree_lock); 1326 break; 1327 case PCTL_SLOCKED: 1328 sx_sunlock(&proctree_lock); 1329 break; 1330 default: 1331 break; 1332 } 1333 if (sapblk) 1334 stop_all_proc_unblock(); 1335 return (error); 1336 } 1337