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