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