1 /* 2 * Copyright (c) 1982, 1986, 1989, 1990, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * (c) UNIX System Laboratories, Inc. 5 * All or some portions of this file are derived from material licensed 6 * to the University of California by American Telephone and Telegraph 7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8 * the permission of UNIX System Laboratories, Inc. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the University of 21 * California, Berkeley and its contributors. 22 * 4. Neither the name of the University nor the names of its contributors 23 * may be used to endorse or promote products derived from this software 24 * without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 * @(#)kern_prot.c 8.6 (Berkeley) 1/21/94 39 * $FreeBSD: src/sys/kern/kern_prot.c,v 1.53.2.9 2002/03/09 05:20:26 dd Exp $ 40 * $DragonFly: src/sys/kern/kern_prot.c,v 1.29 2008/02/16 15:53:39 matthias Exp $ 41 */ 42 43 /* 44 * System calls related to processes and protection 45 */ 46 47 #include "opt_compat.h" 48 49 #include <sys/param.h> 50 #include <sys/acct.h> 51 #include <sys/systm.h> 52 #include <sys/sysproto.h> 53 #include <sys/kernel.h> 54 #include <sys/lock.h> 55 #include <sys/proc.h> 56 #include <sys/priv.h> 57 #include <sys/malloc.h> 58 #include <sys/pioctl.h> 59 #include <sys/resourcevar.h> 60 #include <sys/jail.h> 61 #include <sys/lockf.h> 62 #include <sys/spinlock.h> 63 64 #include <sys/thread2.h> 65 #include <sys/spinlock2.h> 66 67 static MALLOC_DEFINE(M_CRED, "cred", "credentials"); 68 69 /* 70 * MPALMOSTSAFE 71 */ 72 int 73 sys_getpid(struct getpid_args *uap) 74 { 75 struct proc *p = curproc; 76 77 uap->sysmsg_fds[0] = p->p_pid; 78 #if defined(COMPAT_43) || defined(COMPAT_SUNOS) 79 get_mplock(); 80 uap->sysmsg_fds[1] = p->p_pptr->p_pid; 81 rel_mplock(); 82 #endif 83 return (0); 84 } 85 86 /* 87 * MPALMOSTSAFE 88 */ 89 int 90 sys_getppid(struct getppid_args *uap) 91 { 92 struct proc *p = curproc; 93 94 get_mplock(); 95 uap->sysmsg_result = p->p_pptr->p_pid; 96 rel_mplock(); 97 98 return (0); 99 } 100 101 /* 102 * MPSAFE 103 */ 104 int 105 sys_lwp_gettid(struct lwp_gettid_args *uap) 106 { 107 struct lwp *lp = curthread->td_lwp; 108 109 uap->sysmsg_result = lp->lwp_tid; 110 return (0); 111 } 112 113 /* 114 * Get process group ID; note that POSIX getpgrp takes no parameter 115 * 116 * MPSAFE XXX pgrp 117 */ 118 int 119 sys_getpgrp(struct getpgrp_args *uap) 120 { 121 struct proc *p = curproc; 122 123 uap->sysmsg_result = p->p_pgrp->pg_id; 124 return (0); 125 } 126 127 /* 128 * Get an arbitrary pid's process group id 129 * 130 * MPALMOSTSAFE 131 */ 132 int 133 sys_getpgid(struct getpgid_args *uap) 134 { 135 struct proc *p = curproc; 136 struct proc *pt; 137 int error; 138 139 get_mplock(); 140 error = 0; 141 142 if (uap->pid == 0) { 143 pt = p; 144 } else { 145 pt = pfind(uap->pid); 146 if (pt == NULL) 147 error = ESRCH; 148 } 149 if (error == 0) 150 uap->sysmsg_result = pt->p_pgrp->pg_id; 151 rel_mplock(); 152 return (error); 153 } 154 155 /* 156 * Get an arbitrary pid's session id. 157 * 158 * MPALMOSTSAFE 159 */ 160 int 161 sys_getsid(struct getsid_args *uap) 162 { 163 struct proc *p = curproc; 164 struct proc *pt; 165 int error; 166 167 get_mplock(); 168 error = 0; 169 170 if (uap->pid == 0) { 171 pt = p; 172 } else { 173 pt = pfind(uap->pid); 174 if (pt == NULL) 175 error = ESRCH; 176 } 177 if (error == 0) 178 uap->sysmsg_result = pt->p_session->s_sid; 179 rel_mplock(); 180 return (error); 181 } 182 183 184 /* 185 * getuid() 186 * 187 * MPSAFE XXX ucred 188 */ 189 int 190 sys_getuid(struct getuid_args *uap) 191 { 192 struct proc *p = curproc; 193 194 uap->sysmsg_fds[0] = p->p_ucred->cr_ruid; 195 #if defined(COMPAT_43) || defined(COMPAT_SUNOS) 196 uap->sysmsg_fds[1] = p->p_ucred->cr_uid; 197 #endif 198 return (0); 199 } 200 201 /* 202 * geteuid() 203 * 204 * MPSAFE XXX ucred 205 */ 206 int 207 sys_geteuid(struct geteuid_args *uap) 208 { 209 struct proc *p = curproc; 210 211 uap->sysmsg_result = p->p_ucred->cr_uid; 212 return (0); 213 } 214 215 /* 216 * getgid() 217 * 218 * MPSAFE XXX UCRED 219 */ 220 int 221 sys_getgid(struct getgid_args *uap) 222 { 223 struct proc *p = curproc; 224 225 uap->sysmsg_fds[0] = p->p_ucred->cr_rgid; 226 #if defined(COMPAT_43) || defined(COMPAT_SUNOS) 227 uap->sysmsg_fds[1] = p->p_ucred->cr_groups[0]; 228 #endif 229 return (0); 230 } 231 232 /* 233 * Get effective group ID. The "egid" is groups[0], and could be obtained 234 * via getgroups. This syscall exists because it is somewhat painful to do 235 * correctly in a library function. 236 * 237 * MPSAFE 238 */ 239 int 240 sys_getegid(struct getegid_args *uap) 241 { 242 struct proc *p = curproc; 243 244 uap->sysmsg_result = p->p_ucred->cr_groups[0]; 245 return (0); 246 } 247 248 /* 249 * MPSAFE 250 */ 251 int 252 sys_getgroups(struct getgroups_args *uap) 253 { 254 struct proc *p = curproc; 255 struct ucred *cr; 256 u_int ngrp; 257 int error; 258 259 cr = p->p_ucred; 260 if ((ngrp = uap->gidsetsize) == 0) { 261 uap->sysmsg_result = cr->cr_ngroups; 262 return (0); 263 } 264 if (ngrp < cr->cr_ngroups) 265 return (EINVAL); 266 ngrp = cr->cr_ngroups; 267 error = copyout((caddr_t)cr->cr_groups, 268 (caddr_t)uap->gidset, ngrp * sizeof(gid_t)); 269 if (error == 0) 270 uap->sysmsg_result = ngrp; 271 return (error); 272 } 273 274 /* 275 * MPALMOSTSAFE 276 */ 277 int 278 sys_setsid(struct setsid_args *uap) 279 { 280 struct proc *p = curproc; 281 int error; 282 283 get_mplock(); 284 if (p->p_pgid == p->p_pid || pgfind(p->p_pid)) { 285 error = EPERM; 286 } else { 287 enterpgrp(p, p->p_pid, 1); 288 uap->sysmsg_result = p->p_pid; 289 error = 0; 290 } 291 rel_mplock(); 292 return (error); 293 } 294 295 /* 296 * set process group (setpgid/old setpgrp) 297 * 298 * caller does setpgid(targpid, targpgid) 299 * 300 * pid must be caller or child of caller (ESRCH) 301 * if a child 302 * pid must be in same session (EPERM) 303 * pid can't have done an exec (EACCES) 304 * if pgid != pid 305 * there must exist some pid in same session having pgid (EPERM) 306 * pid must not be session leader (EPERM) 307 * 308 * MPALMOSTSAFE 309 */ 310 int 311 sys_setpgid(struct setpgid_args *uap) 312 { 313 struct proc *curp = curproc; 314 struct proc *targp; /* target process */ 315 struct pgrp *pgrp; /* target pgrp */ 316 int error; 317 318 if (uap->pgid < 0) 319 return (EINVAL); 320 321 get_mplock(); 322 if (uap->pid != 0 && uap->pid != curp->p_pid) { 323 if ((targp = pfind(uap->pid)) == 0 || !inferior(targp)) { 324 error = ESRCH; 325 goto done; 326 } 327 if (targp->p_pgrp == NULL || 328 targp->p_session != curp->p_session) { 329 error = EPERM; 330 goto done; 331 } 332 if (targp->p_flag & P_EXEC) { 333 error = EACCES; 334 goto done; 335 } 336 } else { 337 targp = curp; 338 } 339 if (SESS_LEADER(targp)) { 340 error = EPERM; 341 goto done; 342 } 343 if (uap->pgid == 0) { 344 uap->pgid = targp->p_pid; 345 } else if (uap->pgid != targp->p_pid) { 346 if ((pgrp = pgfind(uap->pgid)) == 0 || 347 pgrp->pg_session != curp->p_session) { 348 error = EPERM; 349 goto done; 350 } 351 } 352 error = enterpgrp(targp, uap->pgid, 0); 353 done: 354 rel_mplock(); 355 return (error); 356 } 357 358 /* 359 * Use the clause in B.4.2.2 that allows setuid/setgid to be 4.2/4.3BSD 360 * compatible. It says that setting the uid/gid to euid/egid is a special 361 * case of "appropriate privilege". Once the rules are expanded out, this 362 * basically means that setuid(nnn) sets all three id's, in all permitted 363 * cases unless _POSIX_SAVED_IDS is enabled. In that case, setuid(getuid()) 364 * does not set the saved id - this is dangerous for traditional BSD 365 * programs. For this reason, we *really* do not want to set 366 * _POSIX_SAVED_IDS and do not want to clear POSIX_APPENDIX_B_4_2_2. 367 */ 368 #define POSIX_APPENDIX_B_4_2_2 369 370 /* 371 * MPALMOSTSAFE 372 */ 373 int 374 sys_setuid(struct setuid_args *uap) 375 { 376 struct proc *p = curproc; 377 struct ucred *cr; 378 uid_t uid; 379 int error; 380 381 get_mplock(); 382 cr = p->p_ucred; 383 384 /* 385 * See if we have "permission" by POSIX 1003.1 rules. 386 * 387 * Note that setuid(geteuid()) is a special case of 388 * "appropriate privileges" in appendix B.4.2.2. We need 389 * to use this clause to be compatible with traditional BSD 390 * semantics. Basically, it means that "setuid(xx)" sets all 391 * three id's (assuming you have privs). 392 * 393 * Notes on the logic. We do things in three steps. 394 * 1: We determine if the euid is going to change, and do EPERM 395 * right away. We unconditionally change the euid later if this 396 * test is satisfied, simplifying that part of the logic. 397 * 2: We determine if the real and/or saved uid's are going to 398 * change. Determined by compile options. 399 * 3: Change euid last. (after tests in #2 for "appropriate privs") 400 */ 401 uid = uap->uid; 402 if (uid != cr->cr_ruid && /* allow setuid(getuid()) */ 403 #ifdef _POSIX_SAVED_IDS 404 uid != crc->cr_svuid && /* allow setuid(saved gid) */ 405 #endif 406 #ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */ 407 uid != cr->cr_uid && /* allow setuid(geteuid()) */ 408 #endif 409 (error = priv_check_cred(cr, PRIV_CRED_SETUID, 0))) 410 goto done; 411 412 #ifdef _POSIX_SAVED_IDS 413 /* 414 * Do we have "appropriate privileges" (are we root or uid == euid) 415 * If so, we are changing the real uid and/or saved uid. 416 */ 417 if ( 418 #ifdef POSIX_APPENDIX_B_4_2_2 /* Use the clause from B.4.2.2 */ 419 uid == cr->cr_uid || 420 #endif 421 priv_check_cred(cr, PRIV_CRED_SETUID, 0) == 0) /* we are using privs */ 422 #endif 423 { 424 /* 425 * Set the real uid and transfer proc count to new user. 426 */ 427 if (uid != cr->cr_ruid) { 428 cr = change_ruid(uid); 429 setsugid(); 430 } 431 /* 432 * Set saved uid 433 * 434 * XXX always set saved uid even if not _POSIX_SAVED_IDS, as 435 * the security of seteuid() depends on it. B.4.2.2 says it 436 * is important that we should do this. 437 */ 438 if (cr->cr_svuid != uid) { 439 cr = cratom(&p->p_ucred); 440 cr->cr_svuid = uid; 441 setsugid(); 442 } 443 } 444 445 /* 446 * In all permitted cases, we are changing the euid. 447 * Copy credentials so other references do not see our changes. 448 */ 449 if (cr->cr_uid != uid) { 450 change_euid(uid); 451 setsugid(); 452 } 453 error = 0; 454 done: 455 rel_mplock(); 456 return (error); 457 } 458 459 /* 460 * MPALMOSTSAFE 461 */ 462 int 463 sys_seteuid(struct seteuid_args *uap) 464 { 465 struct proc *p = curproc; 466 struct ucred *cr; 467 uid_t euid; 468 int error; 469 470 cr = p->p_ucred; 471 euid = uap->euid; 472 if (euid != cr->cr_ruid && /* allow seteuid(getuid()) */ 473 euid != cr->cr_svuid && /* allow seteuid(saved uid) */ 474 (error = priv_check_cred(cr, PRIV_CRED_SETEUID, 0))) { 475 return (error); 476 } 477 478 /* 479 * Everything's okay, do it. Copy credentials so other references do 480 * not see our changes. 481 */ 482 if (cr->cr_uid != euid) { 483 get_mplock(); 484 change_euid(euid); 485 setsugid(); 486 rel_mplock(); 487 } 488 return (0); 489 } 490 491 /* 492 * MPALMOSTSAFE 493 */ 494 int 495 sys_setgid(struct setgid_args *uap) 496 { 497 struct proc *p = curproc; 498 struct ucred *cr; 499 gid_t gid; 500 int error; 501 502 get_mplock(); 503 cr = p->p_ucred; 504 505 /* 506 * See if we have "permission" by POSIX 1003.1 rules. 507 * 508 * Note that setgid(getegid()) is a special case of 509 * "appropriate privileges" in appendix B.4.2.2. We need 510 * to use this clause to be compatible with traditional BSD 511 * semantics. Basically, it means that "setgid(xx)" sets all 512 * three id's (assuming you have privs). 513 * 514 * For notes on the logic here, see setuid() above. 515 */ 516 gid = uap->gid; 517 if (gid != cr->cr_rgid && /* allow setgid(getgid()) */ 518 #ifdef _POSIX_SAVED_IDS 519 gid != cr->cr_svgid && /* allow setgid(saved gid) */ 520 #endif 521 #ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */ 522 gid != cr->cr_groups[0] && /* allow setgid(getegid()) */ 523 #endif 524 (error = priv_check_cred(cr, PRIV_CRED_SETGID, 0))) { 525 goto done; 526 } 527 528 #ifdef _POSIX_SAVED_IDS 529 /* 530 * Do we have "appropriate privileges" (are we root or gid == egid) 531 * If so, we are changing the real uid and saved gid. 532 */ 533 if ( 534 #ifdef POSIX_APPENDIX_B_4_2_2 /* use the clause from B.4.2.2 */ 535 gid == cr->cr_groups[0] || 536 #endif 537 priv_check_cred(cr, PRIV_CRED_SETGID, 0) == 0) /* we are using privs */ 538 #endif 539 { 540 /* 541 * Set real gid 542 */ 543 if (cr->cr_rgid != gid) { 544 cr = cratom(&p->p_ucred); 545 cr->cr_rgid = gid; 546 setsugid(); 547 } 548 /* 549 * Set saved gid 550 * 551 * XXX always set saved gid even if not _POSIX_SAVED_IDS, as 552 * the security of setegid() depends on it. B.4.2.2 says it 553 * is important that we should do this. 554 */ 555 if (cr->cr_svgid != gid) { 556 cr = cratom(&p->p_ucred); 557 cr->cr_svgid = gid; 558 setsugid(); 559 } 560 } 561 /* 562 * In all cases permitted cases, we are changing the egid. 563 * Copy credentials so other references do not see our changes. 564 */ 565 if (cr->cr_groups[0] != gid) { 566 cr = cratom(&p->p_ucred); 567 cr->cr_groups[0] = gid; 568 setsugid(); 569 } 570 error = 0; 571 done: 572 rel_mplock(); 573 return (error); 574 } 575 576 /* 577 * MPALMOSTSAFE 578 */ 579 int 580 sys_setegid(struct setegid_args *uap) 581 { 582 struct proc *p = curproc; 583 struct ucred *cr; 584 gid_t egid; 585 int error; 586 587 get_mplock(); 588 cr = p->p_ucred; 589 egid = uap->egid; 590 if (egid != cr->cr_rgid && /* allow setegid(getgid()) */ 591 egid != cr->cr_svgid && /* allow setegid(saved gid) */ 592 (error = priv_check_cred(cr, PRIV_CRED_SETEGID, 0))) { 593 goto done; 594 } 595 if (cr->cr_groups[0] != egid) { 596 cr = cratom(&p->p_ucred); 597 cr->cr_groups[0] = egid; 598 setsugid(); 599 } 600 error = 0; 601 done: 602 rel_mplock(); 603 return (error); 604 } 605 606 /* 607 * MPALMOSTSAFE 608 */ 609 int 610 sys_setgroups(struct setgroups_args *uap) 611 { 612 struct proc *p = curproc; 613 struct ucred *cr; 614 u_int ngrp; 615 int error; 616 617 get_mplock(); 618 cr = p->p_ucred; 619 620 if ((error = priv_check_cred(cr, PRIV_CRED_SETGROUPS, 0))) 621 goto done; 622 ngrp = uap->gidsetsize; 623 if (ngrp > NGROUPS) { 624 error = EINVAL; 625 goto done; 626 } 627 /* 628 * XXX A little bit lazy here. We could test if anything has 629 * changed before cratom() and setting P_SUGID. 630 */ 631 cr = cratom(&p->p_ucred); 632 if (ngrp < 1) { 633 /* 634 * setgroups(0, NULL) is a legitimate way of clearing the 635 * groups vector on non-BSD systems (which generally do not 636 * have the egid in the groups[0]). We risk security holes 637 * when running non-BSD software if we do not do the same. 638 */ 639 cr->cr_ngroups = 1; 640 } else { 641 error = copyin(uap->gidset, cr->cr_groups, 642 ngrp * sizeof(gid_t)); 643 if (error) 644 goto done; 645 cr->cr_ngroups = ngrp; 646 } 647 setsugid(); 648 error = 0; 649 done: 650 rel_mplock(); 651 return (error); 652 } 653 654 /* 655 * MPALMOSTSAFE 656 */ 657 int 658 sys_setreuid(struct setreuid_args *uap) 659 { 660 struct proc *p = curproc; 661 struct ucred *cr; 662 uid_t ruid, euid; 663 int error; 664 665 get_mplock(); 666 cr = p->p_ucred; 667 668 ruid = uap->ruid; 669 euid = uap->euid; 670 if (((ruid != (uid_t)-1 && ruid != cr->cr_ruid && ruid != cr->cr_svuid) || 671 (euid != (uid_t)-1 && euid != cr->cr_uid && 672 euid != cr->cr_ruid && euid != cr->cr_svuid)) && 673 (error = priv_check_cred(cr, PRIV_CRED_SETREUID, 0)) != 0) { 674 goto done; 675 } 676 677 if (euid != (uid_t)-1 && cr->cr_uid != euid) { 678 cr = change_euid(euid); 679 setsugid(); 680 } 681 if (ruid != (uid_t)-1 && cr->cr_ruid != ruid) { 682 cr = change_ruid(ruid); 683 setsugid(); 684 } 685 if ((ruid != (uid_t)-1 || cr->cr_uid != cr->cr_ruid) && 686 cr->cr_svuid != cr->cr_uid) { 687 cr = cratom(&p->p_ucred); 688 cr->cr_svuid = cr->cr_uid; 689 setsugid(); 690 } 691 error = 0; 692 done: 693 rel_mplock(); 694 return (error); 695 } 696 697 /* 698 * MPALMOSTSAFE 699 */ 700 int 701 sys_setregid(struct setregid_args *uap) 702 { 703 struct proc *p = curproc; 704 struct ucred *cr; 705 gid_t rgid, egid; 706 int error; 707 708 get_mplock(); 709 cr = p->p_ucred; 710 711 rgid = uap->rgid; 712 egid = uap->egid; 713 if (((rgid != (gid_t)-1 && rgid != cr->cr_rgid && rgid != cr->cr_svgid) || 714 (egid != (gid_t)-1 && egid != cr->cr_groups[0] && 715 egid != cr->cr_rgid && egid != cr->cr_svgid)) && 716 (error = priv_check_cred(cr, PRIV_CRED_SETREGID, 0)) != 0) { 717 goto done; 718 } 719 720 if (egid != (gid_t)-1 && cr->cr_groups[0] != egid) { 721 cr = cratom(&p->p_ucred); 722 cr->cr_groups[0] = egid; 723 setsugid(); 724 } 725 if (rgid != (gid_t)-1 && cr->cr_rgid != rgid) { 726 cr = cratom(&p->p_ucred); 727 cr->cr_rgid = rgid; 728 setsugid(); 729 } 730 if ((rgid != (gid_t)-1 || cr->cr_groups[0] != cr->cr_rgid) && 731 cr->cr_svgid != cr->cr_groups[0]) { 732 cr = cratom(&p->p_ucred); 733 cr->cr_svgid = cr->cr_groups[0]; 734 setsugid(); 735 } 736 error = 0; 737 done: 738 rel_mplock(); 739 return (error); 740 } 741 742 /* 743 * setresuid(ruid, euid, suid) is like setreuid except control over the 744 * saved uid is explicit. 745 * 746 * MPALMOSTSAFE 747 */ 748 int 749 sys_setresuid(struct setresuid_args *uap) 750 { 751 struct proc *p = curproc; 752 struct ucred *cr; 753 uid_t ruid, euid, suid; 754 int error; 755 756 get_mplock(); 757 cr = p->p_ucred; 758 759 ruid = uap->ruid; 760 euid = uap->euid; 761 suid = uap->suid; 762 if (((ruid != (uid_t)-1 && ruid != cr->cr_ruid && ruid != cr->cr_svuid && 763 ruid != cr->cr_uid) || 764 (euid != (uid_t)-1 && euid != cr->cr_ruid && euid != cr->cr_svuid && 765 euid != cr->cr_uid) || 766 (suid != (uid_t)-1 && suid != cr->cr_ruid && suid != cr->cr_svuid && 767 suid != cr->cr_uid)) && 768 (error = priv_check_cred(cr, PRIV_CRED_SETRESUID, 0)) != 0) { 769 goto done; 770 } 771 if (euid != (uid_t)-1 && cr->cr_uid != euid) { 772 cr = change_euid(euid); 773 setsugid(); 774 } 775 if (ruid != (uid_t)-1 && cr->cr_ruid != ruid) { 776 cr = change_ruid(ruid); 777 setsugid(); 778 } 779 if (suid != (uid_t)-1 && cr->cr_svuid != suid) { 780 cr = cratom(&p->p_ucred); 781 cr->cr_svuid = suid; 782 setsugid(); 783 } 784 error = 0; 785 done: 786 rel_mplock(); 787 return (error); 788 } 789 790 /* 791 * setresgid(rgid, egid, sgid) is like setregid except control over the 792 * saved gid is explicit. 793 * 794 * MPALMOSTSAFE 795 */ 796 int 797 sys_setresgid(struct setresgid_args *uap) 798 { 799 struct proc *p = curproc; 800 struct ucred *cr; 801 gid_t rgid, egid, sgid; 802 int error; 803 804 get_mplock(); 805 cr = p->p_ucred; 806 rgid = uap->rgid; 807 egid = uap->egid; 808 sgid = uap->sgid; 809 if (((rgid != (gid_t)-1 && rgid != cr->cr_rgid && rgid != cr->cr_svgid && 810 rgid != cr->cr_groups[0]) || 811 (egid != (gid_t)-1 && egid != cr->cr_rgid && egid != cr->cr_svgid && 812 egid != cr->cr_groups[0]) || 813 (sgid != (gid_t)-1 && sgid != cr->cr_rgid && sgid != cr->cr_svgid && 814 sgid != cr->cr_groups[0])) && 815 (error = priv_check_cred(cr, PRIV_CRED_SETRESGID, 0)) != 0) { 816 goto done; 817 } 818 819 if (egid != (gid_t)-1 && cr->cr_groups[0] != egid) { 820 cr = cratom(&p->p_ucred); 821 cr->cr_groups[0] = egid; 822 setsugid(); 823 } 824 if (rgid != (gid_t)-1 && cr->cr_rgid != rgid) { 825 cr = cratom(&p->p_ucred); 826 cr->cr_rgid = rgid; 827 setsugid(); 828 } 829 if (sgid != (gid_t)-1 && cr->cr_svgid != sgid) { 830 cr = cratom(&p->p_ucred); 831 cr->cr_svgid = sgid; 832 setsugid(); 833 } 834 error = 0; 835 done: 836 rel_mplock(); 837 return (error); 838 } 839 840 /* 841 * MPALMOSTSAFE 842 */ 843 int 844 sys_getresuid(struct getresuid_args *uap) 845 { 846 struct proc *p = curproc; 847 struct ucred *cr; 848 int error1 = 0, error2 = 0, error3 = 0; 849 850 get_mplock(); 851 cr = p->p_ucred; 852 if (uap->ruid) 853 error1 = copyout((caddr_t)&cr->cr_ruid, 854 (caddr_t)uap->ruid, sizeof(cr->cr_ruid)); 855 if (uap->euid) 856 error2 = copyout((caddr_t)&cr->cr_uid, 857 (caddr_t)uap->euid, sizeof(cr->cr_uid)); 858 if (uap->suid) 859 error3 = copyout((caddr_t)&cr->cr_svuid, 860 (caddr_t)uap->suid, sizeof(cr->cr_svuid)); 861 rel_mplock(); 862 return error1 ? error1 : (error2 ? error2 : error3); 863 } 864 865 /* 866 * MPALMOSTSAFE 867 */ 868 int 869 sys_getresgid(struct getresgid_args *uap) 870 { 871 struct proc *p = curproc; 872 struct ucred *cr; 873 int error1 = 0, error2 = 0, error3 = 0; 874 875 get_mplock(); 876 cr = p->p_ucred; 877 if (uap->rgid) 878 error1 = copyout((caddr_t)&cr->cr_rgid, 879 (caddr_t)uap->rgid, sizeof(cr->cr_rgid)); 880 if (uap->egid) 881 error2 = copyout((caddr_t)&cr->cr_groups[0], 882 (caddr_t)uap->egid, sizeof(cr->cr_groups[0])); 883 if (uap->sgid) 884 error3 = copyout((caddr_t)&cr->cr_svgid, 885 (caddr_t)uap->sgid, sizeof(cr->cr_svgid)); 886 rel_mplock(); 887 return error1 ? error1 : (error2 ? error2 : error3); 888 } 889 890 891 /* 892 * NOTE: OpenBSD sets a P_SUGIDEXEC flag set at execve() time, 893 * we use P_SUGID because we consider changing the owners as 894 * "tainting" as well. 895 * This is significant for procs that start as root and "become" 896 * a user without an exec - programs cannot know *everything* 897 * that libc *might* have put in their data segment. 898 * 899 * MPSAFE 900 */ 901 int 902 sys_issetugid(struct issetugid_args *uap) 903 { 904 uap->sysmsg_result = (curproc->p_flag & P_SUGID) ? 1 : 0; 905 return (0); 906 } 907 908 /* 909 * Check if gid is a member of the group set. 910 */ 911 int 912 groupmember(gid_t gid, struct ucred *cred) 913 { 914 gid_t *gp; 915 gid_t *egp; 916 917 egp = &(cred->cr_groups[cred->cr_ngroups]); 918 for (gp = cred->cr_groups; gp < egp; gp++) { 919 if (*gp == gid) 920 return (1); 921 } 922 return (0); 923 } 924 925 /* 926 * Test whether the specified credentials have the privilege 927 * in question. 928 * 929 * A kernel thread without a process context is assumed to have 930 * the privilege in question. In situations where the caller always 931 * expect a cred to exist, the cred should be passed separately and 932 * priv_check_cred() should be used instead of priv_check(). 933 * 934 * Returns 0 or error. 935 * 936 * MPSAFE 937 */ 938 int 939 priv_check(struct thread *td, int priv) 940 { 941 struct proc *p = td->td_proc; 942 943 if (p != NULL) { 944 return priv_check_cred(p->p_ucred, priv, 0); 945 } else { 946 return (0); 947 } 948 } 949 950 /* 951 * Check a credential for privilege. 952 * 953 * A non-null credential is expected unless NULL_CRED_OKAY is set. 954 * 955 * MPSAFE 956 */ 957 int 958 priv_check_cred(struct ucred *cred, int priv, int flags) 959 { 960 int error; 961 962 KASSERT(PRIV_VALID(priv), ("priv_check_cred: invalid privilege")); 963 964 KASSERT(cred != NULL || flags & NULL_CRED_OKAY, 965 ("priv_check_cred: NULL cred!")); 966 967 if (cred == NULL) { 968 if (flags & NULL_CRED_OKAY) 969 return (0); 970 else 971 return (EPERM); 972 } 973 if (cred->cr_uid != 0) 974 return (EPERM); 975 976 error = prison_priv_check(cred, priv); 977 if (error) 978 return (error); 979 980 /* NOTE: accounting for suser access (p_acflag/ASU) removed */ 981 return (0); 982 } 983 984 /* 985 * Return zero if p1 can fondle p2, return errno (EPERM/ESRCH) otherwise. 986 */ 987 int 988 p_trespass(struct ucred *cr1, struct ucred *cr2) 989 { 990 if (cr1 == cr2) 991 return (0); 992 if (!PRISON_CHECK(cr1, cr2)) 993 return (ESRCH); 994 if (cr1->cr_ruid == cr2->cr_ruid) 995 return (0); 996 if (cr1->cr_uid == cr2->cr_ruid) 997 return (0); 998 if (cr1->cr_ruid == cr2->cr_uid) 999 return (0); 1000 if (cr1->cr_uid == cr2->cr_uid) 1001 return (0); 1002 if (priv_check_cred(cr1, PRIV_PROC_TRESPASS, 0) == 0) 1003 return (0); 1004 return (EPERM); 1005 } 1006 1007 /* 1008 * MPSAFE 1009 */ 1010 static __inline void 1011 _crinit(struct ucred *cr) 1012 { 1013 cr->cr_ref = 1; 1014 spin_init(&cr->cr_spin); 1015 } 1016 1017 /* 1018 * MPSAFE 1019 */ 1020 void 1021 crinit(struct ucred *cr) 1022 { 1023 bzero(cr, sizeof(*cr)); 1024 _crinit(cr); 1025 } 1026 1027 /* 1028 * Allocate a zeroed cred structure. 1029 * 1030 * MPSAFE 1031 */ 1032 struct ucred * 1033 crget(void) 1034 { 1035 struct ucred *cr; 1036 1037 cr = kmalloc(sizeof(*cr), M_CRED, M_WAITOK|M_ZERO); 1038 _crinit(cr); 1039 return (cr); 1040 } 1041 1042 /* 1043 * Claim another reference to a ucred structure. Can be used with special 1044 * creds. 1045 * 1046 * It must be possible to call this routine with spinlocks held, meaning 1047 * that this routine itself cannot obtain a spinlock. 1048 * 1049 * MPSAFE 1050 */ 1051 struct ucred * 1052 crhold(struct ucred *cr) 1053 { 1054 if (cr != NOCRED && cr != FSCRED) 1055 atomic_add_int(&cr->cr_ref, 1); 1056 return(cr); 1057 } 1058 1059 /* 1060 * Drop a reference from the cred structure, free it if the reference count 1061 * reaches 0. 1062 * 1063 * NOTE: because we used atomic_add_int() above, without a spinlock, we 1064 * must also use atomic_subtract_int() below. A spinlock is required 1065 * in crfree() to handle multiple callers racing the refcount to 0. 1066 * 1067 * MPALMOSTSAFE - acquires mplock on 1->0 transition of ref count 1068 */ 1069 void 1070 crfree(struct ucred *cr) 1071 { 1072 if (cr->cr_ref <= 0) 1073 panic("Freeing already free credential! %p", cr); 1074 spin_lock_wr(&cr->cr_spin); 1075 atomic_subtract_int(&cr->cr_ref, 1); 1076 if (cr->cr_ref == 0) { 1077 spin_unlock_wr(&cr->cr_spin); 1078 /* 1079 * Some callers of crget(), such as nfs_statfs(), 1080 * allocate a temporary credential, but don't 1081 * allocate a uidinfo structure. 1082 */ 1083 get_mplock(); 1084 if (cr->cr_uidinfo != NULL) { 1085 uidrop(cr->cr_uidinfo); 1086 cr->cr_uidinfo = NULL; 1087 } 1088 if (cr->cr_ruidinfo != NULL) { 1089 uidrop(cr->cr_ruidinfo); 1090 cr->cr_ruidinfo = NULL; 1091 } 1092 1093 /* 1094 * Destroy empty prisons 1095 */ 1096 if (jailed(cr)) 1097 prison_free(cr->cr_prison); 1098 cr->cr_prison = NULL; /* safety */ 1099 1100 FREE((caddr_t)cr, M_CRED); 1101 rel_mplock(); 1102 } else { 1103 spin_unlock_wr(&cr->cr_spin); 1104 } 1105 } 1106 1107 /* 1108 * Atomize a cred structure so it can be modified without polluting 1109 * other references to it. 1110 */ 1111 struct ucred * 1112 cratom(struct ucred **pcr) 1113 { 1114 struct ucred *oldcr; 1115 struct ucred *newcr; 1116 1117 oldcr = *pcr; 1118 if (oldcr->cr_ref == 1) 1119 return (oldcr); 1120 newcr = crget(); 1121 *newcr = *oldcr; 1122 if (newcr->cr_uidinfo) 1123 uihold(newcr->cr_uidinfo); 1124 if (newcr->cr_ruidinfo) 1125 uihold(newcr->cr_ruidinfo); 1126 if (jailed(newcr)) 1127 prison_hold(newcr->cr_prison); 1128 newcr->cr_ref = 1; 1129 crfree(oldcr); 1130 *pcr = newcr; 1131 return (newcr); 1132 } 1133 1134 #if 0 /* no longer used but keep around for a little while */ 1135 /* 1136 * Copy cred structure to a new one and free the old one. 1137 */ 1138 struct ucred * 1139 crcopy(struct ucred *cr) 1140 { 1141 struct ucred *newcr; 1142 1143 if (cr->cr_ref == 1) 1144 return (cr); 1145 newcr = crget(); 1146 *newcr = *cr; 1147 if (newcr->cr_uidinfo) 1148 uihold(newcr->cr_uidinfo); 1149 if (newcr->cr_ruidinfo) 1150 uihold(newcr->cr_ruidinfo); 1151 if (jailed(newcr)) 1152 prison_hold(newcr->cr_prison); 1153 newcr->cr_ref = 1; 1154 crfree(cr); 1155 return (newcr); 1156 } 1157 #endif 1158 1159 /* 1160 * Dup cred struct to a new held one. 1161 */ 1162 struct ucred * 1163 crdup(struct ucred *cr) 1164 { 1165 struct ucred *newcr; 1166 1167 newcr = crget(); 1168 *newcr = *cr; 1169 if (newcr->cr_uidinfo) 1170 uihold(newcr->cr_uidinfo); 1171 if (newcr->cr_ruidinfo) 1172 uihold(newcr->cr_ruidinfo); 1173 if (jailed(newcr)) 1174 prison_hold(newcr->cr_prison); 1175 newcr->cr_ref = 1; 1176 return (newcr); 1177 } 1178 1179 /* 1180 * Fill in a struct xucred based on a struct ucred. 1181 */ 1182 void 1183 cru2x(struct ucred *cr, struct xucred *xcr) 1184 { 1185 1186 bzero(xcr, sizeof(*xcr)); 1187 xcr->cr_version = XUCRED_VERSION; 1188 xcr->cr_uid = cr->cr_uid; 1189 xcr->cr_ngroups = cr->cr_ngroups; 1190 bcopy(cr->cr_groups, xcr->cr_groups, sizeof(cr->cr_groups)); 1191 } 1192 1193 /* 1194 * Get login name, if available. 1195 * 1196 * MPALMOSTSAFE 1197 */ 1198 int 1199 sys_getlogin(struct getlogin_args *uap) 1200 { 1201 struct proc *p = curproc; 1202 char buf[MAXLOGNAME]; 1203 int error; 1204 1205 if (uap->namelen > MAXLOGNAME) /* namelen is unsigned */ 1206 uap->namelen = MAXLOGNAME; 1207 get_mplock(); 1208 bzero(buf, sizeof(buf)); 1209 bcopy(p->p_pgrp->pg_session->s_login, buf, uap->namelen); 1210 rel_mplock(); 1211 1212 error = copyout(buf, uap->namebuf, uap->namelen); 1213 return (error); 1214 } 1215 1216 /* 1217 * Set login name. 1218 * 1219 * MPALMOSTSAFE 1220 */ 1221 int 1222 sys_setlogin(struct setlogin_args *uap) 1223 { 1224 struct proc *p = curproc; 1225 char buf[MAXLOGNAME]; 1226 int error; 1227 1228 KKASSERT(p != NULL); 1229 if ((error = priv_check_cred(p->p_ucred, PRIV_PROC_SETLOGIN, 0))) 1230 return (error); 1231 bzero(buf, sizeof(buf)); 1232 error = copyinstr(uap->namebuf, buf, sizeof(buf), NULL); 1233 if (error == ENAMETOOLONG) 1234 error = EINVAL; 1235 if (error == 0) { 1236 get_mplock(); 1237 memcpy(p->p_pgrp->pg_session->s_login, buf, sizeof(buf)); 1238 rel_mplock(); 1239 } 1240 return (error); 1241 } 1242 1243 void 1244 setsugid(void) 1245 { 1246 struct proc *p = curproc; 1247 1248 KKASSERT(p != NULL); 1249 p->p_flag |= P_SUGID; 1250 if (!(p->p_pfsflags & PF_ISUGID)) 1251 p->p_stops = 0; 1252 } 1253 1254 /* 1255 * Helper function to change the effective uid of a process 1256 */ 1257 struct ucred * 1258 change_euid(uid_t euid) 1259 { 1260 struct proc *p = curproc; 1261 struct ucred *cr; 1262 1263 KKASSERT(p != NULL); 1264 lf_count_adjust(p, 0); 1265 cr = cratom(&p->p_ucred); 1266 cr->cr_uid = euid; 1267 uireplace(&cr->cr_uidinfo, uifind(euid)); 1268 lf_count_adjust(p, 1); 1269 return (cr); 1270 } 1271 1272 /* 1273 * Helper function to change the real uid of a process 1274 * 1275 * The per-uid process count for this process is transfered from 1276 * the old uid to the new uid. 1277 */ 1278 struct ucred * 1279 change_ruid(uid_t ruid) 1280 { 1281 struct proc *p = curproc; 1282 struct ucred *cr; 1283 1284 KKASSERT(p != NULL); 1285 1286 cr = cratom(&p->p_ucred); 1287 chgproccnt(cr->cr_ruidinfo, -1, 0); 1288 cr->cr_ruid = ruid; 1289 uireplace(&cr->cr_ruidinfo, uifind(ruid)); 1290 chgproccnt(cr->cr_ruidinfo, 1, 0); 1291 return (cr); 1292 } 1293