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