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