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