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_proc(p); 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_proc(p); 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_proc(p); 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_proc(p); 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_proc(p); 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_proc(p); 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 && 639 ruid != cr->cr_svuid) || 640 (euid != (uid_t)-1 && euid != cr->cr_uid && 641 euid != cr->cr_ruid && euid != cr->cr_svuid)) && 642 (error = priv_check_cred(cr, PRIV_CRED_SETREUID, 0)) != 0) { 643 goto done; 644 } 645 646 if (euid != (uid_t)-1 && cr->cr_uid != euid) { 647 cr = change_euid(euid); 648 setsugid(); 649 } 650 if (ruid != (uid_t)-1 && cr->cr_ruid != ruid) { 651 cr = change_ruid(ruid); 652 setsugid(); 653 } 654 if ((ruid != (uid_t)-1 || cr->cr_uid != cr->cr_ruid) && 655 cr->cr_svuid != cr->cr_uid) { 656 cr = cratom_proc(p); 657 cr->cr_svuid = cr->cr_uid; 658 setsugid(); 659 } 660 error = 0; 661 done: 662 lwkt_reltoken(&p->p_token); 663 return (error); 664 } 665 666 int 667 sys_setregid(struct setregid_args *uap) 668 { 669 struct proc *p = curproc; 670 struct ucred *cr; 671 gid_t rgid, egid; 672 int error; 673 674 lwkt_gettoken(&p->p_token); 675 cr = p->p_ucred; 676 677 rgid = uap->rgid; 678 egid = uap->egid; 679 if (((rgid != (gid_t)-1 && rgid != cr->cr_rgid && 680 rgid != cr->cr_svgid) || 681 (egid != (gid_t)-1 && egid != cr->cr_groups[0] && 682 egid != cr->cr_rgid && egid != cr->cr_svgid)) && 683 (error = priv_check_cred(cr, PRIV_CRED_SETREGID, 0)) != 0) { 684 goto done; 685 } 686 687 if (egid != (gid_t)-1 && cr->cr_groups[0] != egid) { 688 cr = cratom_proc(p); 689 cr->cr_groups[0] = egid; 690 setsugid(); 691 } 692 if (rgid != (gid_t)-1 && cr->cr_rgid != rgid) { 693 cr = cratom_proc(p); 694 cr->cr_rgid = rgid; 695 setsugid(); 696 } 697 if ((rgid != (gid_t)-1 || cr->cr_groups[0] != cr->cr_rgid) && 698 cr->cr_svgid != cr->cr_groups[0]) { 699 cr = cratom_proc(p); 700 cr->cr_svgid = cr->cr_groups[0]; 701 setsugid(); 702 } 703 error = 0; 704 done: 705 lwkt_reltoken(&p->p_token); 706 return (error); 707 } 708 709 /* 710 * setresuid(ruid, euid, suid) is like setreuid except control over the 711 * saved uid is explicit. 712 */ 713 int 714 sys_setresuid(struct setresuid_args *uap) 715 { 716 struct proc *p = curproc; 717 struct ucred *cr; 718 uid_t ruid, euid, suid; 719 int error; 720 721 lwkt_gettoken(&p->p_token); 722 cr = p->p_ucred; 723 724 ruid = uap->ruid; 725 euid = uap->euid; 726 suid = uap->suid; 727 if (((ruid != (uid_t)-1 && ruid != cr->cr_ruid && 728 ruid != cr->cr_svuid && ruid != cr->cr_uid) || 729 (euid != (uid_t)-1 && euid != cr->cr_ruid && 730 euid != cr->cr_svuid && euid != cr->cr_uid) || 731 (suid != (uid_t)-1 && suid != cr->cr_ruid && 732 suid != cr->cr_svuid && suid != cr->cr_uid)) && 733 (error = priv_check_cred(cr, PRIV_CRED_SETRESUID, 0)) != 0) { 734 goto done; 735 } 736 if (euid != (uid_t)-1 && cr->cr_uid != euid) { 737 cr = change_euid(euid); 738 setsugid(); 739 } 740 if (ruid != (uid_t)-1 && cr->cr_ruid != ruid) { 741 cr = change_ruid(ruid); 742 setsugid(); 743 } 744 if (suid != (uid_t)-1 && cr->cr_svuid != suid) { 745 cr = cratom_proc(p); 746 cr->cr_svuid = suid; 747 setsugid(); 748 } 749 error = 0; 750 done: 751 lwkt_reltoken(&p->p_token); 752 return (error); 753 } 754 755 /* 756 * setresgid(rgid, egid, sgid) is like setregid except control over the 757 * saved gid is explicit. 758 */ 759 int 760 sys_setresgid(struct setresgid_args *uap) 761 { 762 struct proc *p = curproc; 763 struct ucred *cr; 764 gid_t rgid, egid, sgid; 765 int error; 766 767 lwkt_gettoken(&p->p_token); 768 cr = p->p_ucred; 769 rgid = uap->rgid; 770 egid = uap->egid; 771 sgid = uap->sgid; 772 if (((rgid != (gid_t)-1 && rgid != cr->cr_rgid && 773 rgid != cr->cr_svgid && rgid != cr->cr_groups[0]) || 774 (egid != (gid_t)-1 && egid != cr->cr_rgid && 775 egid != cr->cr_svgid && egid != cr->cr_groups[0]) || 776 (sgid != (gid_t)-1 && sgid != cr->cr_rgid && 777 sgid != cr->cr_svgid && sgid != cr->cr_groups[0])) && 778 (error = priv_check_cred(cr, PRIV_CRED_SETRESGID, 0)) != 0) { 779 goto done; 780 } 781 782 if (egid != (gid_t)-1 && cr->cr_groups[0] != egid) { 783 cr = cratom_proc(p); 784 cr->cr_groups[0] = egid; 785 setsugid(); 786 } 787 if (rgid != (gid_t)-1 && cr->cr_rgid != rgid) { 788 cr = cratom_proc(p); 789 cr->cr_rgid = rgid; 790 setsugid(); 791 } 792 if (sgid != (gid_t)-1 && cr->cr_svgid != sgid) { 793 cr = cratom_proc(p); 794 cr->cr_svgid = sgid; 795 setsugid(); 796 } 797 error = 0; 798 done: 799 lwkt_reltoken(&p->p_token); 800 return (error); 801 } 802 803 int 804 sys_getresuid(struct getresuid_args *uap) 805 { 806 struct ucred *cr; 807 int error1 = 0, error2 = 0, error3 = 0; 808 809 /* 810 * copyout's can fault synchronously so we cannot use a shared 811 * token here. 812 */ 813 cr = curthread->td_ucred; 814 if (uap->ruid) 815 error1 = copyout((caddr_t)&cr->cr_ruid, 816 (caddr_t)uap->ruid, sizeof(cr->cr_ruid)); 817 if (uap->euid) 818 error2 = copyout((caddr_t)&cr->cr_uid, 819 (caddr_t)uap->euid, sizeof(cr->cr_uid)); 820 if (uap->suid) 821 error3 = copyout((caddr_t)&cr->cr_svuid, 822 (caddr_t)uap->suid, sizeof(cr->cr_svuid)); 823 return error1 ? error1 : (error2 ? error2 : error3); 824 } 825 826 int 827 sys_getresgid(struct getresgid_args *uap) 828 { 829 struct ucred *cr; 830 int error1 = 0, error2 = 0, error3 = 0; 831 832 cr = curthread->td_ucred; 833 if (uap->rgid) 834 error1 = copyout(&cr->cr_rgid, uap->rgid, 835 sizeof(cr->cr_rgid)); 836 if (uap->egid) 837 error2 = copyout(&cr->cr_groups[0], uap->egid, 838 sizeof(cr->cr_groups[0])); 839 if (uap->sgid) 840 error3 = copyout(&cr->cr_svgid, uap->sgid, 841 sizeof(cr->cr_svgid)); 842 return error1 ? error1 : (error2 ? error2 : error3); 843 } 844 845 846 /* 847 * NOTE: OpenBSD sets a P_SUGIDEXEC flag set at execve() time, 848 * we use P_SUGID because we consider changing the owners as 849 * "tainting" as well. 850 * This is significant for procs that start as root and "become" 851 * a user without an exec - programs cannot know *everything* 852 * that libc *might* have put in their data segment. 853 */ 854 int 855 sys_issetugid(struct issetugid_args *uap) 856 { 857 uap->sysmsg_result = (curproc->p_flags & P_SUGID) ? 1 : 0; 858 return (0); 859 } 860 861 /* 862 * Check if gid is a member of the group set. 863 */ 864 int 865 groupmember(gid_t gid, struct ucred *cred) 866 { 867 gid_t *gp; 868 gid_t *egp; 869 870 egp = &(cred->cr_groups[cred->cr_ngroups]); 871 for (gp = cred->cr_groups; gp < egp; gp++) { 872 if (*gp == gid) 873 return (1); 874 } 875 return (0); 876 } 877 878 /* 879 * Test whether the specified credentials have the privilege 880 * in question. 881 * 882 * A kernel thread without a process context is assumed to have 883 * the privilege in question. In situations where the caller always 884 * expect a cred to exist, the cred should be passed separately and 885 * priv_check_cred() should be used instead of priv_check(). 886 * 887 * Returns 0 or error. 888 */ 889 int 890 priv_check(struct thread *td, int priv) 891 { 892 if (td->td_lwp != NULL) 893 return priv_check_cred(td->td_ucred, priv, 0); 894 return (0); 895 } 896 897 /* 898 * Check a credential for privilege. 899 * 900 * A non-null credential is expected unless NULL_CRED_OKAY is set. 901 */ 902 int 903 priv_check_cred(struct ucred *cred, int priv, int flags) 904 { 905 int error; 906 907 KASSERT(PRIV_VALID(priv), ("priv_check_cred: invalid privilege")); 908 909 KASSERT(cred != NULL || (flags & NULL_CRED_OKAY), 910 ("priv_check_cred: NULL cred!")); 911 912 if (cred == NULL) { 913 if (flags & NULL_CRED_OKAY) 914 return (0); 915 else 916 return (EPERM); 917 } 918 if (cred->cr_uid != 0) 919 return (EPERM); 920 921 error = prison_priv_check(cred, priv); 922 if (error) 923 return (error); 924 925 /* NOTE: accounting for suser access (p_acflag/ASU) removed */ 926 return (0); 927 } 928 929 /* 930 * Return zero if p1 can fondle p2, return errno (EPERM/ESRCH) otherwise. 931 */ 932 int 933 p_trespass(struct ucred *cr1, struct ucred *cr2) 934 { 935 if (cr1 == cr2) 936 return (0); 937 if (!PRISON_CHECK(cr1, cr2)) 938 return (ESRCH); 939 if (cr1->cr_ruid == cr2->cr_ruid) 940 return (0); 941 if (cr1->cr_uid == cr2->cr_ruid) 942 return (0); 943 if (cr1->cr_ruid == cr2->cr_uid) 944 return (0); 945 if (cr1->cr_uid == cr2->cr_uid) 946 return (0); 947 if (priv_check_cred(cr1, PRIV_PROC_TRESPASS, 0) == 0) 948 return (0); 949 return (EPERM); 950 } 951 952 static __inline void 953 _crinit(struct ucred *cr) 954 { 955 cr->cr_ref = 1; 956 } 957 958 void 959 crinit(struct ucred *cr) 960 { 961 bzero(cr, sizeof(*cr)); 962 _crinit(cr); 963 } 964 965 /* 966 * Allocate a zeroed cred structure. 967 */ 968 struct ucred * 969 crget(void) 970 { 971 struct ucred *cr; 972 973 cr = kmalloc(sizeof(*cr), M_CRED, M_WAITOK|M_ZERO); 974 _crinit(cr); 975 return (cr); 976 } 977 978 /* 979 * Claim another reference to a ucred structure. Can be used with special 980 * creds. 981 * 982 * It must be possible to call this routine with spinlocks held, meaning 983 * that this routine itself cannot obtain a spinlock. 984 */ 985 struct ucred * 986 crhold(struct ucred *cr) 987 { 988 if (cr != NOCRED && cr != FSCRED) 989 atomic_add_int(&cr->cr_ref, 1); 990 return(cr); 991 } 992 993 /* 994 * Drop a reference from the cred structure, free it if the reference count 995 * reaches 0. 996 * 997 * NOTE: because we used atomic_add_int() above, without a spinlock, we 998 * must also use atomic_subtract_int() below. A spinlock is required 999 * in crfree() to handle multiple callers racing the refcount to 0. 1000 */ 1001 void 1002 crfree(struct ucred *cr) 1003 { 1004 if (cr->cr_ref <= 0) 1005 panic("Freeing already free credential! %p", cr); 1006 if (atomic_fetchadd_int(&cr->cr_ref, -1) == 1) { 1007 /* 1008 * Some callers of crget(), such as nfs_statfs(), 1009 * allocate a temporary credential, but don't 1010 * allocate a uidinfo structure. 1011 */ 1012 if (cr->cr_uidinfo != NULL) { 1013 uidrop(cr->cr_uidinfo); 1014 cr->cr_uidinfo = NULL; 1015 } 1016 if (cr->cr_ruidinfo != NULL) { 1017 uidrop(cr->cr_ruidinfo); 1018 cr->cr_ruidinfo = NULL; 1019 } 1020 1021 /* 1022 * Destroy empty prisons 1023 */ 1024 if (jailed(cr)) 1025 prison_free(cr->cr_prison); 1026 cr->cr_prison = NULL; /* safety */ 1027 1028 kfree((caddr_t)cr, M_CRED); 1029 } 1030 } 1031 1032 /* 1033 * Atomize a cred structure so it can be modified without polluting 1034 * other references to it. 1035 * 1036 * MPSAFE (however, *pcr must be stable) 1037 */ 1038 struct ucred * 1039 cratom(struct ucred **pcr) 1040 { 1041 struct ucred *oldcr; 1042 struct ucred *newcr; 1043 1044 oldcr = *pcr; 1045 if (oldcr->cr_ref == 1) 1046 return (oldcr); 1047 newcr = crget(); /* this might block */ 1048 oldcr = *pcr; /* re-cache after potentially blocking */ 1049 *newcr = *oldcr; 1050 if (newcr->cr_uidinfo) 1051 uihold(newcr->cr_uidinfo); 1052 if (newcr->cr_ruidinfo) 1053 uihold(newcr->cr_ruidinfo); 1054 if (jailed(newcr)) 1055 prison_hold(newcr->cr_prison); 1056 newcr->cr_ref = 1; 1057 crfree(oldcr); 1058 *pcr = newcr; 1059 1060 return (newcr); 1061 } 1062 1063 /* 1064 * Called with a modifying token held, but must still obtain p_spin to 1065 * actually replace p_ucred to handle races against syscall entry from 1066 * other threads which cache p_ucred->td_ucred. 1067 * 1068 * (the threads will only get the spin-lock, and they only need to in 1069 * the case where td_ucred != p_ucred so this is optimal). 1070 */ 1071 struct ucred * 1072 cratom_proc(struct proc *p) 1073 { 1074 struct ucred *oldcr; 1075 struct ucred *newcr; 1076 1077 oldcr = p->p_ucred; 1078 if (oldcr->cr_ref == 1) 1079 return(oldcr); 1080 1081 newcr = crget(); /* this might block */ 1082 oldcr = p->p_ucred; /* so re-cache oldcr (do not re-test) */ 1083 *newcr = *oldcr; 1084 if (newcr->cr_uidinfo) 1085 uihold(newcr->cr_uidinfo); 1086 if (newcr->cr_ruidinfo) 1087 uihold(newcr->cr_ruidinfo); 1088 if (jailed(newcr)) 1089 prison_hold(newcr->cr_prison); 1090 newcr->cr_ref = 1; 1091 1092 spin_lock(&p->p_spin); 1093 p->p_ucred = newcr; 1094 spin_unlock(&p->p_spin); 1095 crfree(oldcr); 1096 1097 return newcr; 1098 } 1099 1100 /* 1101 * Dup cred struct to a new held one. 1102 */ 1103 struct ucred * 1104 crdup(struct ucred *cr) 1105 { 1106 struct ucred *newcr; 1107 1108 newcr = crget(); 1109 *newcr = *cr; 1110 if (newcr->cr_uidinfo) 1111 uihold(newcr->cr_uidinfo); 1112 if (newcr->cr_ruidinfo) 1113 uihold(newcr->cr_ruidinfo); 1114 if (jailed(newcr)) 1115 prison_hold(newcr->cr_prison); 1116 newcr->cr_ref = 1; 1117 return (newcr); 1118 } 1119 1120 /* 1121 * Fill in a struct xucred based on a struct ucred. 1122 */ 1123 void 1124 cru2x(struct ucred *cr, struct xucred *xcr) 1125 { 1126 1127 bzero(xcr, sizeof(*xcr)); 1128 xcr->cr_version = XUCRED_VERSION; 1129 xcr->cr_uid = cr->cr_uid; 1130 xcr->cr_ngroups = cr->cr_ngroups; 1131 bcopy(cr->cr_groups, xcr->cr_groups, sizeof(cr->cr_groups)); 1132 } 1133 1134 /* 1135 * Get login name, if available. 1136 */ 1137 int 1138 sys_getlogin(struct getlogin_args *uap) 1139 { 1140 struct proc *p = curproc; 1141 char buf[MAXLOGNAME]; 1142 int error; 1143 1144 if (uap->namelen > MAXLOGNAME) /* namelen is unsigned */ 1145 uap->namelen = MAXLOGNAME; 1146 bzero(buf, sizeof(buf)); 1147 lwkt_gettoken_shared(&p->p_token); 1148 bcopy(p->p_pgrp->pg_session->s_login, buf, uap->namelen); 1149 lwkt_reltoken(&p->p_token); 1150 1151 error = copyout(buf, uap->namebuf, uap->namelen); 1152 return (error); 1153 } 1154 1155 /* 1156 * Set login name. 1157 */ 1158 int 1159 sys_setlogin(struct setlogin_args *uap) 1160 { 1161 struct thread *td = curthread; 1162 struct proc *p; 1163 struct ucred *cred; 1164 char buf[MAXLOGNAME]; 1165 int error; 1166 1167 cred = td->td_ucred; 1168 p = td->td_proc; 1169 1170 if ((error = priv_check_cred(cred, PRIV_PROC_SETLOGIN, 0))) 1171 return (error); 1172 bzero(buf, sizeof(buf)); 1173 error = copyinstr(uap->namebuf, buf, sizeof(buf), NULL); 1174 if (error == ENAMETOOLONG) 1175 error = EINVAL; 1176 if (error == 0) { 1177 lwkt_gettoken_shared(&p->p_token); 1178 memcpy(p->p_pgrp->pg_session->s_login, buf, sizeof(buf)); 1179 lwkt_reltoken(&p->p_token); 1180 } 1181 return (error); 1182 } 1183 1184 void 1185 setsugid(void) 1186 { 1187 struct proc *p = curproc; 1188 1189 KKASSERT(p != NULL); 1190 lwkt_gettoken(&p->p_token); 1191 p->p_flags |= P_SUGID; 1192 if (!(p->p_pfsflags & PF_ISUGID)) 1193 p->p_stops = 0; 1194 lwkt_reltoken(&p->p_token); 1195 } 1196 1197 /* 1198 * Helper function to change the effective uid of a process 1199 */ 1200 struct ucred * 1201 change_euid(uid_t euid) 1202 { 1203 struct proc *p = curproc; 1204 struct ucred *cr; 1205 1206 KKASSERT(p != NULL); 1207 lf_count_adjust(p, 0); 1208 cr = cratom_proc(p); 1209 cr->cr_uid = euid; 1210 uireplace(&cr->cr_uidinfo, uifind(euid)); 1211 lf_count_adjust(p, 1); 1212 return (cr); 1213 } 1214 1215 /* 1216 * Helper function to change the real uid of a process 1217 * 1218 * The per-uid process count for this process is transfered from 1219 * the old uid to the new uid. 1220 */ 1221 struct ucred * 1222 change_ruid(uid_t ruid) 1223 { 1224 struct proc *p = curproc; 1225 struct ucred *cr; 1226 1227 KKASSERT(p != NULL); 1228 1229 cr = cratom_proc(p); 1230 chgproccnt(cr->cr_ruidinfo, -1, 0); 1231 cr->cr_ruid = ruid; 1232 uireplace(&cr->cr_ruidinfo, uifind(ruid)); 1233 chgproccnt(cr->cr_ruidinfo, 1, 0); 1234 return (cr); 1235 } 1236