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