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