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 <sys/cdefs.h> 31 __FBSDID("$FreeBSD$"); 32 33 #include <sys/param.h> 34 #include <sys/_unrhdr.h> 35 #include <sys/systm.h> 36 #include <sys/capsicum.h> 37 #include <sys/lock.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/sx.h> 44 #include <sys/syscallsubr.h> 45 #include <sys/sysproto.h> 46 #include <sys/wait.h> 47 48 #include <vm/vm.h> 49 #include <vm/pmap.h> 50 #include <vm/vm_map.h> 51 #include <vm/vm_extern.h> 52 53 static int 54 protect_setchild(struct thread *td, struct proc *p, int flags) 55 { 56 57 PROC_LOCK_ASSERT(p, MA_OWNED); 58 if (p->p_flag & P_SYSTEM || p_cansched(td, p) != 0) 59 return (0); 60 if (flags & PPROT_SET) { 61 p->p_flag |= P_PROTECTED; 62 if (flags & PPROT_INHERIT) 63 p->p_flag2 |= P2_INHERIT_PROTECTED; 64 } else { 65 p->p_flag &= ~P_PROTECTED; 66 p->p_flag2 &= ~P2_INHERIT_PROTECTED; 67 } 68 return (1); 69 } 70 71 static int 72 protect_setchildren(struct thread *td, struct proc *top, int flags) 73 { 74 struct proc *p; 75 int ret; 76 77 p = top; 78 ret = 0; 79 sx_assert(&proctree_lock, SX_LOCKED); 80 for (;;) { 81 ret |= protect_setchild(td, p, flags); 82 PROC_UNLOCK(p); 83 /* 84 * If this process has children, descend to them next, 85 * otherwise do any siblings, and if done with this level, 86 * follow back up the tree (but not past top). 87 */ 88 if (!LIST_EMPTY(&p->p_children)) 89 p = LIST_FIRST(&p->p_children); 90 else for (;;) { 91 if (p == top) { 92 PROC_LOCK(p); 93 return (ret); 94 } 95 if (LIST_NEXT(p, p_sibling)) { 96 p = LIST_NEXT(p, p_sibling); 97 break; 98 } 99 p = p->p_pptr; 100 } 101 PROC_LOCK(p); 102 } 103 } 104 105 static int 106 protect_set(struct thread *td, struct proc *p, void *data) 107 { 108 int error, flags, ret; 109 110 flags = *(int *)data; 111 switch (PPROT_OP(flags)) { 112 case PPROT_SET: 113 case PPROT_CLEAR: 114 break; 115 default: 116 return (EINVAL); 117 } 118 119 if ((PPROT_FLAGS(flags) & ~(PPROT_DESCEND | PPROT_INHERIT)) != 0) 120 return (EINVAL); 121 122 error = priv_check(td, PRIV_VM_MADV_PROTECT); 123 if (error) 124 return (error); 125 126 if (flags & PPROT_DESCEND) 127 ret = protect_setchildren(td, p, flags); 128 else 129 ret = protect_setchild(td, p, flags); 130 if (ret == 0) 131 return (EPERM); 132 return (0); 133 } 134 135 static int 136 reap_acquire(struct thread *td, struct proc *p, void *data __unused) 137 { 138 139 sx_assert(&proctree_lock, SX_XLOCKED); 140 if (p != td->td_proc) 141 return (EPERM); 142 if ((p->p_treeflag & P_TREE_REAPER) != 0) 143 return (EBUSY); 144 p->p_treeflag |= P_TREE_REAPER; 145 /* 146 * We do not reattach existing children and the whole tree 147 * under them to us, since p->p_reaper already seen them. 148 */ 149 return (0); 150 } 151 152 static int 153 reap_release(struct thread *td, struct proc *p, void *data __unused) 154 { 155 156 sx_assert(&proctree_lock, SX_XLOCKED); 157 if (p != td->td_proc) 158 return (EPERM); 159 if (p == initproc) 160 return (EINVAL); 161 if ((p->p_treeflag & P_TREE_REAPER) == 0) 162 return (EINVAL); 163 reaper_abandon_children(p, false); 164 return (0); 165 } 166 167 static int 168 reap_status(struct thread *td, struct proc *p, void *data) 169 { 170 struct proc *reap, *p2, *first_p; 171 struct procctl_reaper_status *rs; 172 173 rs = data; 174 sx_assert(&proctree_lock, SX_LOCKED); 175 if ((p->p_treeflag & P_TREE_REAPER) == 0) { 176 reap = p->p_reaper; 177 } else { 178 reap = p; 179 rs->rs_flags |= REAPER_STATUS_OWNED; 180 } 181 if (reap == initproc) 182 rs->rs_flags |= REAPER_STATUS_REALINIT; 183 rs->rs_reaper = reap->p_pid; 184 rs->rs_descendants = 0; 185 rs->rs_children = 0; 186 if (!LIST_EMPTY(&reap->p_reaplist)) { 187 first_p = LIST_FIRST(&reap->p_children); 188 if (first_p == NULL) 189 first_p = LIST_FIRST(&reap->p_reaplist); 190 rs->rs_pid = first_p->p_pid; 191 LIST_FOREACH(p2, &reap->p_reaplist, p_reapsibling) { 192 if (proc_realparent(p2) == reap) 193 rs->rs_children++; 194 rs->rs_descendants++; 195 } 196 } else { 197 rs->rs_pid = -1; 198 } 199 return (0); 200 } 201 202 static int 203 reap_getpids(struct thread *td, struct proc *p, void *data) 204 { 205 struct proc *reap, *p2; 206 struct procctl_reaper_pidinfo *pi, *pip; 207 struct procctl_reaper_pids *rp; 208 u_int i, n; 209 int error; 210 211 rp = data; 212 sx_assert(&proctree_lock, SX_LOCKED); 213 PROC_UNLOCK(p); 214 reap = (p->p_treeflag & P_TREE_REAPER) == 0 ? p->p_reaper : p; 215 n = i = 0; 216 error = 0; 217 LIST_FOREACH(p2, &reap->p_reaplist, p_reapsibling) 218 n++; 219 sx_unlock(&proctree_lock); 220 if (rp->rp_count < n) 221 n = rp->rp_count; 222 pi = malloc(n * sizeof(*pi), M_TEMP, M_WAITOK); 223 sx_slock(&proctree_lock); 224 LIST_FOREACH(p2, &reap->p_reaplist, p_reapsibling) { 225 if (i == n) 226 break; 227 pip = &pi[i]; 228 bzero(pip, sizeof(*pip)); 229 pip->pi_pid = p2->p_pid; 230 pip->pi_subtree = p2->p_reapsubtree; 231 pip->pi_flags = REAPER_PIDINFO_VALID; 232 if (proc_realparent(p2) == reap) 233 pip->pi_flags |= REAPER_PIDINFO_CHILD; 234 if ((p2->p_treeflag & P_TREE_REAPER) != 0) 235 pip->pi_flags |= REAPER_PIDINFO_REAPER; 236 i++; 237 } 238 sx_sunlock(&proctree_lock); 239 error = copyout(pi, rp->rp_pids, i * sizeof(*pi)); 240 free(pi, M_TEMP); 241 sx_slock(&proctree_lock); 242 PROC_LOCK(p); 243 return (error); 244 } 245 246 static void 247 reap_kill_proc_relock(struct proc *p, int xlocked) 248 { 249 PROC_UNLOCK(p); 250 if (xlocked) 251 sx_xlock(&proctree_lock); 252 else 253 sx_slock(&proctree_lock); 254 PROC_LOCK(p); 255 } 256 257 static bool 258 reap_kill_proc_locked(struct thread *td, struct proc *p2, 259 ksiginfo_t *ksi, struct procctl_reaper_kill *rk, int *error) 260 { 261 int error1, r, xlocked; 262 bool need_stop; 263 264 PROC_LOCK_ASSERT(p2, MA_OWNED); 265 PROC_ASSERT_HELD(p2); 266 267 error1 = p_cansignal(td, p2, rk->rk_sig); 268 if (error1 != 0) { 269 if (*error == ESRCH) { 270 rk->rk_fpid = p2->p_pid; 271 *error = error1; 272 } 273 return (true); 274 } 275 276 /* 277 * The need_stop indicates if the target process needs to be 278 * suspended before being signalled. This is needed when we 279 * guarantee that all processes in subtree are signalled, 280 * avoiding the race with some process not yet fully linked 281 * into all structures during fork, ignored by iterator, and 282 * then escaping signalling. 283 * 284 * If need_stop is true, then reap_kill_proc() returns true if 285 * the process was successfully stopped and signalled, and 286 * false if stopping failed and the signal was not sent. 287 * 288 * The thread cannot usefully stop itself anyway, and if other 289 * thread of the current process forks while the current 290 * thread signals the whole subtree, it is an application 291 * race. 292 */ 293 need_stop = p2 != td->td_proc && 294 (p2->p_flag & (P_KPROC | P_SYSTEM)) == 0 && 295 (rk->rk_flags & REAPER_KILL_CHILDREN) == 0; 296 297 if (need_stop) { 298 if (P_SHOULDSTOP(p2) == P_STOPPED_SINGLE) 299 return (false); /* retry later */ 300 xlocked = sx_xlocked(&proctree_lock); 301 sx_unlock(&proctree_lock); 302 r = thread_single(p2, SINGLE_ALLPROC); 303 if (r != 0) { 304 reap_kill_proc_relock(p2, xlocked); 305 return (false); 306 } 307 } 308 309 pksignal(p2, rk->rk_sig, ksi); 310 rk->rk_killed++; 311 *error = error1; 312 313 if (need_stop) { 314 reap_kill_proc_relock(p2, xlocked); 315 thread_single_end(p2, SINGLE_ALLPROC); 316 } 317 return (true); 318 } 319 320 static bool 321 reap_kill_proc(struct thread *td, struct proc *p2, ksiginfo_t *ksi, 322 struct procctl_reaper_kill *rk, int *error) 323 { 324 bool res; 325 326 res = true; 327 PROC_LOCK(p2); 328 if ((p2->p_flag & P_WEXIT) == 0) { 329 _PHOLD_LITE(p2); 330 res = reap_kill_proc_locked(td, p2, ksi, rk, error); 331 _PRELE(p2); 332 } 333 PROC_UNLOCK(p2); 334 return (res); 335 } 336 337 struct reap_kill_tracker { 338 struct proc *parent; 339 TAILQ_ENTRY(reap_kill_tracker) link; 340 }; 341 342 TAILQ_HEAD(reap_kill_tracker_head, reap_kill_tracker); 343 344 static void 345 reap_kill_sched(struct reap_kill_tracker_head *tracker, struct proc *p2) 346 { 347 struct reap_kill_tracker *t; 348 349 t = malloc(sizeof(struct reap_kill_tracker), M_TEMP, M_WAITOK); 350 t->parent = p2; 351 TAILQ_INSERT_TAIL(tracker, t, link); 352 } 353 354 static void 355 reap_kill_children(struct thread *td, struct proc *reaper, 356 struct procctl_reaper_kill *rk, ksiginfo_t *ksi, int *error) 357 { 358 struct proc *p2; 359 360 LIST_FOREACH(p2, &reaper->p_children, p_sibling) { 361 (void)reap_kill_proc(td, p2, ksi, rk, error); 362 /* 363 * Do not end the loop on error, signal everything we 364 * can. 365 */ 366 } 367 } 368 369 static bool 370 reap_kill_subtree_once(struct thread *td, struct proc *p, struct proc *reaper, 371 struct procctl_reaper_kill *rk, ksiginfo_t *ksi, int *error, 372 struct unrhdr *pids) 373 { 374 struct reap_kill_tracker_head tracker; 375 struct reap_kill_tracker *t; 376 struct proc *p2; 377 bool res; 378 379 res = false; 380 TAILQ_INIT(&tracker); 381 reap_kill_sched(&tracker, reaper); 382 while ((t = TAILQ_FIRST(&tracker)) != NULL) { 383 MPASS((t->parent->p_treeflag & P_TREE_REAPER) != 0); 384 TAILQ_REMOVE(&tracker, t, link); 385 LIST_FOREACH(p2, &t->parent->p_reaplist, p_reapsibling) { 386 if (t->parent == reaper && 387 (rk->rk_flags & REAPER_KILL_SUBTREE) != 0 && 388 p2->p_reapsubtree != rk->rk_subtree) 389 continue; 390 if ((p2->p_treeflag & P_TREE_REAPER) != 0) 391 reap_kill_sched(&tracker, p2); 392 if (alloc_unr_specific(pids, p2->p_pid) != p2->p_pid) 393 continue; 394 if (!reap_kill_proc(td, p2, ksi, rk, error)) 395 free_unr(pids, p2->p_pid); 396 res = true; 397 } 398 free(t, M_TEMP); 399 } 400 return (res); 401 } 402 403 static void 404 reap_kill_subtree(struct thread *td, struct proc *p, struct proc *reaper, 405 struct procctl_reaper_kill *rk, ksiginfo_t *ksi, int *error) 406 { 407 struct unrhdr pids; 408 409 /* 410 * pids records processes which were already signalled, to 411 * avoid doubling signals to them if iteration needs to be 412 * repeated. 413 */ 414 init_unrhdr(&pids, 1, PID_MAX, UNR_NO_MTX); 415 while (reap_kill_subtree_once(td, p, reaper, rk, ksi, error, &pids)) 416 ; 417 clean_unrhdr(&pids); 418 clear_unrhdr(&pids); 419 } 420 421 static bool 422 reap_kill_sapblk(struct thread *td __unused, void *data) 423 { 424 struct procctl_reaper_kill *rk; 425 426 rk = data; 427 return ((rk->rk_flags & REAPER_KILL_CHILDREN) == 0); 428 } 429 430 static int 431 reap_kill(struct thread *td, struct proc *p, void *data) 432 { 433 struct proc *reaper; 434 ksiginfo_t ksi; 435 struct procctl_reaper_kill *rk; 436 int error; 437 438 rk = data; 439 sx_assert(&proctree_lock, SX_LOCKED); 440 if (IN_CAPABILITY_MODE(td)) 441 return (ECAPMODE); 442 if (rk->rk_sig <= 0 || rk->rk_sig > _SIG_MAXSIG || 443 (rk->rk_flags & ~(REAPER_KILL_CHILDREN | 444 REAPER_KILL_SUBTREE)) != 0 || (rk->rk_flags & 445 (REAPER_KILL_CHILDREN | REAPER_KILL_SUBTREE)) == 446 (REAPER_KILL_CHILDREN | REAPER_KILL_SUBTREE)) 447 return (EINVAL); 448 PROC_UNLOCK(p); 449 reaper = (p->p_treeflag & P_TREE_REAPER) == 0 ? p->p_reaper : p; 450 ksiginfo_init(&ksi); 451 ksi.ksi_signo = rk->rk_sig; 452 ksi.ksi_code = SI_USER; 453 ksi.ksi_pid = td->td_proc->p_pid; 454 ksi.ksi_uid = td->td_ucred->cr_ruid; 455 error = ESRCH; 456 rk->rk_killed = 0; 457 rk->rk_fpid = -1; 458 if ((rk->rk_flags & REAPER_KILL_CHILDREN) != 0) { 459 reap_kill_children(td, reaper, rk, &ksi, &error); 460 } else { 461 reap_kill_subtree(td, p, reaper, rk, &ksi, &error); 462 } 463 PROC_LOCK(p); 464 return (error); 465 } 466 467 static int 468 trace_ctl(struct thread *td, struct proc *p, void *data) 469 { 470 int state; 471 472 PROC_LOCK_ASSERT(p, MA_OWNED); 473 state = *(int *)data; 474 475 /* 476 * Ktrace changes p_traceflag from or to zero under the 477 * process lock, so the test does not need to acquire ktrace 478 * mutex. 479 */ 480 if ((p->p_flag & P_TRACED) != 0 || p->p_traceflag != 0) 481 return (EBUSY); 482 483 switch (state) { 484 case PROC_TRACE_CTL_ENABLE: 485 if (td->td_proc != p) 486 return (EPERM); 487 p->p_flag2 &= ~(P2_NOTRACE | P2_NOTRACE_EXEC); 488 break; 489 case PROC_TRACE_CTL_DISABLE_EXEC: 490 p->p_flag2 |= P2_NOTRACE_EXEC | P2_NOTRACE; 491 break; 492 case PROC_TRACE_CTL_DISABLE: 493 if ((p->p_flag2 & P2_NOTRACE_EXEC) != 0) { 494 KASSERT((p->p_flag2 & P2_NOTRACE) != 0, 495 ("dandling P2_NOTRACE_EXEC")); 496 if (td->td_proc != p) 497 return (EPERM); 498 p->p_flag2 &= ~P2_NOTRACE_EXEC; 499 } else { 500 p->p_flag2 |= P2_NOTRACE; 501 } 502 break; 503 default: 504 return (EINVAL); 505 } 506 return (0); 507 } 508 509 static int 510 trace_status(struct thread *td, struct proc *p, void *data) 511 { 512 int *status; 513 514 status = data; 515 if ((p->p_flag2 & P2_NOTRACE) != 0) { 516 KASSERT((p->p_flag & P_TRACED) == 0, 517 ("%d traced but tracing disabled", p->p_pid)); 518 *status = -1; 519 } else if ((p->p_flag & P_TRACED) != 0) { 520 *status = p->p_pptr->p_pid; 521 } else { 522 *status = 0; 523 } 524 return (0); 525 } 526 527 static int 528 trapcap_ctl(struct thread *td, struct proc *p, void *data) 529 { 530 int state; 531 532 PROC_LOCK_ASSERT(p, MA_OWNED); 533 state = *(int *)data; 534 535 switch (state) { 536 case PROC_TRAPCAP_CTL_ENABLE: 537 p->p_flag2 |= P2_TRAPCAP; 538 break; 539 case PROC_TRAPCAP_CTL_DISABLE: 540 p->p_flag2 &= ~P2_TRAPCAP; 541 break; 542 default: 543 return (EINVAL); 544 } 545 return (0); 546 } 547 548 static int 549 trapcap_status(struct thread *td, struct proc *p, void *data) 550 { 551 int *status; 552 553 status = data; 554 *status = (p->p_flag2 & P2_TRAPCAP) != 0 ? PROC_TRAPCAP_CTL_ENABLE : 555 PROC_TRAPCAP_CTL_DISABLE; 556 return (0); 557 } 558 559 static int 560 no_new_privs_ctl(struct thread *td, struct proc *p, void *data) 561 { 562 int state; 563 564 PROC_LOCK_ASSERT(p, MA_OWNED); 565 state = *(int *)data; 566 567 if (state != PROC_NO_NEW_PRIVS_ENABLE) 568 return (EINVAL); 569 p->p_flag2 |= P2_NO_NEW_PRIVS; 570 return (0); 571 } 572 573 static int 574 no_new_privs_status(struct thread *td, struct proc *p, void *data) 575 { 576 577 *(int *)data = (p->p_flag2 & P2_NO_NEW_PRIVS) != 0 ? 578 PROC_NO_NEW_PRIVS_ENABLE : PROC_NO_NEW_PRIVS_DISABLE; 579 return (0); 580 } 581 582 static int 583 protmax_ctl(struct thread *td, struct proc *p, void *data) 584 { 585 int state; 586 587 PROC_LOCK_ASSERT(p, MA_OWNED); 588 state = *(int *)data; 589 590 switch (state) { 591 case PROC_PROTMAX_FORCE_ENABLE: 592 p->p_flag2 &= ~P2_PROTMAX_DISABLE; 593 p->p_flag2 |= P2_PROTMAX_ENABLE; 594 break; 595 case PROC_PROTMAX_FORCE_DISABLE: 596 p->p_flag2 |= P2_PROTMAX_DISABLE; 597 p->p_flag2 &= ~P2_PROTMAX_ENABLE; 598 break; 599 case PROC_PROTMAX_NOFORCE: 600 p->p_flag2 &= ~(P2_PROTMAX_ENABLE | P2_PROTMAX_DISABLE); 601 break; 602 default: 603 return (EINVAL); 604 } 605 return (0); 606 } 607 608 static int 609 protmax_status(struct thread *td, struct proc *p, void *data) 610 { 611 int d; 612 613 switch (p->p_flag2 & (P2_PROTMAX_ENABLE | P2_PROTMAX_DISABLE)) { 614 case 0: 615 d = PROC_PROTMAX_NOFORCE; 616 break; 617 case P2_PROTMAX_ENABLE: 618 d = PROC_PROTMAX_FORCE_ENABLE; 619 break; 620 case P2_PROTMAX_DISABLE: 621 d = PROC_PROTMAX_FORCE_DISABLE; 622 break; 623 } 624 if (kern_mmap_maxprot(p, PROT_READ) == PROT_READ) 625 d |= PROC_PROTMAX_ACTIVE; 626 *(int *)data = d; 627 return (0); 628 } 629 630 static int 631 aslr_ctl(struct thread *td, struct proc *p, void *data) 632 { 633 int state; 634 635 PROC_LOCK_ASSERT(p, MA_OWNED); 636 state = *(int *)data; 637 638 switch (state) { 639 case PROC_ASLR_FORCE_ENABLE: 640 p->p_flag2 &= ~P2_ASLR_DISABLE; 641 p->p_flag2 |= P2_ASLR_ENABLE; 642 break; 643 case PROC_ASLR_FORCE_DISABLE: 644 p->p_flag2 |= P2_ASLR_DISABLE; 645 p->p_flag2 &= ~P2_ASLR_ENABLE; 646 break; 647 case PROC_ASLR_NOFORCE: 648 p->p_flag2 &= ~(P2_ASLR_ENABLE | P2_ASLR_DISABLE); 649 break; 650 default: 651 return (EINVAL); 652 } 653 return (0); 654 } 655 656 static int 657 aslr_status(struct thread *td, struct proc *p, void *data) 658 { 659 struct vmspace *vm; 660 int d; 661 662 switch (p->p_flag2 & (P2_ASLR_ENABLE | P2_ASLR_DISABLE)) { 663 case 0: 664 d = PROC_ASLR_NOFORCE; 665 break; 666 case P2_ASLR_ENABLE: 667 d = PROC_ASLR_FORCE_ENABLE; 668 break; 669 case P2_ASLR_DISABLE: 670 d = PROC_ASLR_FORCE_DISABLE; 671 break; 672 } 673 if ((p->p_flag & P_WEXIT) == 0) { 674 _PHOLD(p); 675 PROC_UNLOCK(p); 676 vm = vmspace_acquire_ref(p); 677 if (vm != NULL) { 678 if ((vm->vm_map.flags & MAP_ASLR) != 0) 679 d |= PROC_ASLR_ACTIVE; 680 vmspace_free(vm); 681 } 682 PROC_LOCK(p); 683 _PRELE(p); 684 } 685 *(int *)data = d; 686 return (0); 687 } 688 689 static int 690 stackgap_ctl(struct thread *td, struct proc *p, void *data) 691 { 692 int state; 693 694 PROC_LOCK_ASSERT(p, MA_OWNED); 695 state = *(int *)data; 696 697 if ((state & ~(PROC_STACKGAP_ENABLE | PROC_STACKGAP_DISABLE | 698 PROC_STACKGAP_ENABLE_EXEC | PROC_STACKGAP_DISABLE_EXEC)) != 0) 699 return (EINVAL); 700 switch (state & (PROC_STACKGAP_ENABLE | PROC_STACKGAP_DISABLE)) { 701 case PROC_STACKGAP_ENABLE: 702 if ((p->p_flag2 & P2_STKGAP_DISABLE) != 0) 703 return (EINVAL); 704 break; 705 case PROC_STACKGAP_DISABLE: 706 p->p_flag2 |= P2_STKGAP_DISABLE; 707 break; 708 case 0: 709 break; 710 default: 711 return (EINVAL); 712 } 713 switch (state & (PROC_STACKGAP_ENABLE_EXEC | 714 PROC_STACKGAP_DISABLE_EXEC)) { 715 case PROC_STACKGAP_ENABLE_EXEC: 716 p->p_flag2 &= ~P2_STKGAP_DISABLE_EXEC; 717 break; 718 case PROC_STACKGAP_DISABLE_EXEC: 719 p->p_flag2 |= P2_STKGAP_DISABLE_EXEC; 720 break; 721 case 0: 722 break; 723 default: 724 return (EINVAL); 725 } 726 return (0); 727 } 728 729 static int 730 stackgap_status(struct thread *td, struct proc *p, void *data) 731 { 732 int d; 733 734 PROC_LOCK_ASSERT(p, MA_OWNED); 735 736 d = (p->p_flag2 & P2_STKGAP_DISABLE) != 0 ? PROC_STACKGAP_DISABLE : 737 PROC_STACKGAP_ENABLE; 738 d |= (p->p_flag2 & P2_STKGAP_DISABLE_EXEC) != 0 ? 739 PROC_STACKGAP_DISABLE_EXEC : PROC_STACKGAP_ENABLE_EXEC; 740 *(int *)data = d; 741 return (0); 742 } 743 744 static int 745 wxmap_ctl(struct thread *td, struct proc *p, void *data) 746 { 747 struct vmspace *vm; 748 vm_map_t map; 749 int state; 750 751 PROC_LOCK_ASSERT(p, MA_OWNED); 752 if ((p->p_flag & P_WEXIT) != 0) 753 return (ESRCH); 754 state = *(int *)data; 755 756 switch (state) { 757 case PROC_WX_MAPPINGS_PERMIT: 758 p->p_flag2 |= P2_WXORX_DISABLE; 759 _PHOLD(p); 760 PROC_UNLOCK(p); 761 vm = vmspace_acquire_ref(p); 762 if (vm != NULL) { 763 map = &vm->vm_map; 764 vm_map_lock(map); 765 map->flags &= ~MAP_WXORX; 766 vm_map_unlock(map); 767 vmspace_free(vm); 768 } 769 PROC_LOCK(p); 770 _PRELE(p); 771 break; 772 case PROC_WX_MAPPINGS_DISALLOW_EXEC: 773 p->p_flag2 |= P2_WXORX_ENABLE_EXEC; 774 break; 775 default: 776 return (EINVAL); 777 } 778 779 return (0); 780 } 781 782 static int 783 wxmap_status(struct thread *td, struct proc *p, void *data) 784 { 785 struct vmspace *vm; 786 int d; 787 788 PROC_LOCK_ASSERT(p, MA_OWNED); 789 if ((p->p_flag & P_WEXIT) != 0) 790 return (ESRCH); 791 792 d = 0; 793 if ((p->p_flag2 & P2_WXORX_DISABLE) != 0) 794 d |= PROC_WX_MAPPINGS_PERMIT; 795 if ((p->p_flag2 & P2_WXORX_ENABLE_EXEC) != 0) 796 d |= PROC_WX_MAPPINGS_DISALLOW_EXEC; 797 _PHOLD(p); 798 PROC_UNLOCK(p); 799 vm = vmspace_acquire_ref(p); 800 if (vm != NULL) { 801 if ((vm->vm_map.flags & MAP_WXORX) != 0) 802 d |= PROC_WXORX_ENFORCE; 803 vmspace_free(vm); 804 } 805 PROC_LOCK(p); 806 _PRELE(p); 807 *(int *)data = d; 808 return (0); 809 } 810 811 static int 812 pdeathsig_ctl(struct thread *td, struct proc *p, void *data) 813 { 814 int signum; 815 816 signum = *(int *)data; 817 if (p != td->td_proc || (signum != 0 && !_SIG_VALID(signum))) 818 return (EINVAL); 819 p->p_pdeathsig = signum; 820 return (0); 821 } 822 823 static int 824 pdeathsig_status(struct thread *td, struct proc *p, void *data) 825 { 826 if (p != td->td_proc) 827 return (EINVAL); 828 *(int *)data = p->p_pdeathsig; 829 return (0); 830 } 831 832 enum { 833 PCTL_SLOCKED, 834 PCTL_XLOCKED, 835 PCTL_UNLOCKED, 836 }; 837 838 struct procctl_cmd_info { 839 int lock_tree; 840 bool one_proc : 1; 841 bool esrch_is_einval : 1; 842 bool copyout_on_error : 1; 843 bool no_nonnull_data : 1; 844 bool need_candebug : 1; 845 int copyin_sz; 846 int copyout_sz; 847 int (*exec)(struct thread *, struct proc *, void *); 848 bool (*sapblk)(struct thread *, void *); 849 }; 850 static const struct procctl_cmd_info procctl_cmds_info[] = { 851 [PROC_SPROTECT] = 852 { .lock_tree = PCTL_SLOCKED, .one_proc = false, 853 .esrch_is_einval = false, .no_nonnull_data = false, 854 .need_candebug = false, 855 .copyin_sz = sizeof(int), .copyout_sz = 0, 856 .exec = protect_set, .copyout_on_error = false, }, 857 [PROC_REAP_ACQUIRE] = 858 { .lock_tree = PCTL_XLOCKED, .one_proc = true, 859 .esrch_is_einval = false, .no_nonnull_data = true, 860 .need_candebug = false, 861 .copyin_sz = 0, .copyout_sz = 0, 862 .exec = reap_acquire, .copyout_on_error = false, }, 863 [PROC_REAP_RELEASE] = 864 { .lock_tree = PCTL_XLOCKED, .one_proc = true, 865 .esrch_is_einval = false, .no_nonnull_data = true, 866 .need_candebug = false, 867 .copyin_sz = 0, .copyout_sz = 0, 868 .exec = reap_release, .copyout_on_error = false, }, 869 [PROC_REAP_STATUS] = 870 { .lock_tree = PCTL_SLOCKED, .one_proc = true, 871 .esrch_is_einval = false, .no_nonnull_data = false, 872 .need_candebug = false, 873 .copyin_sz = 0, 874 .copyout_sz = sizeof(struct procctl_reaper_status), 875 .exec = reap_status, .copyout_on_error = false, }, 876 [PROC_REAP_GETPIDS] = 877 { .lock_tree = PCTL_SLOCKED, .one_proc = true, 878 .esrch_is_einval = false, .no_nonnull_data = false, 879 .need_candebug = false, 880 .copyin_sz = sizeof(struct procctl_reaper_pids), 881 .copyout_sz = 0, 882 .exec = reap_getpids, .copyout_on_error = false, }, 883 [PROC_REAP_KILL] = 884 { .lock_tree = PCTL_SLOCKED, .one_proc = true, 885 .esrch_is_einval = false, .no_nonnull_data = false, 886 .need_candebug = false, 887 .copyin_sz = sizeof(struct procctl_reaper_kill), 888 .copyout_sz = sizeof(struct procctl_reaper_kill), 889 .exec = reap_kill, .copyout_on_error = true, 890 .sapblk = reap_kill_sapblk, }, 891 [PROC_TRACE_CTL] = 892 { .lock_tree = PCTL_SLOCKED, .one_proc = false, 893 .esrch_is_einval = false, .no_nonnull_data = false, 894 .need_candebug = true, 895 .copyin_sz = sizeof(int), .copyout_sz = 0, 896 .exec = trace_ctl, .copyout_on_error = false, }, 897 [PROC_TRACE_STATUS] = 898 { .lock_tree = PCTL_UNLOCKED, .one_proc = true, 899 .esrch_is_einval = false, .no_nonnull_data = false, 900 .need_candebug = false, 901 .copyin_sz = 0, .copyout_sz = sizeof(int), 902 .exec = trace_status, .copyout_on_error = false, }, 903 [PROC_TRAPCAP_CTL] = 904 { .lock_tree = PCTL_SLOCKED, .one_proc = false, 905 .esrch_is_einval = false, .no_nonnull_data = false, 906 .need_candebug = true, 907 .copyin_sz = sizeof(int), .copyout_sz = 0, 908 .exec = trapcap_ctl, .copyout_on_error = false, }, 909 [PROC_TRAPCAP_STATUS] = 910 { .lock_tree = PCTL_UNLOCKED, .one_proc = true, 911 .esrch_is_einval = false, .no_nonnull_data = false, 912 .need_candebug = false, 913 .copyin_sz = 0, .copyout_sz = sizeof(int), 914 .exec = trapcap_status, .copyout_on_error = false, }, 915 [PROC_PDEATHSIG_CTL] = 916 { .lock_tree = PCTL_UNLOCKED, .one_proc = true, 917 .esrch_is_einval = true, .no_nonnull_data = false, 918 .need_candebug = false, 919 .copyin_sz = sizeof(int), .copyout_sz = 0, 920 .exec = pdeathsig_ctl, .copyout_on_error = false, }, 921 [PROC_PDEATHSIG_STATUS] = 922 { .lock_tree = PCTL_UNLOCKED, .one_proc = true, 923 .esrch_is_einval = true, .no_nonnull_data = false, 924 .need_candebug = false, 925 .copyin_sz = 0, .copyout_sz = sizeof(int), 926 .exec = pdeathsig_status, .copyout_on_error = false, }, 927 [PROC_ASLR_CTL] = 928 { .lock_tree = PCTL_UNLOCKED, .one_proc = true, 929 .esrch_is_einval = false, .no_nonnull_data = false, 930 .need_candebug = true, 931 .copyin_sz = sizeof(int), .copyout_sz = 0, 932 .exec = aslr_ctl, .copyout_on_error = false, }, 933 [PROC_ASLR_STATUS] = 934 { .lock_tree = PCTL_UNLOCKED, .one_proc = true, 935 .esrch_is_einval = false, .no_nonnull_data = false, 936 .need_candebug = false, 937 .copyin_sz = 0, .copyout_sz = sizeof(int), 938 .exec = aslr_status, .copyout_on_error = false, }, 939 [PROC_PROTMAX_CTL] = 940 { .lock_tree = PCTL_UNLOCKED, .one_proc = true, 941 .esrch_is_einval = false, .no_nonnull_data = false, 942 .need_candebug = true, 943 .copyin_sz = sizeof(int), .copyout_sz = 0, 944 .exec = protmax_ctl, .copyout_on_error = false, }, 945 [PROC_PROTMAX_STATUS] = 946 { .lock_tree = PCTL_UNLOCKED, .one_proc = true, 947 .esrch_is_einval = false, .no_nonnull_data = false, 948 .need_candebug = false, 949 .copyin_sz = 0, .copyout_sz = sizeof(int), 950 .exec = protmax_status, .copyout_on_error = false, }, 951 [PROC_STACKGAP_CTL] = 952 { .lock_tree = PCTL_UNLOCKED, .one_proc = true, 953 .esrch_is_einval = false, .no_nonnull_data = false, 954 .need_candebug = true, 955 .copyin_sz = sizeof(int), .copyout_sz = 0, 956 .exec = stackgap_ctl, .copyout_on_error = false, }, 957 [PROC_STACKGAP_STATUS] = 958 { .lock_tree = PCTL_UNLOCKED, .one_proc = true, 959 .esrch_is_einval = false, .no_nonnull_data = false, 960 .need_candebug = false, 961 .copyin_sz = 0, .copyout_sz = sizeof(int), 962 .exec = stackgap_status, .copyout_on_error = false, }, 963 [PROC_NO_NEW_PRIVS_CTL] = 964 { .lock_tree = PCTL_SLOCKED, .one_proc = true, 965 .esrch_is_einval = false, .no_nonnull_data = false, 966 .need_candebug = true, 967 .copyin_sz = sizeof(int), .copyout_sz = 0, 968 .exec = no_new_privs_ctl, .copyout_on_error = false, }, 969 [PROC_NO_NEW_PRIVS_STATUS] = 970 { .lock_tree = PCTL_UNLOCKED, .one_proc = true, 971 .esrch_is_einval = false, .no_nonnull_data = false, 972 .need_candebug = false, 973 .copyin_sz = 0, .copyout_sz = sizeof(int), 974 .exec = no_new_privs_status, .copyout_on_error = false, }, 975 [PROC_WXMAP_CTL] = 976 { .lock_tree = PCTL_UNLOCKED, .one_proc = true, 977 .esrch_is_einval = false, .no_nonnull_data = false, 978 .need_candebug = true, 979 .copyin_sz = sizeof(int), .copyout_sz = 0, 980 .exec = wxmap_ctl, .copyout_on_error = false, }, 981 [PROC_WXMAP_STATUS] = 982 { .lock_tree = PCTL_UNLOCKED, .one_proc = true, 983 .esrch_is_einval = false, .no_nonnull_data = false, 984 .need_candebug = false, 985 .copyin_sz = 0, .copyout_sz = sizeof(int), 986 .exec = wxmap_status, .copyout_on_error = false, }, 987 }; 988 989 int 990 sys_procctl(struct thread *td, struct procctl_args *uap) 991 { 992 union { 993 struct procctl_reaper_status rs; 994 struct procctl_reaper_pids rp; 995 struct procctl_reaper_kill rk; 996 int flags; 997 } x; 998 const struct procctl_cmd_info *cmd_info; 999 int error, error1; 1000 1001 if (uap->com >= PROC_PROCCTL_MD_MIN) 1002 return (cpu_procctl(td, uap->idtype, uap->id, 1003 uap->com, uap->data)); 1004 if (uap->com == 0 || uap->com >= nitems(procctl_cmds_info)) 1005 return (EINVAL); 1006 cmd_info = &procctl_cmds_info[uap->com]; 1007 bzero(&x, sizeof(x)); 1008 1009 if (cmd_info->copyin_sz > 0) { 1010 error = copyin(uap->data, &x, cmd_info->copyin_sz); 1011 if (error != 0) 1012 return (error); 1013 } else if (cmd_info->no_nonnull_data && uap->data != NULL) { 1014 return (EINVAL); 1015 } 1016 1017 error = kern_procctl(td, uap->idtype, uap->id, uap->com, &x); 1018 1019 if (cmd_info->copyout_sz > 0 && (error == 0 || 1020 cmd_info->copyout_on_error)) { 1021 error1 = copyout(&x, uap->data, cmd_info->copyout_sz); 1022 if (error == 0) 1023 error = error1; 1024 } 1025 return (error); 1026 } 1027 1028 static int 1029 kern_procctl_single(struct thread *td, struct proc *p, int com, void *data) 1030 { 1031 1032 PROC_LOCK_ASSERT(p, MA_OWNED); 1033 return (procctl_cmds_info[com].exec(td, p, data)); 1034 } 1035 1036 int 1037 kern_procctl(struct thread *td, idtype_t idtype, id_t id, int com, void *data) 1038 { 1039 struct pgrp *pg; 1040 struct proc *p; 1041 const struct procctl_cmd_info *cmd_info; 1042 int error, first_error, ok; 1043 bool sapblk; 1044 1045 MPASS(com > 0 && com < nitems(procctl_cmds_info)); 1046 cmd_info = &procctl_cmds_info[com]; 1047 if (idtype != P_PID && cmd_info->one_proc) 1048 return (EINVAL); 1049 1050 sapblk = false; 1051 if (cmd_info->sapblk != NULL) { 1052 sapblk = cmd_info->sapblk(td, data); 1053 if (sapblk) 1054 stop_all_proc_block(); 1055 } 1056 1057 switch (cmd_info->lock_tree) { 1058 case PCTL_XLOCKED: 1059 sx_xlock(&proctree_lock); 1060 break; 1061 case PCTL_SLOCKED: 1062 sx_slock(&proctree_lock); 1063 break; 1064 default: 1065 break; 1066 } 1067 1068 switch (idtype) { 1069 case P_PID: 1070 if (id == 0) { 1071 p = td->td_proc; 1072 error = 0; 1073 PROC_LOCK(p); 1074 } else { 1075 p = pfind(id); 1076 if (p == NULL) { 1077 error = cmd_info->esrch_is_einval ? 1078 EINVAL : ESRCH; 1079 break; 1080 } 1081 error = cmd_info->need_candebug ? p_candebug(td, p) : 1082 p_cansee(td, p); 1083 } 1084 if (error == 0) 1085 error = kern_procctl_single(td, p, com, data); 1086 PROC_UNLOCK(p); 1087 break; 1088 case P_PGID: 1089 /* 1090 * Attempt to apply the operation to all members of the 1091 * group. Ignore processes in the group that can't be 1092 * seen. Ignore errors so long as at least one process is 1093 * able to complete the request successfully. 1094 */ 1095 pg = pgfind(id); 1096 if (pg == NULL) { 1097 error = ESRCH; 1098 break; 1099 } 1100 PGRP_UNLOCK(pg); 1101 ok = 0; 1102 first_error = 0; 1103 LIST_FOREACH(p, &pg->pg_members, p_pglist) { 1104 PROC_LOCK(p); 1105 if (p->p_state == PRS_NEW || 1106 p->p_state == PRS_ZOMBIE || 1107 (cmd_info->need_candebug ? p_candebug(td, p) : 1108 p_cansee(td, p)) != 0) { 1109 PROC_UNLOCK(p); 1110 continue; 1111 } 1112 error = kern_procctl_single(td, p, com, data); 1113 PROC_UNLOCK(p); 1114 if (error == 0) 1115 ok = 1; 1116 else if (first_error == 0) 1117 first_error = error; 1118 } 1119 if (ok) 1120 error = 0; 1121 else if (first_error != 0) 1122 error = first_error; 1123 else 1124 /* 1125 * Was not able to see any processes in the 1126 * process group. 1127 */ 1128 error = ESRCH; 1129 break; 1130 default: 1131 error = EINVAL; 1132 break; 1133 } 1134 1135 switch (cmd_info->lock_tree) { 1136 case PCTL_XLOCKED: 1137 sx_xunlock(&proctree_lock); 1138 break; 1139 case PCTL_SLOCKED: 1140 sx_sunlock(&proctree_lock); 1141 break; 1142 default: 1143 break; 1144 } 1145 if (sapblk) 1146 stop_all_proc_unblock(); 1147 return (error); 1148 } 1149