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