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