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