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