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