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