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