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/caps.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 = caps_priv_check(cr, SYSCAP_NOCRED_SETUID))) 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 caps_priv_check(cr, SYSCAP_NOCRED_SETUID, 0) == 0) /* 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 = caps_priv_check(cr, SYSCAP_NOCRED_SETEUID))) 532 { 533 lwkt_reltoken(&p->p_token); 534 return (error); 535 } 536 537 /* 538 * Everything's okay, do it. Copy credentials so other references do 539 * not see our changes. 540 */ 541 if (cr->cr_uid != euid) { 542 change_euid(euid); 543 setsugid(); 544 } 545 lwkt_reltoken(&p->p_token); 546 return (0); 547 } 548 549 int 550 sys_setgid(struct sysmsg *sysmsg, const struct setgid_args *uap) 551 { 552 struct proc *p = curproc; 553 struct ucred *cr; 554 gid_t gid; 555 int error; 556 557 lwkt_gettoken(&p->p_token); 558 cr = p->p_ucred; 559 560 /* 561 * See if we have "permission" by POSIX 1003.1 rules. 562 * 563 * Note that setgid(getegid()) is a special case of 564 * "appropriate privileges" in appendix B.4.2.2. We need 565 * to use this clause to be compatible with traditional BSD 566 * semantics. Basically, it means that "setgid(xx)" sets all 567 * three id's (assuming you have privs). 568 * 569 * For notes on the logic here, see setuid() above. 570 */ 571 gid = uap->gid; 572 if (gid != cr->cr_rgid && /* allow setgid(getgid()) */ 573 #ifdef _POSIX_SAVED_IDS 574 gid != cr->cr_svgid && /* allow setgid(saved gid) */ 575 #endif 576 #ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */ 577 gid != cr->cr_groups[0] && /* allow setgid(getegid()) */ 578 #endif 579 (error = caps_priv_check(cr, SYSCAP_NOCRED_SETGID))) 580 { 581 goto done; 582 } 583 584 #ifdef _POSIX_SAVED_IDS 585 /* 586 * Do we have "appropriate privileges" (are we root or gid == egid) 587 * If so, we are changing the real uid and saved gid. 588 */ 589 if ( 590 #ifdef POSIX_APPENDIX_B_4_2_2 /* use the clause from B.4.2.2 */ 591 gid == cr->cr_groups[0] || 592 #endif 593 cpas_priv_check(cr, SYSCAP_NOCRED_SETGID) == 0) /* using privs */ 594 #endif 595 { 596 /* 597 * Set real gid 598 */ 599 if (cr->cr_rgid != gid) { 600 cr = cratom_proc(p); 601 cr->cr_rgid = gid; 602 setsugid(); 603 } 604 /* 605 * Set saved gid 606 * 607 * XXX always set saved gid even if not _POSIX_SAVED_IDS, as 608 * the security of setegid() depends on it. B.4.2.2 says it 609 * is important that we should do this. 610 */ 611 if (cr->cr_svgid != gid) { 612 cr = cratom_proc(p); 613 cr->cr_svgid = gid; 614 setsugid(); 615 } 616 } 617 /* 618 * In all cases permitted cases, we are changing the egid. 619 * Copy credentials so other references do not see our changes. 620 */ 621 if (cr->cr_groups[0] != gid) { 622 cr = cratom_proc(p); 623 cr->cr_groups[0] = gid; 624 setsugid(); 625 } 626 error = 0; 627 done: 628 lwkt_reltoken(&p->p_token); 629 return (error); 630 } 631 632 int 633 sys_setegid(struct sysmsg *sysmsg, const struct setegid_args *uap) 634 { 635 struct proc *p = curproc; 636 struct ucred *cr; 637 gid_t egid; 638 int error; 639 640 lwkt_gettoken(&p->p_token); 641 cr = p->p_ucred; 642 egid = uap->egid; 643 if (egid != cr->cr_rgid && /* allow setegid(getgid()) */ 644 egid != cr->cr_svgid && /* allow setegid(saved gid) */ 645 (error = caps_priv_check(cr, SYSCAP_NOCRED_SETEGID))) 646 { 647 goto done; 648 } 649 if (cr->cr_groups[0] != egid) { 650 cr = cratom_proc(p); 651 cr->cr_groups[0] = egid; 652 setsugid(); 653 } 654 error = 0; 655 done: 656 lwkt_reltoken(&p->p_token); 657 return (error); 658 } 659 660 int 661 sys_setgroups(struct sysmsg *sysmsg, const struct setgroups_args *uap) 662 { 663 struct proc *p = curproc; 664 struct ucred *cr; 665 u_int ngrp; 666 int error; 667 668 lwkt_gettoken(&p->p_token); 669 cr = p->p_ucred; 670 671 if ((error = caps_priv_check(cr, SYSCAP_NOCRED_SETGROUPS))) 672 goto done; 673 ngrp = uap->gidsetsize; 674 if (ngrp > NGROUPS) { 675 error = EINVAL; 676 goto done; 677 } 678 /* 679 * XXX A little bit lazy here. We could test if anything has 680 * changed before cratom() and setting P_SUGID. 681 */ 682 cr = cratom_proc(p); 683 if (ngrp < 1) { 684 /* 685 * setgroups(0, NULL) is a legitimate way of clearing the 686 * groups vector on non-BSD systems (which generally do not 687 * have the egid in the groups[0]). We risk security holes 688 * when running non-BSD software if we do not do the same. 689 */ 690 cr->cr_ngroups = 1; 691 } else { 692 error = copyin(uap->gidset, cr->cr_groups, 693 ngrp * sizeof(gid_t)); 694 if (error) 695 goto done; 696 cr->cr_ngroups = ngrp; 697 } 698 setsugid(); 699 error = 0; 700 done: 701 lwkt_reltoken(&p->p_token); 702 return (error); 703 } 704 705 int 706 sys_setreuid(struct sysmsg *sysmsg, const struct setreuid_args *uap) 707 { 708 struct proc *p = curproc; 709 struct ucred *cr; 710 uid_t ruid, euid; 711 int error; 712 713 lwkt_gettoken(&p->p_token); 714 cr = p->p_ucred; 715 716 ruid = uap->ruid; 717 euid = uap->euid; 718 if (((ruid != (uid_t)-1 && ruid != cr->cr_ruid && 719 ruid != cr->cr_svuid) || 720 (euid != (uid_t)-1 && euid != cr->cr_uid && 721 euid != cr->cr_ruid && euid != cr->cr_svuid)) && 722 (error = caps_priv_check(cr, SYSCAP_NOCRED_SETREUID)) != 0) 723 { 724 goto done; 725 } 726 727 if (euid != (uid_t)-1 && cr->cr_uid != euid) { 728 cr = change_euid(euid); 729 setsugid(); 730 } 731 if (ruid != (uid_t)-1 && cr->cr_ruid != ruid) { 732 cr = change_ruid(ruid); 733 setsugid(); 734 } 735 if ((ruid != (uid_t)-1 || cr->cr_uid != cr->cr_ruid) && 736 cr->cr_svuid != cr->cr_uid) { 737 cr = cratom_proc(p); 738 cr->cr_svuid = cr->cr_uid; 739 setsugid(); 740 } 741 error = 0; 742 done: 743 lwkt_reltoken(&p->p_token); 744 return (error); 745 } 746 747 int 748 sys_setregid(struct sysmsg *sysmsg, const struct setregid_args *uap) 749 { 750 struct proc *p = curproc; 751 struct ucred *cr; 752 gid_t rgid, egid; 753 int error; 754 755 lwkt_gettoken(&p->p_token); 756 cr = p->p_ucred; 757 758 rgid = uap->rgid; 759 egid = uap->egid; 760 if (((rgid != (gid_t)-1 && rgid != cr->cr_rgid && 761 rgid != cr->cr_svgid) || 762 (egid != (gid_t)-1 && egid != cr->cr_groups[0] && 763 egid != cr->cr_rgid && egid != cr->cr_svgid)) && 764 (error = caps_priv_check(cr, SYSCAP_NOCRED_SETREGID)) != 0) 765 { 766 goto done; 767 } 768 769 if (egid != (gid_t)-1 && cr->cr_groups[0] != egid) { 770 cr = cratom_proc(p); 771 cr->cr_groups[0] = egid; 772 setsugid(); 773 } 774 if (rgid != (gid_t)-1 && cr->cr_rgid != rgid) { 775 cr = cratom_proc(p); 776 cr->cr_rgid = rgid; 777 setsugid(); 778 } 779 if ((rgid != (gid_t)-1 || cr->cr_groups[0] != cr->cr_rgid) && 780 cr->cr_svgid != cr->cr_groups[0]) { 781 cr = cratom_proc(p); 782 cr->cr_svgid = cr->cr_groups[0]; 783 setsugid(); 784 } 785 error = 0; 786 done: 787 lwkt_reltoken(&p->p_token); 788 return (error); 789 } 790 791 /* 792 * setresuid(ruid, euid, suid) is like setreuid except control over the 793 * saved uid is explicit. 794 */ 795 int 796 sys_setresuid(struct sysmsg *sysmsg, const struct setresuid_args *uap) 797 { 798 struct proc *p = curproc; 799 struct ucred *cr; 800 uid_t ruid, euid, suid; 801 int error; 802 803 lwkt_gettoken(&p->p_token); 804 cr = p->p_ucred; 805 806 ruid = uap->ruid; 807 euid = uap->euid; 808 suid = uap->suid; 809 if (((ruid != (uid_t)-1 && ruid != cr->cr_ruid && 810 ruid != cr->cr_svuid && ruid != cr->cr_uid) || 811 (euid != (uid_t)-1 && euid != cr->cr_ruid && 812 euid != cr->cr_svuid && euid != cr->cr_uid) || 813 (suid != (uid_t)-1 && suid != cr->cr_ruid && 814 suid != cr->cr_svuid && suid != cr->cr_uid)) && 815 (error = caps_priv_check(cr, SYSCAP_NOCRED_SETRESUID)) != 0) 816 { 817 goto done; 818 } 819 if (euid != (uid_t)-1 && cr->cr_uid != euid) { 820 cr = change_euid(euid); 821 setsugid(); 822 } 823 if (ruid != (uid_t)-1 && cr->cr_ruid != ruid) { 824 cr = change_ruid(ruid); 825 setsugid(); 826 } 827 if (suid != (uid_t)-1 && cr->cr_svuid != suid) { 828 cr = cratom_proc(p); 829 cr->cr_svuid = suid; 830 setsugid(); 831 } 832 error = 0; 833 done: 834 lwkt_reltoken(&p->p_token); 835 return (error); 836 } 837 838 /* 839 * setresgid(rgid, egid, sgid) is like setregid except control over the 840 * saved gid is explicit. 841 */ 842 int 843 sys_setresgid(struct sysmsg *sysmsg, const struct setresgid_args *uap) 844 { 845 struct proc *p = curproc; 846 struct ucred *cr; 847 gid_t rgid, egid, sgid; 848 int error; 849 850 lwkt_gettoken(&p->p_token); 851 cr = p->p_ucred; 852 rgid = uap->rgid; 853 egid = uap->egid; 854 sgid = uap->sgid; 855 if (((rgid != (gid_t)-1 && rgid != cr->cr_rgid && 856 rgid != cr->cr_svgid && rgid != cr->cr_groups[0]) || 857 (egid != (gid_t)-1 && egid != cr->cr_rgid && 858 egid != cr->cr_svgid && egid != cr->cr_groups[0]) || 859 (sgid != (gid_t)-1 && sgid != cr->cr_rgid && 860 sgid != cr->cr_svgid && sgid != cr->cr_groups[0])) && 861 (error = caps_priv_check(cr, SYSCAP_NOCRED_SETRESGID)) != 0) 862 { 863 goto done; 864 } 865 866 if (egid != (gid_t)-1 && cr->cr_groups[0] != egid) { 867 cr = cratom_proc(p); 868 cr->cr_groups[0] = egid; 869 setsugid(); 870 } 871 if (rgid != (gid_t)-1 && cr->cr_rgid != rgid) { 872 cr = cratom_proc(p); 873 cr->cr_rgid = rgid; 874 setsugid(); 875 } 876 if (sgid != (gid_t)-1 && cr->cr_svgid != sgid) { 877 cr = cratom_proc(p); 878 cr->cr_svgid = sgid; 879 setsugid(); 880 } 881 error = 0; 882 done: 883 lwkt_reltoken(&p->p_token); 884 return (error); 885 } 886 887 int 888 sys_getresuid(struct sysmsg *sysmsg, const struct getresuid_args *uap) 889 { 890 struct ucred *cr; 891 int error1 = 0, error2 = 0, error3 = 0; 892 893 /* 894 * copyout's can fault synchronously so we cannot use a shared 895 * token here. 896 */ 897 cr = curthread->td_ucred; 898 if (uap->ruid) 899 error1 = copyout((caddr_t)&cr->cr_ruid, 900 (caddr_t)uap->ruid, sizeof(cr->cr_ruid)); 901 if (uap->euid) 902 error2 = copyout((caddr_t)&cr->cr_uid, 903 (caddr_t)uap->euid, sizeof(cr->cr_uid)); 904 if (uap->suid) 905 error3 = copyout((caddr_t)&cr->cr_svuid, 906 (caddr_t)uap->suid, sizeof(cr->cr_svuid)); 907 return error1 ? error1 : (error2 ? error2 : error3); 908 } 909 910 int 911 sys_getresgid(struct sysmsg *sysmsg, const struct getresgid_args *uap) 912 { 913 struct ucred *cr; 914 int error1 = 0, error2 = 0, error3 = 0; 915 916 cr = curthread->td_ucred; 917 if (uap->rgid) 918 error1 = copyout(&cr->cr_rgid, uap->rgid, 919 sizeof(cr->cr_rgid)); 920 if (uap->egid) 921 error2 = copyout(&cr->cr_groups[0], uap->egid, 922 sizeof(cr->cr_groups[0])); 923 if (uap->sgid) 924 error3 = copyout(&cr->cr_svgid, uap->sgid, 925 sizeof(cr->cr_svgid)); 926 return error1 ? error1 : (error2 ? error2 : error3); 927 } 928 929 930 /* 931 * NOTE: OpenBSD sets a P_SUGIDEXEC flag set at execve() time, 932 * we use P_SUGID because we consider changing the owners as 933 * "tainting" as well. 934 * This is significant for procs that start as root and "become" 935 * a user without an exec - programs cannot know *everything* 936 * that libc *might* have put in their data segment. 937 */ 938 int 939 sys_issetugid(struct sysmsg *sysmsg, const struct issetugid_args *uap) 940 { 941 sysmsg->sysmsg_result = (curproc->p_flags & P_SUGID) ? 1 : 0; 942 return (0); 943 } 944 945 /* 946 * Check if gid is a member of the group set. 947 */ 948 int 949 groupmember(gid_t gid, struct ucred *cred) 950 { 951 gid_t *gp; 952 gid_t *egp; 953 954 egp = &(cred->cr_groups[cred->cr_ngroups]); 955 for (gp = cred->cr_groups; gp < egp; gp++) { 956 if (*gp == gid) 957 return (1); 958 } 959 return (0); 960 } 961 962 #if 0 963 /* 964 * Test whether the specified credentials have the privilege 965 * in question. 966 * 967 * A kernel thread without a process context is assumed to have 968 * the privilege in question. In situations where the caller always 969 * expect a cred to exist, the cred should be passed separately and 970 * priv_check_cred() should be used instead of priv_check(). 971 * 972 * Returns 0 or error. 973 */ 974 int 975 priv_check(struct thread *td, int priv) 976 { 977 if (td->td_lwp != NULL) 978 return priv_check_cred(td->td_ucred, priv, 0); 979 return (0); 980 } 981 982 /* 983 * Check a credential for privilege. 984 * 985 * A non-null credential is expected unless NULL_CRED_OKAY is set. 986 */ 987 int 988 priv_check_cred(struct ucred *cred, int priv, int flags) 989 { 990 int error; 991 992 KASSERT(PRIV_VALID(priv), ("priv_check_cred: invalid privilege")); 993 994 KASSERT(cred != NULL || (flags & NULL_CRED_OKAY), 995 ("priv_check_cred: NULL cred!")); 996 997 if (cred == NULL) { 998 if (flags & NULL_CRED_OKAY) 999 return (0); 1000 else 1001 return (EPERM); 1002 } 1003 if (cred->cr_uid != 0) 1004 return (EPERM); 1005 1006 error = prison_priv_check(cred, priv); 1007 if (error) 1008 return (error); 1009 error = caps_priv_check(cred, priv); 1010 if (error) 1011 return (error); 1012 1013 /* NOTE: accounting for suser access (p_acflag/ASU) removed */ 1014 return (0); 1015 } 1016 1017 #endif 1018 1019 /* 1020 * Return zero if p1 can signal p2, return errno (EPERM/ESRCH) otherwise. 1021 */ 1022 int 1023 p_trespass(struct ucred *cr1, struct ucred *cr2) 1024 { 1025 if (cr1 == cr2) 1026 return (0); 1027 1028 /* 1029 * Disallow signals crossing outside of a prison boundary 1030 */ 1031 if (!PRISON_CHECK(cr1, cr2)) 1032 return (ESRCH); 1033 1034 /* 1035 * Processes inside a restricted root cannot signal processes 1036 * outside of a restricted root. Unless it is also jailed, this will 1037 * still allow cross-signaling between unrelated restricted roots. 1038 */ 1039 if ((caps_get(cr1, SYSCAP_RESTRICTEDROOT) & __SYSCAP_SELF) && 1040 (caps_get(cr2, SYSCAP_RESTRICTEDROOT) & __SYSCAP_SELF) == 0) 1041 { 1042 return (ESRCH); 1043 } 1044 1045 if (cr1->cr_ruid == cr2->cr_ruid) 1046 return (0); 1047 if (cr1->cr_uid == cr2->cr_ruid) 1048 return (0); 1049 if (cr1->cr_ruid == cr2->cr_uid) 1050 return (0); 1051 if (cr1->cr_uid == cr2->cr_uid) 1052 return (0); 1053 if (caps_priv_check(cr1, SYSCAP_NOPROC_TRESPASS) == 0) 1054 return (0); 1055 if (cr1->cr_uid == 0) 1056 return (0); 1057 return (EPERM); 1058 } 1059 1060 /* 1061 * Allocate a zeroed cred structure. 1062 */ 1063 struct ucred * 1064 crget(void) 1065 { 1066 struct ucred *cr; 1067 1068 cr = kmalloc(sizeof(*cr), M_CRED, M_WAITOK|M_ZERO); 1069 cr->cr_ref = 1; 1070 1071 return (cr); 1072 } 1073 1074 /* 1075 * Claim another reference to a ucred structure. Can be used with special 1076 * creds. 1077 * 1078 * It must be possible to call this routine with spinlocks held, meaning 1079 * that this routine itself cannot obtain a spinlock. 1080 */ 1081 struct ucred * 1082 crhold(struct ucred *cr) 1083 { 1084 if (cr != NOCRED && cr != FSCRED) 1085 atomic_add_long(&cr->cr_ref, 1); 1086 return(cr); 1087 } 1088 1089 /* 1090 * Drop a reference from the cred structure, free it if the reference count 1091 * reaches 0. 1092 * 1093 * NOTE: because we used atomic_add_int() above, without a spinlock, we 1094 * must also use atomic_subtract_int() below. A spinlock is required 1095 * in crfree() to handle multiple callers racing the refcount to 0. 1096 */ 1097 void 1098 crfree(struct ucred *cr) 1099 { 1100 if (cr->cr_ref <= 0) 1101 panic("Freeing already free credential! %p", cr); 1102 if (atomic_fetchadd_long(&cr->cr_ref, -1) == 1) { 1103 /* 1104 * Some callers of crget(), such as nfs_statfs(), 1105 * allocate a temporary credential, but don't 1106 * allocate a uidinfo structure. 1107 */ 1108 if (cr->cr_uidinfo != NULL) { 1109 uidrop(cr->cr_uidinfo); 1110 cr->cr_uidinfo = NULL; 1111 } 1112 if (cr->cr_ruidinfo != NULL) { 1113 uidrop(cr->cr_ruidinfo); 1114 cr->cr_ruidinfo = NULL; 1115 } 1116 1117 /* 1118 * Destroy empty prisons 1119 */ 1120 if (jailed(cr)) 1121 prison_free(cr->cr_prison); 1122 cr->cr_prison = NULL; /* safety */ 1123 1124 kfree((caddr_t)cr, M_CRED); 1125 } 1126 } 1127 1128 /* 1129 * Atomize a cred structure so it can be modified without polluting 1130 * other references to it. 1131 * 1132 * MPSAFE (however, *pcr must be stable) 1133 */ 1134 struct ucred * 1135 cratom(struct ucred **pcr) 1136 { 1137 struct ucred *oldcr; 1138 struct ucred *newcr; 1139 1140 oldcr = *pcr; 1141 if (oldcr->cr_ref == 1) 1142 return (oldcr); 1143 newcr = crget(); /* this might block */ 1144 oldcr = *pcr; /* re-cache after potentially blocking */ 1145 *newcr = *oldcr; 1146 uihold(newcr->cr_uidinfo); 1147 uihold(newcr->cr_ruidinfo); 1148 if (jailed(newcr)) 1149 prison_hold(newcr->cr_prison); 1150 newcr->cr_ref = 1; 1151 crfree(oldcr); 1152 *pcr = newcr; 1153 1154 return (newcr); 1155 } 1156 1157 /* 1158 * Called with a modifying token held, but must still obtain p_spin to 1159 * actually replace p_ucred to handle races against syscall entry from 1160 * other threads which cache p_ucred->td_ucred. 1161 * 1162 * (the threads will only get the spin-lock, and they only need to in 1163 * the case where td_ucred != p_ucred so this is optimal). 1164 */ 1165 struct ucred * 1166 cratom_proc(struct proc *p) 1167 { 1168 struct ucred *oldcr; 1169 struct ucred *newcr; 1170 1171 oldcr = p->p_ucred; 1172 if (oldcr->cr_ref == 1) 1173 return(oldcr); 1174 1175 newcr = crget(); /* this might block */ 1176 oldcr = p->p_ucred; /* so re-cache oldcr (do not re-test) */ 1177 *newcr = *oldcr; 1178 uihold(newcr->cr_uidinfo); 1179 uihold(newcr->cr_ruidinfo); 1180 if (jailed(newcr)) 1181 prison_hold(newcr->cr_prison); 1182 newcr->cr_ref = 1; 1183 1184 spin_lock(&p->p_spin); 1185 p->p_ucred = newcr; 1186 spin_unlock(&p->p_spin); 1187 crfree(oldcr); 1188 1189 return newcr; 1190 } 1191 1192 /* 1193 * Dup cred struct to a new held one. 1194 */ 1195 struct ucred * 1196 crdup(struct ucred *cr) 1197 { 1198 struct ucred *newcr; 1199 1200 newcr = crget(); 1201 *newcr = *cr; 1202 uihold(newcr->cr_uidinfo); 1203 uihold(newcr->cr_ruidinfo); 1204 if (jailed(newcr)) 1205 prison_hold(newcr->cr_prison); 1206 newcr->cr_ref = 1; 1207 1208 return (newcr); 1209 } 1210 1211 /* 1212 * Dup cred structure without caps or prison 1213 */ 1214 struct ucred * 1215 crdup_nocaps(struct ucred *cr) 1216 { 1217 struct ucred *newcr; 1218 1219 newcr = crget(); 1220 *newcr = *cr; 1221 uihold(newcr->cr_uidinfo); 1222 uihold(newcr->cr_ruidinfo); 1223 newcr->cr_prison = NULL; 1224 bzero(&newcr->cr_caps, sizeof(newcr->cr_caps)); 1225 newcr->cr_ref = 1; 1226 1227 return (newcr); 1228 } 1229 1230 /* 1231 * Fill in a struct xucred based on a struct ucred. 1232 */ 1233 void 1234 cru2x(struct ucred *cr, struct xucred *xcr) 1235 { 1236 1237 bzero(xcr, sizeof(*xcr)); 1238 xcr->cr_version = XUCRED_VERSION; 1239 xcr->cr_uid = cr->cr_uid; 1240 xcr->cr_ngroups = cr->cr_ngroups; 1241 bcopy(cr->cr_groups, xcr->cr_groups, sizeof(cr->cr_groups)); 1242 } 1243 1244 /* 1245 * Get login name, if available. 1246 */ 1247 int 1248 sys_getlogin(struct sysmsg *sysmsg, const struct getlogin_args *uap) 1249 { 1250 struct proc *p = curproc; 1251 char buf[MAXLOGNAME]; 1252 int error; 1253 size_t namelen; 1254 1255 namelen = uap->namelen; 1256 if (namelen > MAXLOGNAME) /* namelen is unsigned */ 1257 namelen = MAXLOGNAME; 1258 bzero(buf, sizeof(buf)); 1259 lwkt_gettoken_shared(&p->p_token); 1260 bcopy(p->p_pgrp->pg_session->s_login, buf, namelen); 1261 lwkt_reltoken(&p->p_token); 1262 1263 error = copyout(buf, uap->namebuf, namelen); 1264 1265 return (error); 1266 } 1267 1268 /* 1269 * Set login name. 1270 */ 1271 int 1272 sys_setlogin(struct sysmsg *sysmsg, const struct setlogin_args *uap) 1273 { 1274 struct thread *td = curthread; 1275 struct proc *p; 1276 struct ucred *cred; 1277 char buf[MAXLOGNAME]; 1278 int error; 1279 1280 cred = td->td_ucred; 1281 p = td->td_proc; 1282 1283 if ((error = caps_priv_check(cred, SYSCAP_NOPROC_SETLOGIN))) 1284 return (error); 1285 bzero(buf, sizeof(buf)); 1286 error = copyinstr(uap->namebuf, buf, sizeof(buf), NULL); 1287 if (error == ENAMETOOLONG) 1288 error = EINVAL; 1289 if (error == 0) { 1290 lwkt_gettoken_shared(&p->p_token); 1291 memcpy(p->p_pgrp->pg_session->s_login, buf, sizeof(buf)); 1292 lwkt_reltoken(&p->p_token); 1293 } 1294 return (error); 1295 } 1296 1297 void 1298 setsugid(void) 1299 { 1300 struct proc *p = curproc; 1301 1302 KKASSERT(p != NULL); 1303 lwkt_gettoken(&p->p_token); 1304 p->p_flags |= P_SUGID; 1305 if (!(p->p_pfsflags & PF_ISUGID)) 1306 p->p_stops = 0; 1307 lwkt_reltoken(&p->p_token); 1308 } 1309 1310 /* 1311 * Helper function to change the effective uid of a process 1312 */ 1313 struct ucred * 1314 change_euid(uid_t euid) 1315 { 1316 struct proc *p = curproc; 1317 struct ucred *cr; 1318 1319 KKASSERT(p != NULL); 1320 lf_count_adjust(p, 0); 1321 cr = cratom_proc(p); 1322 cr->cr_uid = euid; 1323 uireplace(&cr->cr_uidinfo, uifind(euid)); 1324 lf_count_adjust(p, 1); 1325 return (cr); 1326 } 1327 1328 /* 1329 * Helper function to change the real uid of a process 1330 * 1331 * The per-uid process count for this process is transfered from 1332 * the old uid to the new uid. 1333 */ 1334 struct ucred * 1335 change_ruid(uid_t ruid) 1336 { 1337 struct proc *p = curproc; 1338 struct ucred *cr; 1339 1340 KKASSERT(p != NULL); 1341 1342 cr = cratom_proc(p); 1343 chgproccnt(cr->cr_ruidinfo, -1, 0); 1344 cr->cr_ruid = ruid; 1345 uireplace(&cr->cr_ruidinfo, uifind(ruid)); 1346 chgproccnt(cr->cr_ruidinfo, 1, 0); 1347 return (cr); 1348 } 1349