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