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