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