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