1 /*- 2 * Copyright (c) 1982, 1986, 1989, 1990, 1991, 1993 3 * The Regents of the University of California. 4 * (c) UNIX System Laboratories, Inc. 5 * Copyright (c) 2000-2001 Robert N. M. Watson. 6 * All rights reserved. 7 * 8 * All or some portions of this file are derived from material licensed 9 * to the University of California by American Telephone and Telegraph 10 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 11 * the permission of UNIX System Laboratories, Inc. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 2. Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * 4. Neither the name of the University nor the names of its contributors 22 * may be used to endorse or promote products derived from this software 23 * without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 * 37 * @(#)kern_prot.c 8.6 (Berkeley) 1/21/94 38 */ 39 40 /* 41 * System calls related to processes and protection 42 */ 43 44 #include <sys/cdefs.h> 45 __FBSDID("$FreeBSD$"); 46 47 #include "opt_compat.h" 48 #include "opt_inet.h" 49 #include "opt_inet6.h" 50 51 #include <sys/param.h> 52 #include <sys/systm.h> 53 #include <sys/acct.h> 54 #include <sys/kdb.h> 55 #include <sys/kernel.h> 56 #include <sys/lock.h> 57 #include <sys/loginclass.h> 58 #include <sys/malloc.h> 59 #include <sys/mutex.h> 60 #include <sys/refcount.h> 61 #include <sys/sx.h> 62 #include <sys/priv.h> 63 #include <sys/proc.h> 64 #include <sys/sysproto.h> 65 #include <sys/jail.h> 66 #include <sys/pioctl.h> 67 #include <sys/racct.h> 68 #include <sys/resourcevar.h> 69 #include <sys/socket.h> 70 #include <sys/socketvar.h> 71 #include <sys/syscallsubr.h> 72 #include <sys/sysctl.h> 73 74 #ifdef REGRESSION 75 FEATURE(regression, 76 "Kernel support for interfaces necessary for regression testing (SECURITY RISK!)"); 77 #endif 78 79 #if defined(INET) || defined(INET6) 80 #include <netinet/in.h> 81 #include <netinet/in_pcb.h> 82 #endif 83 84 #include <security/audit/audit.h> 85 #include <security/mac/mac_framework.h> 86 87 static MALLOC_DEFINE(M_CRED, "cred", "credentials"); 88 89 SYSCTL_NODE(_security, OID_AUTO, bsd, CTLFLAG_RW, 0, "BSD security policy"); 90 91 static void crextend(struct ucred *cr, int n); 92 static void crsetgroups_locked(struct ucred *cr, int ngrp, 93 gid_t *groups); 94 95 #ifndef _SYS_SYSPROTO_H_ 96 struct getpid_args { 97 int dummy; 98 }; 99 #endif 100 /* ARGSUSED */ 101 int 102 sys_getpid(struct thread *td, struct getpid_args *uap) 103 { 104 struct proc *p = td->td_proc; 105 106 td->td_retval[0] = p->p_pid; 107 #if defined(COMPAT_43) 108 td->td_retval[1] = kern_getppid(td); 109 #endif 110 return (0); 111 } 112 113 #ifndef _SYS_SYSPROTO_H_ 114 struct getppid_args { 115 int dummy; 116 }; 117 #endif 118 /* ARGSUSED */ 119 int 120 sys_getppid(struct thread *td, struct getppid_args *uap) 121 { 122 123 td->td_retval[0] = kern_getppid(td); 124 return (0); 125 } 126 127 int 128 kern_getppid(struct thread *td) 129 { 130 struct proc *p = td->td_proc; 131 struct proc *pp; 132 int ppid; 133 134 PROC_LOCK(p); 135 if (!(p->p_flag & P_TRACED)) { 136 ppid = p->p_pptr->p_pid; 137 PROC_UNLOCK(p); 138 } else { 139 PROC_UNLOCK(p); 140 sx_slock(&proctree_lock); 141 pp = proc_realparent(p); 142 ppid = pp->p_pid; 143 sx_sunlock(&proctree_lock); 144 } 145 146 return (ppid); 147 } 148 149 /* 150 * Get process group ID; note that POSIX getpgrp takes no parameter. 151 */ 152 #ifndef _SYS_SYSPROTO_H_ 153 struct getpgrp_args { 154 int dummy; 155 }; 156 #endif 157 int 158 sys_getpgrp(struct thread *td, struct getpgrp_args *uap) 159 { 160 struct proc *p = td->td_proc; 161 162 PROC_LOCK(p); 163 td->td_retval[0] = p->p_pgrp->pg_id; 164 PROC_UNLOCK(p); 165 return (0); 166 } 167 168 /* Get an arbitary pid's process group id */ 169 #ifndef _SYS_SYSPROTO_H_ 170 struct getpgid_args { 171 pid_t pid; 172 }; 173 #endif 174 int 175 sys_getpgid(struct thread *td, struct getpgid_args *uap) 176 { 177 struct proc *p; 178 int error; 179 180 if (uap->pid == 0) { 181 p = td->td_proc; 182 PROC_LOCK(p); 183 } else { 184 p = pfind(uap->pid); 185 if (p == NULL) 186 return (ESRCH); 187 error = p_cansee(td, p); 188 if (error) { 189 PROC_UNLOCK(p); 190 return (error); 191 } 192 } 193 td->td_retval[0] = p->p_pgrp->pg_id; 194 PROC_UNLOCK(p); 195 return (0); 196 } 197 198 /* 199 * Get an arbitary pid's session id. 200 */ 201 #ifndef _SYS_SYSPROTO_H_ 202 struct getsid_args { 203 pid_t pid; 204 }; 205 #endif 206 int 207 sys_getsid(struct thread *td, struct getsid_args *uap) 208 { 209 struct proc *p; 210 int error; 211 212 if (uap->pid == 0) { 213 p = td->td_proc; 214 PROC_LOCK(p); 215 } else { 216 p = pfind(uap->pid); 217 if (p == NULL) 218 return (ESRCH); 219 error = p_cansee(td, p); 220 if (error) { 221 PROC_UNLOCK(p); 222 return (error); 223 } 224 } 225 td->td_retval[0] = p->p_session->s_sid; 226 PROC_UNLOCK(p); 227 return (0); 228 } 229 230 #ifndef _SYS_SYSPROTO_H_ 231 struct getuid_args { 232 int dummy; 233 }; 234 #endif 235 /* ARGSUSED */ 236 int 237 sys_getuid(struct thread *td, struct getuid_args *uap) 238 { 239 240 td->td_retval[0] = td->td_ucred->cr_ruid; 241 #if defined(COMPAT_43) 242 td->td_retval[1] = td->td_ucred->cr_uid; 243 #endif 244 return (0); 245 } 246 247 #ifndef _SYS_SYSPROTO_H_ 248 struct geteuid_args { 249 int dummy; 250 }; 251 #endif 252 /* ARGSUSED */ 253 int 254 sys_geteuid(struct thread *td, struct geteuid_args *uap) 255 { 256 257 td->td_retval[0] = td->td_ucred->cr_uid; 258 return (0); 259 } 260 261 #ifndef _SYS_SYSPROTO_H_ 262 struct getgid_args { 263 int dummy; 264 }; 265 #endif 266 /* ARGSUSED */ 267 int 268 sys_getgid(struct thread *td, struct getgid_args *uap) 269 { 270 271 td->td_retval[0] = td->td_ucred->cr_rgid; 272 #if defined(COMPAT_43) 273 td->td_retval[1] = td->td_ucred->cr_groups[0]; 274 #endif 275 return (0); 276 } 277 278 /* 279 * Get effective group ID. The "egid" is groups[0], and could be obtained 280 * via getgroups. This syscall exists because it is somewhat painful to do 281 * correctly in a library function. 282 */ 283 #ifndef _SYS_SYSPROTO_H_ 284 struct getegid_args { 285 int dummy; 286 }; 287 #endif 288 /* ARGSUSED */ 289 int 290 sys_getegid(struct thread *td, struct getegid_args *uap) 291 { 292 293 td->td_retval[0] = td->td_ucred->cr_groups[0]; 294 return (0); 295 } 296 297 #ifndef _SYS_SYSPROTO_H_ 298 struct getgroups_args { 299 u_int gidsetsize; 300 gid_t *gidset; 301 }; 302 #endif 303 int 304 sys_getgroups(struct thread *td, register struct getgroups_args *uap) 305 { 306 struct ucred *cred; 307 u_int ngrp; 308 int error; 309 310 cred = td->td_ucred; 311 ngrp = cred->cr_ngroups; 312 313 if (uap->gidsetsize == 0) { 314 error = 0; 315 goto out; 316 } 317 if (uap->gidsetsize < ngrp) 318 return (EINVAL); 319 320 error = copyout(cred->cr_groups, uap->gidset, ngrp * sizeof(gid_t)); 321 out: 322 td->td_retval[0] = ngrp; 323 return (error); 324 } 325 326 #ifndef _SYS_SYSPROTO_H_ 327 struct setsid_args { 328 int dummy; 329 }; 330 #endif 331 /* ARGSUSED */ 332 int 333 sys_setsid(register struct thread *td, struct setsid_args *uap) 334 { 335 struct pgrp *pgrp; 336 int error; 337 struct proc *p = td->td_proc; 338 struct pgrp *newpgrp; 339 struct session *newsess; 340 341 error = 0; 342 pgrp = NULL; 343 344 newpgrp = malloc(sizeof(struct pgrp), M_PGRP, M_WAITOK | M_ZERO); 345 newsess = malloc(sizeof(struct session), M_SESSION, M_WAITOK | M_ZERO); 346 347 sx_xlock(&proctree_lock); 348 349 if (p->p_pgid == p->p_pid || (pgrp = pgfind(p->p_pid)) != NULL) { 350 if (pgrp != NULL) 351 PGRP_UNLOCK(pgrp); 352 error = EPERM; 353 } else { 354 (void)enterpgrp(p, p->p_pid, newpgrp, newsess); 355 td->td_retval[0] = p->p_pid; 356 newpgrp = NULL; 357 newsess = NULL; 358 } 359 360 sx_xunlock(&proctree_lock); 361 362 if (newpgrp != NULL) 363 free(newpgrp, M_PGRP); 364 if (newsess != NULL) 365 free(newsess, M_SESSION); 366 367 return (error); 368 } 369 370 /* 371 * set process group (setpgid/old setpgrp) 372 * 373 * caller does setpgid(targpid, targpgid) 374 * 375 * pid must be caller or child of caller (ESRCH) 376 * if a child 377 * pid must be in same session (EPERM) 378 * pid can't have done an exec (EACCES) 379 * if pgid != pid 380 * there must exist some pid in same session having pgid (EPERM) 381 * pid must not be session leader (EPERM) 382 */ 383 #ifndef _SYS_SYSPROTO_H_ 384 struct setpgid_args { 385 int pid; /* target process id */ 386 int pgid; /* target pgrp id */ 387 }; 388 #endif 389 /* ARGSUSED */ 390 int 391 sys_setpgid(struct thread *td, register struct setpgid_args *uap) 392 { 393 struct proc *curp = td->td_proc; 394 register struct proc *targp; /* target process */ 395 register struct pgrp *pgrp; /* target pgrp */ 396 int error; 397 struct pgrp *newpgrp; 398 399 if (uap->pgid < 0) 400 return (EINVAL); 401 402 error = 0; 403 404 newpgrp = malloc(sizeof(struct pgrp), M_PGRP, M_WAITOK | M_ZERO); 405 406 sx_xlock(&proctree_lock); 407 if (uap->pid != 0 && uap->pid != curp->p_pid) { 408 if ((targp = pfind(uap->pid)) == NULL) { 409 error = ESRCH; 410 goto done; 411 } 412 if (!inferior(targp)) { 413 PROC_UNLOCK(targp); 414 error = ESRCH; 415 goto done; 416 } 417 if ((error = p_cansee(td, targp))) { 418 PROC_UNLOCK(targp); 419 goto done; 420 } 421 if (targp->p_pgrp == NULL || 422 targp->p_session != curp->p_session) { 423 PROC_UNLOCK(targp); 424 error = EPERM; 425 goto done; 426 } 427 if (targp->p_flag & P_EXEC) { 428 PROC_UNLOCK(targp); 429 error = EACCES; 430 goto done; 431 } 432 PROC_UNLOCK(targp); 433 } else 434 targp = curp; 435 if (SESS_LEADER(targp)) { 436 error = EPERM; 437 goto done; 438 } 439 if (uap->pgid == 0) 440 uap->pgid = targp->p_pid; 441 if ((pgrp = pgfind(uap->pgid)) == NULL) { 442 if (uap->pgid == targp->p_pid) { 443 error = enterpgrp(targp, uap->pgid, newpgrp, 444 NULL); 445 if (error == 0) 446 newpgrp = NULL; 447 } else 448 error = EPERM; 449 } else { 450 if (pgrp == targp->p_pgrp) { 451 PGRP_UNLOCK(pgrp); 452 goto done; 453 } 454 if (pgrp->pg_id != targp->p_pid && 455 pgrp->pg_session != curp->p_session) { 456 PGRP_UNLOCK(pgrp); 457 error = EPERM; 458 goto done; 459 } 460 PGRP_UNLOCK(pgrp); 461 error = enterthispgrp(targp, pgrp); 462 } 463 done: 464 sx_xunlock(&proctree_lock); 465 KASSERT((error == 0) || (newpgrp != NULL), 466 ("setpgid failed and newpgrp is NULL")); 467 if (newpgrp != NULL) 468 free(newpgrp, M_PGRP); 469 return (error); 470 } 471 472 /* 473 * Use the clause in B.4.2.2 that allows setuid/setgid to be 4.2/4.3BSD 474 * compatible. It says that setting the uid/gid to euid/egid is a special 475 * case of "appropriate privilege". Once the rules are expanded out, this 476 * basically means that setuid(nnn) sets all three id's, in all permitted 477 * cases unless _POSIX_SAVED_IDS is enabled. In that case, setuid(getuid()) 478 * does not set the saved id - this is dangerous for traditional BSD 479 * programs. For this reason, we *really* do not want to set 480 * _POSIX_SAVED_IDS and do not want to clear POSIX_APPENDIX_B_4_2_2. 481 */ 482 #define POSIX_APPENDIX_B_4_2_2 483 484 #ifndef _SYS_SYSPROTO_H_ 485 struct setuid_args { 486 uid_t uid; 487 }; 488 #endif 489 /* ARGSUSED */ 490 int 491 sys_setuid(struct thread *td, struct setuid_args *uap) 492 { 493 struct proc *p = td->td_proc; 494 struct ucred *newcred, *oldcred; 495 uid_t uid; 496 struct uidinfo *uip; 497 int error; 498 499 uid = uap->uid; 500 AUDIT_ARG_UID(uid); 501 newcred = crget(); 502 uip = uifind(uid); 503 PROC_LOCK(p); 504 /* 505 * Copy credentials so other references do not see our changes. 506 */ 507 oldcred = crcopysafe(p, newcred); 508 509 #ifdef MAC 510 error = mac_cred_check_setuid(oldcred, uid); 511 if (error) 512 goto fail; 513 #endif 514 515 /* 516 * See if we have "permission" by POSIX 1003.1 rules. 517 * 518 * Note that setuid(geteuid()) is a special case of 519 * "appropriate privileges" in appendix B.4.2.2. We need 520 * to use this clause to be compatible with traditional BSD 521 * semantics. Basically, it means that "setuid(xx)" sets all 522 * three id's (assuming you have privs). 523 * 524 * Notes on the logic. We do things in three steps. 525 * 1: We determine if the euid is going to change, and do EPERM 526 * right away. We unconditionally change the euid later if this 527 * test is satisfied, simplifying that part of the logic. 528 * 2: We determine if the real and/or saved uids are going to 529 * change. Determined by compile options. 530 * 3: Change euid last. (after tests in #2 for "appropriate privs") 531 */ 532 if (uid != oldcred->cr_ruid && /* allow setuid(getuid()) */ 533 #ifdef _POSIX_SAVED_IDS 534 uid != oldcred->cr_svuid && /* allow setuid(saved gid) */ 535 #endif 536 #ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */ 537 uid != oldcred->cr_uid && /* allow setuid(geteuid()) */ 538 #endif 539 (error = priv_check_cred(oldcred, PRIV_CRED_SETUID, 0)) != 0) 540 goto fail; 541 542 #ifdef _POSIX_SAVED_IDS 543 /* 544 * Do we have "appropriate privileges" (are we root or uid == euid) 545 * If so, we are changing the real uid and/or saved uid. 546 */ 547 if ( 548 #ifdef POSIX_APPENDIX_B_4_2_2 /* Use the clause from B.4.2.2 */ 549 uid == oldcred->cr_uid || 550 #endif 551 /* We are using privs. */ 552 priv_check_cred(oldcred, PRIV_CRED_SETUID, 0) == 0) 553 #endif 554 { 555 /* 556 * Set the real uid and transfer proc count to new user. 557 */ 558 if (uid != oldcred->cr_ruid) { 559 change_ruid(newcred, uip); 560 setsugid(p); 561 } 562 /* 563 * Set saved uid 564 * 565 * XXX always set saved uid even if not _POSIX_SAVED_IDS, as 566 * the security of seteuid() depends on it. B.4.2.2 says it 567 * is important that we should do this. 568 */ 569 if (uid != oldcred->cr_svuid) { 570 change_svuid(newcred, uid); 571 setsugid(p); 572 } 573 } 574 575 /* 576 * In all permitted cases, we are changing the euid. 577 */ 578 if (uid != oldcred->cr_uid) { 579 change_euid(newcred, uip); 580 setsugid(p); 581 } 582 p->p_ucred = newcred; 583 PROC_UNLOCK(p); 584 #ifdef RACCT 585 racct_proc_ucred_changed(p, oldcred, newcred); 586 #endif 587 uifree(uip); 588 crfree(oldcred); 589 return (0); 590 591 fail: 592 PROC_UNLOCK(p); 593 uifree(uip); 594 crfree(newcred); 595 return (error); 596 } 597 598 #ifndef _SYS_SYSPROTO_H_ 599 struct seteuid_args { 600 uid_t euid; 601 }; 602 #endif 603 /* ARGSUSED */ 604 int 605 sys_seteuid(struct thread *td, struct seteuid_args *uap) 606 { 607 struct proc *p = td->td_proc; 608 struct ucred *newcred, *oldcred; 609 uid_t euid; 610 struct uidinfo *euip; 611 int error; 612 613 euid = uap->euid; 614 AUDIT_ARG_EUID(euid); 615 newcred = crget(); 616 euip = uifind(euid); 617 PROC_LOCK(p); 618 /* 619 * Copy credentials so other references do not see our changes. 620 */ 621 oldcred = crcopysafe(p, newcred); 622 623 #ifdef MAC 624 error = mac_cred_check_seteuid(oldcred, euid); 625 if (error) 626 goto fail; 627 #endif 628 629 if (euid != oldcred->cr_ruid && /* allow seteuid(getuid()) */ 630 euid != oldcred->cr_svuid && /* allow seteuid(saved uid) */ 631 (error = priv_check_cred(oldcred, PRIV_CRED_SETEUID, 0)) != 0) 632 goto fail; 633 634 /* 635 * Everything's okay, do it. 636 */ 637 if (oldcred->cr_uid != euid) { 638 change_euid(newcred, euip); 639 setsugid(p); 640 } 641 p->p_ucred = newcred; 642 PROC_UNLOCK(p); 643 uifree(euip); 644 crfree(oldcred); 645 return (0); 646 647 fail: 648 PROC_UNLOCK(p); 649 uifree(euip); 650 crfree(newcred); 651 return (error); 652 } 653 654 #ifndef _SYS_SYSPROTO_H_ 655 struct setgid_args { 656 gid_t gid; 657 }; 658 #endif 659 /* ARGSUSED */ 660 int 661 sys_setgid(struct thread *td, struct setgid_args *uap) 662 { 663 struct proc *p = td->td_proc; 664 struct ucred *newcred, *oldcred; 665 gid_t gid; 666 int error; 667 668 gid = uap->gid; 669 AUDIT_ARG_GID(gid); 670 newcred = crget(); 671 PROC_LOCK(p); 672 oldcred = crcopysafe(p, newcred); 673 674 #ifdef MAC 675 error = mac_cred_check_setgid(oldcred, gid); 676 if (error) 677 goto fail; 678 #endif 679 680 /* 681 * See if we have "permission" by POSIX 1003.1 rules. 682 * 683 * Note that setgid(getegid()) is a special case of 684 * "appropriate privileges" in appendix B.4.2.2. We need 685 * to use this clause to be compatible with traditional BSD 686 * semantics. Basically, it means that "setgid(xx)" sets all 687 * three id's (assuming you have privs). 688 * 689 * For notes on the logic here, see setuid() above. 690 */ 691 if (gid != oldcred->cr_rgid && /* allow setgid(getgid()) */ 692 #ifdef _POSIX_SAVED_IDS 693 gid != oldcred->cr_svgid && /* allow setgid(saved gid) */ 694 #endif 695 #ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */ 696 gid != oldcred->cr_groups[0] && /* allow setgid(getegid()) */ 697 #endif 698 (error = priv_check_cred(oldcred, PRIV_CRED_SETGID, 0)) != 0) 699 goto fail; 700 701 #ifdef _POSIX_SAVED_IDS 702 /* 703 * Do we have "appropriate privileges" (are we root or gid == egid) 704 * If so, we are changing the real uid and saved gid. 705 */ 706 if ( 707 #ifdef POSIX_APPENDIX_B_4_2_2 /* use the clause from B.4.2.2 */ 708 gid == oldcred->cr_groups[0] || 709 #endif 710 /* We are using privs. */ 711 priv_check_cred(oldcred, PRIV_CRED_SETGID, 0) == 0) 712 #endif 713 { 714 /* 715 * Set real gid 716 */ 717 if (oldcred->cr_rgid != gid) { 718 change_rgid(newcred, gid); 719 setsugid(p); 720 } 721 /* 722 * Set saved gid 723 * 724 * XXX always set saved gid even if not _POSIX_SAVED_IDS, as 725 * the security of setegid() depends on it. B.4.2.2 says it 726 * is important that we should do this. 727 */ 728 if (oldcred->cr_svgid != gid) { 729 change_svgid(newcred, gid); 730 setsugid(p); 731 } 732 } 733 /* 734 * In all cases permitted cases, we are changing the egid. 735 * Copy credentials so other references do not see our changes. 736 */ 737 if (oldcred->cr_groups[0] != gid) { 738 change_egid(newcred, gid); 739 setsugid(p); 740 } 741 p->p_ucred = newcred; 742 PROC_UNLOCK(p); 743 crfree(oldcred); 744 return (0); 745 746 fail: 747 PROC_UNLOCK(p); 748 crfree(newcred); 749 return (error); 750 } 751 752 #ifndef _SYS_SYSPROTO_H_ 753 struct setegid_args { 754 gid_t egid; 755 }; 756 #endif 757 /* ARGSUSED */ 758 int 759 sys_setegid(struct thread *td, struct setegid_args *uap) 760 { 761 struct proc *p = td->td_proc; 762 struct ucred *newcred, *oldcred; 763 gid_t egid; 764 int error; 765 766 egid = uap->egid; 767 AUDIT_ARG_EGID(egid); 768 newcred = crget(); 769 PROC_LOCK(p); 770 oldcred = crcopysafe(p, newcred); 771 772 #ifdef MAC 773 error = mac_cred_check_setegid(oldcred, egid); 774 if (error) 775 goto fail; 776 #endif 777 778 if (egid != oldcred->cr_rgid && /* allow setegid(getgid()) */ 779 egid != oldcred->cr_svgid && /* allow setegid(saved gid) */ 780 (error = priv_check_cred(oldcred, PRIV_CRED_SETEGID, 0)) != 0) 781 goto fail; 782 783 if (oldcred->cr_groups[0] != egid) { 784 change_egid(newcred, egid); 785 setsugid(p); 786 } 787 p->p_ucred = newcred; 788 PROC_UNLOCK(p); 789 crfree(oldcred); 790 return (0); 791 792 fail: 793 PROC_UNLOCK(p); 794 crfree(newcred); 795 return (error); 796 } 797 798 #ifndef _SYS_SYSPROTO_H_ 799 struct setgroups_args { 800 u_int gidsetsize; 801 gid_t *gidset; 802 }; 803 #endif 804 /* ARGSUSED */ 805 int 806 sys_setgroups(struct thread *td, struct setgroups_args *uap) 807 { 808 gid_t smallgroups[XU_NGROUPS]; 809 gid_t *groups; 810 u_int gidsetsize; 811 int error; 812 813 gidsetsize = uap->gidsetsize; 814 if (gidsetsize > ngroups_max + 1) 815 return (EINVAL); 816 817 if (gidsetsize > XU_NGROUPS) 818 groups = malloc(gidsetsize * sizeof(gid_t), M_TEMP, M_WAITOK); 819 else 820 groups = smallgroups; 821 822 error = copyin(uap->gidset, groups, gidsetsize * sizeof(gid_t)); 823 if (error == 0) 824 error = kern_setgroups(td, gidsetsize, groups); 825 826 if (gidsetsize > XU_NGROUPS) 827 free(groups, M_TEMP); 828 return (error); 829 } 830 831 int 832 kern_setgroups(struct thread *td, u_int ngrp, gid_t *groups) 833 { 834 struct proc *p = td->td_proc; 835 struct ucred *newcred, *oldcred; 836 int error; 837 838 MPASS(ngrp <= ngroups_max + 1); 839 AUDIT_ARG_GROUPSET(groups, ngrp); 840 newcred = crget(); 841 crextend(newcred, ngrp); 842 PROC_LOCK(p); 843 oldcred = crcopysafe(p, newcred); 844 845 #ifdef MAC 846 error = mac_cred_check_setgroups(oldcred, ngrp, groups); 847 if (error) 848 goto fail; 849 #endif 850 851 error = priv_check_cred(oldcred, PRIV_CRED_SETGROUPS, 0); 852 if (error) 853 goto fail; 854 855 if (ngrp == 0) { 856 /* 857 * setgroups(0, NULL) is a legitimate way of clearing the 858 * groups vector on non-BSD systems (which generally do not 859 * have the egid in the groups[0]). We risk security holes 860 * when running non-BSD software if we do not do the same. 861 */ 862 newcred->cr_ngroups = 1; 863 } else { 864 crsetgroups_locked(newcred, ngrp, groups); 865 } 866 setsugid(p); 867 p->p_ucred = newcred; 868 PROC_UNLOCK(p); 869 crfree(oldcred); 870 return (0); 871 872 fail: 873 PROC_UNLOCK(p); 874 crfree(newcred); 875 return (error); 876 } 877 878 #ifndef _SYS_SYSPROTO_H_ 879 struct setreuid_args { 880 uid_t ruid; 881 uid_t euid; 882 }; 883 #endif 884 /* ARGSUSED */ 885 int 886 sys_setreuid(register struct thread *td, struct setreuid_args *uap) 887 { 888 struct proc *p = td->td_proc; 889 struct ucred *newcred, *oldcred; 890 uid_t euid, ruid; 891 struct uidinfo *euip, *ruip; 892 int error; 893 894 euid = uap->euid; 895 ruid = uap->ruid; 896 AUDIT_ARG_EUID(euid); 897 AUDIT_ARG_RUID(ruid); 898 newcred = crget(); 899 euip = uifind(euid); 900 ruip = uifind(ruid); 901 PROC_LOCK(p); 902 oldcred = crcopysafe(p, newcred); 903 904 #ifdef MAC 905 error = mac_cred_check_setreuid(oldcred, ruid, euid); 906 if (error) 907 goto fail; 908 #endif 909 910 if (((ruid != (uid_t)-1 && ruid != oldcred->cr_ruid && 911 ruid != oldcred->cr_svuid) || 912 (euid != (uid_t)-1 && euid != oldcred->cr_uid && 913 euid != oldcred->cr_ruid && euid != oldcred->cr_svuid)) && 914 (error = priv_check_cred(oldcred, PRIV_CRED_SETREUID, 0)) != 0) 915 goto fail; 916 917 if (euid != (uid_t)-1 && oldcred->cr_uid != euid) { 918 change_euid(newcred, euip); 919 setsugid(p); 920 } 921 if (ruid != (uid_t)-1 && oldcred->cr_ruid != ruid) { 922 change_ruid(newcred, ruip); 923 setsugid(p); 924 } 925 if ((ruid != (uid_t)-1 || newcred->cr_uid != newcred->cr_ruid) && 926 newcred->cr_svuid != newcred->cr_uid) { 927 change_svuid(newcred, newcred->cr_uid); 928 setsugid(p); 929 } 930 p->p_ucred = newcred; 931 PROC_UNLOCK(p); 932 #ifdef RACCT 933 racct_proc_ucred_changed(p, oldcred, newcred); 934 #endif 935 uifree(ruip); 936 uifree(euip); 937 crfree(oldcred); 938 return (0); 939 940 fail: 941 PROC_UNLOCK(p); 942 uifree(ruip); 943 uifree(euip); 944 crfree(newcred); 945 return (error); 946 } 947 948 #ifndef _SYS_SYSPROTO_H_ 949 struct setregid_args { 950 gid_t rgid; 951 gid_t egid; 952 }; 953 #endif 954 /* ARGSUSED */ 955 int 956 sys_setregid(register struct thread *td, struct setregid_args *uap) 957 { 958 struct proc *p = td->td_proc; 959 struct ucred *newcred, *oldcred; 960 gid_t egid, rgid; 961 int error; 962 963 egid = uap->egid; 964 rgid = uap->rgid; 965 AUDIT_ARG_EGID(egid); 966 AUDIT_ARG_RGID(rgid); 967 newcred = crget(); 968 PROC_LOCK(p); 969 oldcred = crcopysafe(p, newcred); 970 971 #ifdef MAC 972 error = mac_cred_check_setregid(oldcred, rgid, egid); 973 if (error) 974 goto fail; 975 #endif 976 977 if (((rgid != (gid_t)-1 && rgid != oldcred->cr_rgid && 978 rgid != oldcred->cr_svgid) || 979 (egid != (gid_t)-1 && egid != oldcred->cr_groups[0] && 980 egid != oldcred->cr_rgid && egid != oldcred->cr_svgid)) && 981 (error = priv_check_cred(oldcred, PRIV_CRED_SETREGID, 0)) != 0) 982 goto fail; 983 984 if (egid != (gid_t)-1 && oldcred->cr_groups[0] != egid) { 985 change_egid(newcred, egid); 986 setsugid(p); 987 } 988 if (rgid != (gid_t)-1 && oldcred->cr_rgid != rgid) { 989 change_rgid(newcred, rgid); 990 setsugid(p); 991 } 992 if ((rgid != (gid_t)-1 || newcred->cr_groups[0] != newcred->cr_rgid) && 993 newcred->cr_svgid != newcred->cr_groups[0]) { 994 change_svgid(newcred, newcred->cr_groups[0]); 995 setsugid(p); 996 } 997 p->p_ucred = newcred; 998 PROC_UNLOCK(p); 999 crfree(oldcred); 1000 return (0); 1001 1002 fail: 1003 PROC_UNLOCK(p); 1004 crfree(newcred); 1005 return (error); 1006 } 1007 1008 /* 1009 * setresuid(ruid, euid, suid) is like setreuid except control over the saved 1010 * uid is explicit. 1011 */ 1012 #ifndef _SYS_SYSPROTO_H_ 1013 struct setresuid_args { 1014 uid_t ruid; 1015 uid_t euid; 1016 uid_t suid; 1017 }; 1018 #endif 1019 /* ARGSUSED */ 1020 int 1021 sys_setresuid(register struct thread *td, struct setresuid_args *uap) 1022 { 1023 struct proc *p = td->td_proc; 1024 struct ucred *newcred, *oldcred; 1025 uid_t euid, ruid, suid; 1026 struct uidinfo *euip, *ruip; 1027 int error; 1028 1029 euid = uap->euid; 1030 ruid = uap->ruid; 1031 suid = uap->suid; 1032 AUDIT_ARG_EUID(euid); 1033 AUDIT_ARG_RUID(ruid); 1034 AUDIT_ARG_SUID(suid); 1035 newcred = crget(); 1036 euip = uifind(euid); 1037 ruip = uifind(ruid); 1038 PROC_LOCK(p); 1039 oldcred = crcopysafe(p, newcred); 1040 1041 #ifdef MAC 1042 error = mac_cred_check_setresuid(oldcred, ruid, euid, suid); 1043 if (error) 1044 goto fail; 1045 #endif 1046 1047 if (((ruid != (uid_t)-1 && ruid != oldcred->cr_ruid && 1048 ruid != oldcred->cr_svuid && 1049 ruid != oldcred->cr_uid) || 1050 (euid != (uid_t)-1 && euid != oldcred->cr_ruid && 1051 euid != oldcred->cr_svuid && 1052 euid != oldcred->cr_uid) || 1053 (suid != (uid_t)-1 && suid != oldcred->cr_ruid && 1054 suid != oldcred->cr_svuid && 1055 suid != oldcred->cr_uid)) && 1056 (error = priv_check_cred(oldcred, PRIV_CRED_SETRESUID, 0)) != 0) 1057 goto fail; 1058 1059 if (euid != (uid_t)-1 && oldcred->cr_uid != euid) { 1060 change_euid(newcred, euip); 1061 setsugid(p); 1062 } 1063 if (ruid != (uid_t)-1 && oldcred->cr_ruid != ruid) { 1064 change_ruid(newcred, ruip); 1065 setsugid(p); 1066 } 1067 if (suid != (uid_t)-1 && oldcred->cr_svuid != suid) { 1068 change_svuid(newcred, suid); 1069 setsugid(p); 1070 } 1071 p->p_ucred = newcred; 1072 PROC_UNLOCK(p); 1073 #ifdef RACCT 1074 racct_proc_ucred_changed(p, oldcred, newcred); 1075 #endif 1076 uifree(ruip); 1077 uifree(euip); 1078 crfree(oldcred); 1079 return (0); 1080 1081 fail: 1082 PROC_UNLOCK(p); 1083 uifree(ruip); 1084 uifree(euip); 1085 crfree(newcred); 1086 return (error); 1087 1088 } 1089 1090 /* 1091 * setresgid(rgid, egid, sgid) is like setregid except control over the saved 1092 * gid is explicit. 1093 */ 1094 #ifndef _SYS_SYSPROTO_H_ 1095 struct setresgid_args { 1096 gid_t rgid; 1097 gid_t egid; 1098 gid_t sgid; 1099 }; 1100 #endif 1101 /* ARGSUSED */ 1102 int 1103 sys_setresgid(register struct thread *td, struct setresgid_args *uap) 1104 { 1105 struct proc *p = td->td_proc; 1106 struct ucred *newcred, *oldcred; 1107 gid_t egid, rgid, sgid; 1108 int error; 1109 1110 egid = uap->egid; 1111 rgid = uap->rgid; 1112 sgid = uap->sgid; 1113 AUDIT_ARG_EGID(egid); 1114 AUDIT_ARG_RGID(rgid); 1115 AUDIT_ARG_SGID(sgid); 1116 newcred = crget(); 1117 PROC_LOCK(p); 1118 oldcred = crcopysafe(p, newcred); 1119 1120 #ifdef MAC 1121 error = mac_cred_check_setresgid(oldcred, rgid, egid, sgid); 1122 if (error) 1123 goto fail; 1124 #endif 1125 1126 if (((rgid != (gid_t)-1 && rgid != oldcred->cr_rgid && 1127 rgid != oldcred->cr_svgid && 1128 rgid != oldcred->cr_groups[0]) || 1129 (egid != (gid_t)-1 && egid != oldcred->cr_rgid && 1130 egid != oldcred->cr_svgid && 1131 egid != oldcred->cr_groups[0]) || 1132 (sgid != (gid_t)-1 && sgid != oldcred->cr_rgid && 1133 sgid != oldcred->cr_svgid && 1134 sgid != oldcred->cr_groups[0])) && 1135 (error = priv_check_cred(oldcred, PRIV_CRED_SETRESGID, 0)) != 0) 1136 goto fail; 1137 1138 if (egid != (gid_t)-1 && oldcred->cr_groups[0] != egid) { 1139 change_egid(newcred, egid); 1140 setsugid(p); 1141 } 1142 if (rgid != (gid_t)-1 && oldcred->cr_rgid != rgid) { 1143 change_rgid(newcred, rgid); 1144 setsugid(p); 1145 } 1146 if (sgid != (gid_t)-1 && oldcred->cr_svgid != sgid) { 1147 change_svgid(newcred, sgid); 1148 setsugid(p); 1149 } 1150 p->p_ucred = newcred; 1151 PROC_UNLOCK(p); 1152 crfree(oldcred); 1153 return (0); 1154 1155 fail: 1156 PROC_UNLOCK(p); 1157 crfree(newcred); 1158 return (error); 1159 } 1160 1161 #ifndef _SYS_SYSPROTO_H_ 1162 struct getresuid_args { 1163 uid_t *ruid; 1164 uid_t *euid; 1165 uid_t *suid; 1166 }; 1167 #endif 1168 /* ARGSUSED */ 1169 int 1170 sys_getresuid(register struct thread *td, struct getresuid_args *uap) 1171 { 1172 struct ucred *cred; 1173 int error1 = 0, error2 = 0, error3 = 0; 1174 1175 cred = td->td_ucred; 1176 if (uap->ruid) 1177 error1 = copyout(&cred->cr_ruid, 1178 uap->ruid, sizeof(cred->cr_ruid)); 1179 if (uap->euid) 1180 error2 = copyout(&cred->cr_uid, 1181 uap->euid, sizeof(cred->cr_uid)); 1182 if (uap->suid) 1183 error3 = copyout(&cred->cr_svuid, 1184 uap->suid, sizeof(cred->cr_svuid)); 1185 return (error1 ? error1 : error2 ? error2 : error3); 1186 } 1187 1188 #ifndef _SYS_SYSPROTO_H_ 1189 struct getresgid_args { 1190 gid_t *rgid; 1191 gid_t *egid; 1192 gid_t *sgid; 1193 }; 1194 #endif 1195 /* ARGSUSED */ 1196 int 1197 sys_getresgid(register struct thread *td, struct getresgid_args *uap) 1198 { 1199 struct ucred *cred; 1200 int error1 = 0, error2 = 0, error3 = 0; 1201 1202 cred = td->td_ucred; 1203 if (uap->rgid) 1204 error1 = copyout(&cred->cr_rgid, 1205 uap->rgid, sizeof(cred->cr_rgid)); 1206 if (uap->egid) 1207 error2 = copyout(&cred->cr_groups[0], 1208 uap->egid, sizeof(cred->cr_groups[0])); 1209 if (uap->sgid) 1210 error3 = copyout(&cred->cr_svgid, 1211 uap->sgid, sizeof(cred->cr_svgid)); 1212 return (error1 ? error1 : error2 ? error2 : error3); 1213 } 1214 1215 #ifndef _SYS_SYSPROTO_H_ 1216 struct issetugid_args { 1217 int dummy; 1218 }; 1219 #endif 1220 /* ARGSUSED */ 1221 int 1222 sys_issetugid(register struct thread *td, struct issetugid_args *uap) 1223 { 1224 struct proc *p = td->td_proc; 1225 1226 /* 1227 * Note: OpenBSD sets a P_SUGIDEXEC flag set at execve() time, 1228 * we use P_SUGID because we consider changing the owners as 1229 * "tainting" as well. 1230 * This is significant for procs that start as root and "become" 1231 * a user without an exec - programs cannot know *everything* 1232 * that libc *might* have put in their data segment. 1233 */ 1234 PROC_LOCK(p); 1235 td->td_retval[0] = (p->p_flag & P_SUGID) ? 1 : 0; 1236 PROC_UNLOCK(p); 1237 return (0); 1238 } 1239 1240 int 1241 sys___setugid(struct thread *td, struct __setugid_args *uap) 1242 { 1243 #ifdef REGRESSION 1244 struct proc *p; 1245 1246 p = td->td_proc; 1247 switch (uap->flag) { 1248 case 0: 1249 PROC_LOCK(p); 1250 p->p_flag &= ~P_SUGID; 1251 PROC_UNLOCK(p); 1252 return (0); 1253 case 1: 1254 PROC_LOCK(p); 1255 p->p_flag |= P_SUGID; 1256 PROC_UNLOCK(p); 1257 return (0); 1258 default: 1259 return (EINVAL); 1260 } 1261 #else /* !REGRESSION */ 1262 1263 return (ENOSYS); 1264 #endif /* REGRESSION */ 1265 } 1266 1267 /* 1268 * Check if gid is a member of the group set. 1269 */ 1270 int 1271 groupmember(gid_t gid, struct ucred *cred) 1272 { 1273 int l; 1274 int h; 1275 int m; 1276 1277 if (cred->cr_groups[0] == gid) 1278 return(1); 1279 1280 /* 1281 * If gid was not our primary group, perform a binary search 1282 * of the supplemental groups. This is possible because we 1283 * sort the groups in crsetgroups(). 1284 */ 1285 l = 1; 1286 h = cred->cr_ngroups; 1287 while (l < h) { 1288 m = l + ((h - l) / 2); 1289 if (cred->cr_groups[m] < gid) 1290 l = m + 1; 1291 else 1292 h = m; 1293 } 1294 if ((l < cred->cr_ngroups) && (cred->cr_groups[l] == gid)) 1295 return (1); 1296 1297 return (0); 1298 } 1299 1300 /* 1301 * Test the active securelevel against a given level. securelevel_gt() 1302 * implements (securelevel > level). securelevel_ge() implements 1303 * (securelevel >= level). Note that the logic is inverted -- these 1304 * functions return EPERM on "success" and 0 on "failure". 1305 * 1306 * Due to care taken when setting the securelevel, we know that no jail will 1307 * be less secure that its parent (or the physical system), so it is sufficient 1308 * to test the current jail only. 1309 * 1310 * XXXRW: Possibly since this has to do with privilege, it should move to 1311 * kern_priv.c. 1312 */ 1313 int 1314 securelevel_gt(struct ucred *cr, int level) 1315 { 1316 1317 return (cr->cr_prison->pr_securelevel > level ? EPERM : 0); 1318 } 1319 1320 int 1321 securelevel_ge(struct ucred *cr, int level) 1322 { 1323 1324 return (cr->cr_prison->pr_securelevel >= level ? EPERM : 0); 1325 } 1326 1327 /* 1328 * 'see_other_uids' determines whether or not visibility of processes 1329 * and sockets with credentials holding different real uids is possible 1330 * using a variety of system MIBs. 1331 * XXX: data declarations should be together near the beginning of the file. 1332 */ 1333 static int see_other_uids = 1; 1334 SYSCTL_INT(_security_bsd, OID_AUTO, see_other_uids, CTLFLAG_RW, 1335 &see_other_uids, 0, 1336 "Unprivileged processes may see subjects/objects with different real uid"); 1337 1338 /*- 1339 * Determine if u1 "can see" the subject specified by u2, according to the 1340 * 'see_other_uids' policy. 1341 * Returns: 0 for permitted, ESRCH otherwise 1342 * Locks: none 1343 * References: *u1 and *u2 must not change during the call 1344 * u1 may equal u2, in which case only one reference is required 1345 */ 1346 static int 1347 cr_seeotheruids(struct ucred *u1, struct ucred *u2) 1348 { 1349 1350 if (!see_other_uids && u1->cr_ruid != u2->cr_ruid) { 1351 if (priv_check_cred(u1, PRIV_SEEOTHERUIDS, 0) != 0) 1352 return (ESRCH); 1353 } 1354 return (0); 1355 } 1356 1357 /* 1358 * 'see_other_gids' determines whether or not visibility of processes 1359 * and sockets with credentials holding different real gids is possible 1360 * using a variety of system MIBs. 1361 * XXX: data declarations should be together near the beginning of the file. 1362 */ 1363 static int see_other_gids = 1; 1364 SYSCTL_INT(_security_bsd, OID_AUTO, see_other_gids, CTLFLAG_RW, 1365 &see_other_gids, 0, 1366 "Unprivileged processes may see subjects/objects with different real gid"); 1367 1368 /* 1369 * Determine if u1 can "see" the subject specified by u2, according to the 1370 * 'see_other_gids' policy. 1371 * Returns: 0 for permitted, ESRCH otherwise 1372 * Locks: none 1373 * References: *u1 and *u2 must not change during the call 1374 * u1 may equal u2, in which case only one reference is required 1375 */ 1376 static int 1377 cr_seeothergids(struct ucred *u1, struct ucred *u2) 1378 { 1379 int i, match; 1380 1381 if (!see_other_gids) { 1382 match = 0; 1383 for (i = 0; i < u1->cr_ngroups; i++) { 1384 if (groupmember(u1->cr_groups[i], u2)) 1385 match = 1; 1386 if (match) 1387 break; 1388 } 1389 if (!match) { 1390 if (priv_check_cred(u1, PRIV_SEEOTHERGIDS, 0) != 0) 1391 return (ESRCH); 1392 } 1393 } 1394 return (0); 1395 } 1396 1397 /*- 1398 * Determine if u1 "can see" the subject specified by u2. 1399 * Returns: 0 for permitted, an errno value otherwise 1400 * Locks: none 1401 * References: *u1 and *u2 must not change during the call 1402 * u1 may equal u2, in which case only one reference is required 1403 */ 1404 int 1405 cr_cansee(struct ucred *u1, struct ucred *u2) 1406 { 1407 int error; 1408 1409 if ((error = prison_check(u1, u2))) 1410 return (error); 1411 #ifdef MAC 1412 if ((error = mac_cred_check_visible(u1, u2))) 1413 return (error); 1414 #endif 1415 if ((error = cr_seeotheruids(u1, u2))) 1416 return (error); 1417 if ((error = cr_seeothergids(u1, u2))) 1418 return (error); 1419 return (0); 1420 } 1421 1422 /*- 1423 * Determine if td "can see" the subject specified by p. 1424 * Returns: 0 for permitted, an errno value otherwise 1425 * Locks: Sufficient locks to protect p->p_ucred must be held. td really 1426 * should be curthread. 1427 * References: td and p must be valid for the lifetime of the call 1428 */ 1429 int 1430 p_cansee(struct thread *td, struct proc *p) 1431 { 1432 1433 /* Wrap cr_cansee() for all functionality. */ 1434 KASSERT(td == curthread, ("%s: td not curthread", __func__)); 1435 PROC_LOCK_ASSERT(p, MA_OWNED); 1436 return (cr_cansee(td->td_ucred, p->p_ucred)); 1437 } 1438 1439 /* 1440 * 'conservative_signals' prevents the delivery of a broad class of 1441 * signals by unprivileged processes to processes that have changed their 1442 * credentials since the last invocation of execve(). This can prevent 1443 * the leakage of cached information or retained privileges as a result 1444 * of a common class of signal-related vulnerabilities. However, this 1445 * may interfere with some applications that expect to be able to 1446 * deliver these signals to peer processes after having given up 1447 * privilege. 1448 */ 1449 static int conservative_signals = 1; 1450 SYSCTL_INT(_security_bsd, OID_AUTO, conservative_signals, CTLFLAG_RW, 1451 &conservative_signals, 0, "Unprivileged processes prevented from " 1452 "sending certain signals to processes whose credentials have changed"); 1453 /*- 1454 * Determine whether cred may deliver the specified signal to proc. 1455 * Returns: 0 for permitted, an errno value otherwise. 1456 * Locks: A lock must be held for proc. 1457 * References: cred and proc must be valid for the lifetime of the call. 1458 */ 1459 int 1460 cr_cansignal(struct ucred *cred, struct proc *proc, int signum) 1461 { 1462 int error; 1463 1464 PROC_LOCK_ASSERT(proc, MA_OWNED); 1465 /* 1466 * Jail semantics limit the scope of signalling to proc in the 1467 * same jail as cred, if cred is in jail. 1468 */ 1469 error = prison_check(cred, proc->p_ucred); 1470 if (error) 1471 return (error); 1472 #ifdef MAC 1473 if ((error = mac_proc_check_signal(cred, proc, signum))) 1474 return (error); 1475 #endif 1476 if ((error = cr_seeotheruids(cred, proc->p_ucred))) 1477 return (error); 1478 if ((error = cr_seeothergids(cred, proc->p_ucred))) 1479 return (error); 1480 1481 /* 1482 * UNIX signal semantics depend on the status of the P_SUGID 1483 * bit on the target process. If the bit is set, then additional 1484 * restrictions are placed on the set of available signals. 1485 */ 1486 if (conservative_signals && (proc->p_flag & P_SUGID)) { 1487 switch (signum) { 1488 case 0: 1489 case SIGKILL: 1490 case SIGINT: 1491 case SIGTERM: 1492 case SIGALRM: 1493 case SIGSTOP: 1494 case SIGTTIN: 1495 case SIGTTOU: 1496 case SIGTSTP: 1497 case SIGHUP: 1498 case SIGUSR1: 1499 case SIGUSR2: 1500 /* 1501 * Generally, permit job and terminal control 1502 * signals. 1503 */ 1504 break; 1505 default: 1506 /* Not permitted without privilege. */ 1507 error = priv_check_cred(cred, PRIV_SIGNAL_SUGID, 0); 1508 if (error) 1509 return (error); 1510 } 1511 } 1512 1513 /* 1514 * Generally, the target credential's ruid or svuid must match the 1515 * subject credential's ruid or euid. 1516 */ 1517 if (cred->cr_ruid != proc->p_ucred->cr_ruid && 1518 cred->cr_ruid != proc->p_ucred->cr_svuid && 1519 cred->cr_uid != proc->p_ucred->cr_ruid && 1520 cred->cr_uid != proc->p_ucred->cr_svuid) { 1521 error = priv_check_cred(cred, PRIV_SIGNAL_DIFFCRED, 0); 1522 if (error) 1523 return (error); 1524 } 1525 1526 return (0); 1527 } 1528 1529 /*- 1530 * Determine whether td may deliver the specified signal to p. 1531 * Returns: 0 for permitted, an errno value otherwise 1532 * Locks: Sufficient locks to protect various components of td and p 1533 * must be held. td must be curthread, and a lock must be 1534 * held for p. 1535 * References: td and p must be valid for the lifetime of the call 1536 */ 1537 int 1538 p_cansignal(struct thread *td, struct proc *p, int signum) 1539 { 1540 1541 KASSERT(td == curthread, ("%s: td not curthread", __func__)); 1542 PROC_LOCK_ASSERT(p, MA_OWNED); 1543 if (td->td_proc == p) 1544 return (0); 1545 1546 /* 1547 * UNIX signalling semantics require that processes in the same 1548 * session always be able to deliver SIGCONT to one another, 1549 * overriding the remaining protections. 1550 */ 1551 /* XXX: This will require an additional lock of some sort. */ 1552 if (signum == SIGCONT && td->td_proc->p_session == p->p_session) 1553 return (0); 1554 /* 1555 * Some compat layers use SIGTHR and higher signals for 1556 * communication between different kernel threads of the same 1557 * process, so that they expect that it's always possible to 1558 * deliver them, even for suid applications where cr_cansignal() can 1559 * deny such ability for security consideration. It should be 1560 * pretty safe to do since the only way to create two processes 1561 * with the same p_leader is via rfork(2). 1562 */ 1563 if (td->td_proc->p_leader != NULL && signum >= SIGTHR && 1564 signum < SIGTHR + 4 && td->td_proc->p_leader == p->p_leader) 1565 return (0); 1566 1567 return (cr_cansignal(td->td_ucred, p, signum)); 1568 } 1569 1570 /*- 1571 * Determine whether td may reschedule p. 1572 * Returns: 0 for permitted, an errno value otherwise 1573 * Locks: Sufficient locks to protect various components of td and p 1574 * must be held. td must be curthread, and a lock must 1575 * be held for p. 1576 * References: td and p must be valid for the lifetime of the call 1577 */ 1578 int 1579 p_cansched(struct thread *td, struct proc *p) 1580 { 1581 int error; 1582 1583 KASSERT(td == curthread, ("%s: td not curthread", __func__)); 1584 PROC_LOCK_ASSERT(p, MA_OWNED); 1585 if (td->td_proc == p) 1586 return (0); 1587 if ((error = prison_check(td->td_ucred, p->p_ucred))) 1588 return (error); 1589 #ifdef MAC 1590 if ((error = mac_proc_check_sched(td->td_ucred, p))) 1591 return (error); 1592 #endif 1593 if ((error = cr_seeotheruids(td->td_ucred, p->p_ucred))) 1594 return (error); 1595 if ((error = cr_seeothergids(td->td_ucred, p->p_ucred))) 1596 return (error); 1597 if (td->td_ucred->cr_ruid != p->p_ucred->cr_ruid && 1598 td->td_ucred->cr_uid != p->p_ucred->cr_ruid) { 1599 error = priv_check(td, PRIV_SCHED_DIFFCRED); 1600 if (error) 1601 return (error); 1602 } 1603 return (0); 1604 } 1605 1606 /* 1607 * The 'unprivileged_proc_debug' flag may be used to disable a variety of 1608 * unprivileged inter-process debugging services, including some procfs 1609 * functionality, ptrace(), and ktrace(). In the past, inter-process 1610 * debugging has been involved in a variety of security problems, and sites 1611 * not requiring the service might choose to disable it when hardening 1612 * systems. 1613 * 1614 * XXX: Should modifying and reading this variable require locking? 1615 * XXX: data declarations should be together near the beginning of the file. 1616 */ 1617 static int unprivileged_proc_debug = 1; 1618 SYSCTL_INT(_security_bsd, OID_AUTO, unprivileged_proc_debug, CTLFLAG_RW, 1619 &unprivileged_proc_debug, 0, 1620 "Unprivileged processes may use process debugging facilities"); 1621 1622 /*- 1623 * Determine whether td may debug p. 1624 * Returns: 0 for permitted, an errno value otherwise 1625 * Locks: Sufficient locks to protect various components of td and p 1626 * must be held. td must be curthread, and a lock must 1627 * be held for p. 1628 * References: td and p must be valid for the lifetime of the call 1629 */ 1630 int 1631 p_candebug(struct thread *td, struct proc *p) 1632 { 1633 int credentialchanged, error, grpsubset, i, uidsubset; 1634 1635 KASSERT(td == curthread, ("%s: td not curthread", __func__)); 1636 PROC_LOCK_ASSERT(p, MA_OWNED); 1637 if (!unprivileged_proc_debug) { 1638 error = priv_check(td, PRIV_DEBUG_UNPRIV); 1639 if (error) 1640 return (error); 1641 } 1642 if (td->td_proc == p) 1643 return (0); 1644 if ((error = prison_check(td->td_ucred, p->p_ucred))) 1645 return (error); 1646 #ifdef MAC 1647 if ((error = mac_proc_check_debug(td->td_ucred, p))) 1648 return (error); 1649 #endif 1650 if ((error = cr_seeotheruids(td->td_ucred, p->p_ucred))) 1651 return (error); 1652 if ((error = cr_seeothergids(td->td_ucred, p->p_ucred))) 1653 return (error); 1654 1655 /* 1656 * Is p's group set a subset of td's effective group set? This 1657 * includes p's egid, group access list, rgid, and svgid. 1658 */ 1659 grpsubset = 1; 1660 for (i = 0; i < p->p_ucred->cr_ngroups; i++) { 1661 if (!groupmember(p->p_ucred->cr_groups[i], td->td_ucred)) { 1662 grpsubset = 0; 1663 break; 1664 } 1665 } 1666 grpsubset = grpsubset && 1667 groupmember(p->p_ucred->cr_rgid, td->td_ucred) && 1668 groupmember(p->p_ucred->cr_svgid, td->td_ucred); 1669 1670 /* 1671 * Are the uids present in p's credential equal to td's 1672 * effective uid? This includes p's euid, svuid, and ruid. 1673 */ 1674 uidsubset = (td->td_ucred->cr_uid == p->p_ucred->cr_uid && 1675 td->td_ucred->cr_uid == p->p_ucred->cr_svuid && 1676 td->td_ucred->cr_uid == p->p_ucred->cr_ruid); 1677 1678 /* 1679 * Has the credential of the process changed since the last exec()? 1680 */ 1681 credentialchanged = (p->p_flag & P_SUGID); 1682 1683 /* 1684 * If p's gids aren't a subset, or the uids aren't a subset, 1685 * or the credential has changed, require appropriate privilege 1686 * for td to debug p. 1687 */ 1688 if (!grpsubset || !uidsubset) { 1689 error = priv_check(td, PRIV_DEBUG_DIFFCRED); 1690 if (error) 1691 return (error); 1692 } 1693 1694 if (credentialchanged) { 1695 error = priv_check(td, PRIV_DEBUG_SUGID); 1696 if (error) 1697 return (error); 1698 } 1699 1700 /* Can't trace init when securelevel > 0. */ 1701 if (p == initproc) { 1702 error = securelevel_gt(td->td_ucred, 0); 1703 if (error) 1704 return (error); 1705 } 1706 1707 /* 1708 * Can't trace a process that's currently exec'ing. 1709 * 1710 * XXX: Note, this is not a security policy decision, it's a 1711 * basic correctness/functionality decision. Therefore, this check 1712 * should be moved to the caller's of p_candebug(). 1713 */ 1714 if ((p->p_flag & P_INEXEC) != 0) 1715 return (EBUSY); 1716 1717 return (0); 1718 } 1719 1720 /*- 1721 * Determine whether the subject represented by cred can "see" a socket. 1722 * Returns: 0 for permitted, ENOENT otherwise. 1723 */ 1724 int 1725 cr_canseesocket(struct ucred *cred, struct socket *so) 1726 { 1727 int error; 1728 1729 error = prison_check(cred, so->so_cred); 1730 if (error) 1731 return (ENOENT); 1732 #ifdef MAC 1733 error = mac_socket_check_visible(cred, so); 1734 if (error) 1735 return (error); 1736 #endif 1737 if (cr_seeotheruids(cred, so->so_cred)) 1738 return (ENOENT); 1739 if (cr_seeothergids(cred, so->so_cred)) 1740 return (ENOENT); 1741 1742 return (0); 1743 } 1744 1745 #if defined(INET) || defined(INET6) 1746 /*- 1747 * Determine whether the subject represented by cred can "see" a socket. 1748 * Returns: 0 for permitted, ENOENT otherwise. 1749 */ 1750 int 1751 cr_canseeinpcb(struct ucred *cred, struct inpcb *inp) 1752 { 1753 int error; 1754 1755 error = prison_check(cred, inp->inp_cred); 1756 if (error) 1757 return (ENOENT); 1758 #ifdef MAC 1759 INP_LOCK_ASSERT(inp); 1760 error = mac_inpcb_check_visible(cred, inp); 1761 if (error) 1762 return (error); 1763 #endif 1764 if (cr_seeotheruids(cred, inp->inp_cred)) 1765 return (ENOENT); 1766 if (cr_seeothergids(cred, inp->inp_cred)) 1767 return (ENOENT); 1768 1769 return (0); 1770 } 1771 #endif 1772 1773 /*- 1774 * Determine whether td can wait for the exit of p. 1775 * Returns: 0 for permitted, an errno value otherwise 1776 * Locks: Sufficient locks to protect various components of td and p 1777 * must be held. td must be curthread, and a lock must 1778 * be held for p. 1779 * References: td and p must be valid for the lifetime of the call 1780 1781 */ 1782 int 1783 p_canwait(struct thread *td, struct proc *p) 1784 { 1785 int error; 1786 1787 KASSERT(td == curthread, ("%s: td not curthread", __func__)); 1788 PROC_LOCK_ASSERT(p, MA_OWNED); 1789 if ((error = prison_check(td->td_ucred, p->p_ucred))) 1790 return (error); 1791 #ifdef MAC 1792 if ((error = mac_proc_check_wait(td->td_ucred, p))) 1793 return (error); 1794 #endif 1795 #if 0 1796 /* XXXMAC: This could have odd effects on some shells. */ 1797 if ((error = cr_seeotheruids(td->td_ucred, p->p_ucred))) 1798 return (error); 1799 #endif 1800 1801 return (0); 1802 } 1803 1804 /* 1805 * Allocate a zeroed cred structure. 1806 */ 1807 struct ucred * 1808 crget(void) 1809 { 1810 register struct ucred *cr; 1811 1812 cr = malloc(sizeof(*cr), M_CRED, M_WAITOK | M_ZERO); 1813 refcount_init(&cr->cr_ref, 1); 1814 #ifdef AUDIT 1815 audit_cred_init(cr); 1816 #endif 1817 #ifdef MAC 1818 mac_cred_init(cr); 1819 #endif 1820 cr->cr_groups = cr->cr_smallgroups; 1821 cr->cr_agroups = 1822 sizeof(cr->cr_smallgroups) / sizeof(cr->cr_smallgroups[0]); 1823 return (cr); 1824 } 1825 1826 /* 1827 * Claim another reference to a ucred structure. 1828 */ 1829 struct ucred * 1830 crhold(struct ucred *cr) 1831 { 1832 1833 refcount_acquire(&cr->cr_ref); 1834 return (cr); 1835 } 1836 1837 /* 1838 * Free a cred structure. Throws away space when ref count gets to 0. 1839 */ 1840 void 1841 crfree(struct ucred *cr) 1842 { 1843 1844 KASSERT(cr->cr_ref > 0, ("bad ucred refcount: %d", cr->cr_ref)); 1845 KASSERT(cr->cr_ref != 0xdeadc0de, ("dangling reference to ucred")); 1846 if (refcount_release(&cr->cr_ref)) { 1847 /* 1848 * Some callers of crget(), such as nfs_statfs(), 1849 * allocate a temporary credential, but don't 1850 * allocate a uidinfo structure. 1851 */ 1852 if (cr->cr_uidinfo != NULL) 1853 uifree(cr->cr_uidinfo); 1854 if (cr->cr_ruidinfo != NULL) 1855 uifree(cr->cr_ruidinfo); 1856 /* 1857 * Free a prison, if any. 1858 */ 1859 if (cr->cr_prison != NULL) 1860 prison_free(cr->cr_prison); 1861 if (cr->cr_loginclass != NULL) 1862 loginclass_free(cr->cr_loginclass); 1863 #ifdef AUDIT 1864 audit_cred_destroy(cr); 1865 #endif 1866 #ifdef MAC 1867 mac_cred_destroy(cr); 1868 #endif 1869 if (cr->cr_groups != cr->cr_smallgroups) 1870 free(cr->cr_groups, M_CRED); 1871 free(cr, M_CRED); 1872 } 1873 } 1874 1875 /* 1876 * Copy a ucred's contents from a template. Does not block. 1877 */ 1878 void 1879 crcopy(struct ucred *dest, struct ucred *src) 1880 { 1881 1882 KASSERT(dest->cr_ref == 1, ("crcopy of shared ucred")); 1883 bcopy(&src->cr_startcopy, &dest->cr_startcopy, 1884 (unsigned)((caddr_t)&src->cr_endcopy - 1885 (caddr_t)&src->cr_startcopy)); 1886 crsetgroups(dest, src->cr_ngroups, src->cr_groups); 1887 uihold(dest->cr_uidinfo); 1888 uihold(dest->cr_ruidinfo); 1889 prison_hold(dest->cr_prison); 1890 loginclass_hold(dest->cr_loginclass); 1891 #ifdef AUDIT 1892 audit_cred_copy(src, dest); 1893 #endif 1894 #ifdef MAC 1895 mac_cred_copy(src, dest); 1896 #endif 1897 } 1898 1899 /* 1900 * Dup cred struct to a new held one. 1901 */ 1902 struct ucred * 1903 crdup(struct ucred *cr) 1904 { 1905 struct ucred *newcr; 1906 1907 newcr = crget(); 1908 crcopy(newcr, cr); 1909 return (newcr); 1910 } 1911 1912 /* 1913 * Fill in a struct xucred based on a struct ucred. 1914 */ 1915 void 1916 cru2x(struct ucred *cr, struct xucred *xcr) 1917 { 1918 int ngroups; 1919 1920 bzero(xcr, sizeof(*xcr)); 1921 xcr->cr_version = XUCRED_VERSION; 1922 xcr->cr_uid = cr->cr_uid; 1923 1924 ngroups = MIN(cr->cr_ngroups, XU_NGROUPS); 1925 xcr->cr_ngroups = ngroups; 1926 bcopy(cr->cr_groups, xcr->cr_groups, 1927 ngroups * sizeof(*cr->cr_groups)); 1928 } 1929 1930 /* 1931 * small routine to swap a thread's current ucred for the correct one taken 1932 * from the process. 1933 */ 1934 void 1935 cred_update_thread(struct thread *td) 1936 { 1937 struct proc *p; 1938 struct ucred *cred; 1939 1940 p = td->td_proc; 1941 cred = td->td_ucred; 1942 PROC_LOCK(p); 1943 td->td_ucred = crhold(p->p_ucred); 1944 PROC_UNLOCK(p); 1945 if (cred != NULL) 1946 crfree(cred); 1947 } 1948 1949 struct ucred * 1950 crcopysafe(struct proc *p, struct ucred *cr) 1951 { 1952 struct ucred *oldcred; 1953 int groups; 1954 1955 PROC_LOCK_ASSERT(p, MA_OWNED); 1956 1957 oldcred = p->p_ucred; 1958 while (cr->cr_agroups < oldcred->cr_agroups) { 1959 groups = oldcred->cr_agroups; 1960 PROC_UNLOCK(p); 1961 crextend(cr, groups); 1962 PROC_LOCK(p); 1963 oldcred = p->p_ucred; 1964 } 1965 crcopy(cr, oldcred); 1966 1967 return (oldcred); 1968 } 1969 1970 /* 1971 * Extend the passed in credential to hold n items. 1972 */ 1973 static void 1974 crextend(struct ucred *cr, int n) 1975 { 1976 int cnt; 1977 1978 /* Truncate? */ 1979 if (n <= cr->cr_agroups) 1980 return; 1981 1982 /* 1983 * We extend by 2 each time since we're using a power of two 1984 * allocator until we need enough groups to fill a page. 1985 * Once we're allocating multiple pages, only allocate as many 1986 * as we actually need. The case of processes needing a 1987 * non-power of two number of pages seems more likely than 1988 * a real world process that adds thousands of groups one at a 1989 * time. 1990 */ 1991 if ( n < PAGE_SIZE / sizeof(gid_t) ) { 1992 if (cr->cr_agroups == 0) 1993 cnt = MINALLOCSIZE / sizeof(gid_t); 1994 else 1995 cnt = cr->cr_agroups * 2; 1996 1997 while (cnt < n) 1998 cnt *= 2; 1999 } else 2000 cnt = roundup2(n, PAGE_SIZE / sizeof(gid_t)); 2001 2002 /* Free the old array. */ 2003 if (cr->cr_groups != cr->cr_smallgroups) 2004 free(cr->cr_groups, M_CRED); 2005 2006 cr->cr_groups = malloc(cnt * sizeof(gid_t), M_CRED, M_WAITOK | M_ZERO); 2007 cr->cr_agroups = cnt; 2008 } 2009 2010 /* 2011 * Copy groups in to a credential, preserving any necessary invariants. 2012 * Currently this includes the sorting of all supplemental gids. 2013 * crextend() must have been called before hand to ensure sufficient 2014 * space is available. 2015 */ 2016 static void 2017 crsetgroups_locked(struct ucred *cr, int ngrp, gid_t *groups) 2018 { 2019 int i; 2020 int j; 2021 gid_t g; 2022 2023 KASSERT(cr->cr_agroups >= ngrp, ("cr_ngroups is too small")); 2024 2025 bcopy(groups, cr->cr_groups, ngrp * sizeof(gid_t)); 2026 cr->cr_ngroups = ngrp; 2027 2028 /* 2029 * Sort all groups except cr_groups[0] to allow groupmember to 2030 * perform a binary search. 2031 * 2032 * XXX: If large numbers of groups become common this should 2033 * be replaced with shell sort like linux uses or possibly 2034 * heap sort. 2035 */ 2036 for (i = 2; i < ngrp; i++) { 2037 g = cr->cr_groups[i]; 2038 for (j = i-1; j >= 1 && g < cr->cr_groups[j]; j--) 2039 cr->cr_groups[j + 1] = cr->cr_groups[j]; 2040 cr->cr_groups[j + 1] = g; 2041 } 2042 } 2043 2044 /* 2045 * Copy groups in to a credential after expanding it if required. 2046 * Truncate the list to (ngroups_max + 1) if it is too large. 2047 */ 2048 void 2049 crsetgroups(struct ucred *cr, int ngrp, gid_t *groups) 2050 { 2051 2052 if (ngrp > ngroups_max + 1) 2053 ngrp = ngroups_max + 1; 2054 2055 crextend(cr, ngrp); 2056 crsetgroups_locked(cr, ngrp, groups); 2057 } 2058 2059 /* 2060 * Get login name, if available. 2061 */ 2062 #ifndef _SYS_SYSPROTO_H_ 2063 struct getlogin_args { 2064 char *namebuf; 2065 u_int namelen; 2066 }; 2067 #endif 2068 /* ARGSUSED */ 2069 int 2070 sys_getlogin(struct thread *td, struct getlogin_args *uap) 2071 { 2072 char login[MAXLOGNAME]; 2073 struct proc *p = td->td_proc; 2074 size_t len; 2075 2076 if (uap->namelen > MAXLOGNAME) 2077 uap->namelen = MAXLOGNAME; 2078 PROC_LOCK(p); 2079 SESS_LOCK(p->p_session); 2080 len = strlcpy(login, p->p_session->s_login, uap->namelen) + 1; 2081 SESS_UNLOCK(p->p_session); 2082 PROC_UNLOCK(p); 2083 if (len > uap->namelen) 2084 return (ERANGE); 2085 return (copyout(login, uap->namebuf, len)); 2086 } 2087 2088 /* 2089 * Set login name. 2090 */ 2091 #ifndef _SYS_SYSPROTO_H_ 2092 struct setlogin_args { 2093 char *namebuf; 2094 }; 2095 #endif 2096 /* ARGSUSED */ 2097 int 2098 sys_setlogin(struct thread *td, struct setlogin_args *uap) 2099 { 2100 struct proc *p = td->td_proc; 2101 int error; 2102 char logintmp[MAXLOGNAME]; 2103 2104 CTASSERT(sizeof(p->p_session->s_login) >= sizeof(logintmp)); 2105 2106 error = priv_check(td, PRIV_PROC_SETLOGIN); 2107 if (error) 2108 return (error); 2109 error = copyinstr(uap->namebuf, logintmp, sizeof(logintmp), NULL); 2110 if (error != 0) { 2111 if (error == ENAMETOOLONG) 2112 error = EINVAL; 2113 return (error); 2114 } 2115 PROC_LOCK(p); 2116 SESS_LOCK(p->p_session); 2117 strcpy(p->p_session->s_login, logintmp); 2118 SESS_UNLOCK(p->p_session); 2119 PROC_UNLOCK(p); 2120 return (0); 2121 } 2122 2123 void 2124 setsugid(struct proc *p) 2125 { 2126 2127 PROC_LOCK_ASSERT(p, MA_OWNED); 2128 p->p_flag |= P_SUGID; 2129 if (!(p->p_pfsflags & PF_ISUGID)) 2130 p->p_stops = 0; 2131 } 2132 2133 /*- 2134 * Change a process's effective uid. 2135 * Side effects: newcred->cr_uid and newcred->cr_uidinfo will be modified. 2136 * References: newcred must be an exclusive credential reference for the 2137 * duration of the call. 2138 */ 2139 void 2140 change_euid(struct ucred *newcred, struct uidinfo *euip) 2141 { 2142 2143 newcred->cr_uid = euip->ui_uid; 2144 uihold(euip); 2145 uifree(newcred->cr_uidinfo); 2146 newcred->cr_uidinfo = euip; 2147 } 2148 2149 /*- 2150 * Change a process's effective gid. 2151 * Side effects: newcred->cr_gid will be modified. 2152 * References: newcred must be an exclusive credential reference for the 2153 * duration of the call. 2154 */ 2155 void 2156 change_egid(struct ucred *newcred, gid_t egid) 2157 { 2158 2159 newcred->cr_groups[0] = egid; 2160 } 2161 2162 /*- 2163 * Change a process's real uid. 2164 * Side effects: newcred->cr_ruid will be updated, newcred->cr_ruidinfo 2165 * will be updated, and the old and new cr_ruidinfo proc 2166 * counts will be updated. 2167 * References: newcred must be an exclusive credential reference for the 2168 * duration of the call. 2169 */ 2170 void 2171 change_ruid(struct ucred *newcred, struct uidinfo *ruip) 2172 { 2173 2174 (void)chgproccnt(newcred->cr_ruidinfo, -1, 0); 2175 newcred->cr_ruid = ruip->ui_uid; 2176 uihold(ruip); 2177 uifree(newcred->cr_ruidinfo); 2178 newcred->cr_ruidinfo = ruip; 2179 (void)chgproccnt(newcred->cr_ruidinfo, 1, 0); 2180 } 2181 2182 /*- 2183 * Change a process's real gid. 2184 * Side effects: newcred->cr_rgid will be updated. 2185 * References: newcred must be an exclusive credential reference for the 2186 * duration of the call. 2187 */ 2188 void 2189 change_rgid(struct ucred *newcred, gid_t rgid) 2190 { 2191 2192 newcred->cr_rgid = rgid; 2193 } 2194 2195 /*- 2196 * Change a process's saved uid. 2197 * Side effects: newcred->cr_svuid will be updated. 2198 * References: newcred must be an exclusive credential reference for the 2199 * duration of the call. 2200 */ 2201 void 2202 change_svuid(struct ucred *newcred, uid_t svuid) 2203 { 2204 2205 newcred->cr_svuid = svuid; 2206 } 2207 2208 /*- 2209 * Change a process's saved gid. 2210 * Side effects: newcred->cr_svgid will be updated. 2211 * References: newcred must be an exclusive credential reference for the 2212 * duration of the call. 2213 */ 2214 void 2215 change_svgid(struct ucred *newcred, gid_t svgid) 2216 { 2217 2218 newcred->cr_svgid = svgid; 2219 } 2220