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