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