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