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$ 40 */ 41 42 /* 43 * System calls related to processes and protection 44 */ 45 46 #include "opt_compat.h" 47 48 #include <sys/param.h> 49 #include <sys/acct.h> 50 #include <sys/systm.h> 51 #include <sys/sysproto.h> 52 #include <sys/kernel.h> 53 #include <sys/proc.h> 54 #include <sys/malloc.h> 55 #include <sys/pioctl.h> 56 #include <sys/resourcevar.h> 57 #include <sys/sysctl.h> 58 59 static MALLOC_DEFINE(M_CRED, "cred", "credentials"); 60 61 #ifndef _SYS_SYSPROTO_H_ 62 struct getpid_args { 63 int dummy; 64 }; 65 #endif 66 67 /* 68 * NOT MP SAFE due to p_pptr access 69 */ 70 /* ARGSUSED */ 71 int 72 getpid(p, uap) 73 struct proc *p; 74 struct getpid_args *uap; 75 { 76 77 p->p_retval[0] = p->p_pid; 78 #if defined(COMPAT_43) || defined(COMPAT_SUNOS) 79 p->p_retval[1] = p->p_pptr->p_pid; 80 #endif 81 return (0); 82 } 83 84 #ifndef _SYS_SYSPROTO_H_ 85 struct getppid_args { 86 int dummy; 87 }; 88 #endif 89 /* ARGSUSED */ 90 int 91 getppid(p, uap) 92 struct proc *p; 93 struct getppid_args *uap; 94 { 95 96 p->p_retval[0] = p->p_pptr->p_pid; 97 return (0); 98 } 99 100 /* 101 * Get process group ID; note that POSIX getpgrp takes no parameter 102 * 103 * MP SAFE 104 */ 105 #ifndef _SYS_SYSPROTO_H_ 106 struct getpgrp_args { 107 int dummy; 108 }; 109 #endif 110 111 int 112 getpgrp(p, uap) 113 struct proc *p; 114 struct getpgrp_args *uap; 115 { 116 117 p->p_retval[0] = p->p_pgrp->pg_id; 118 return (0); 119 } 120 121 /* Get an arbitary pid's process group id */ 122 #ifndef _SYS_SYSPROTO_H_ 123 struct getpgid_args { 124 pid_t pid; 125 }; 126 #endif 127 128 int 129 getpgid(p, uap) 130 struct proc *p; 131 struct getpgid_args *uap; 132 { 133 struct proc *pt; 134 135 pt = p; 136 if (uap->pid == 0) 137 goto found; 138 139 if ((pt = pfind(uap->pid)) == 0) 140 return ESRCH; 141 found: 142 p->p_retval[0] = pt->p_pgrp->pg_id; 143 return 0; 144 } 145 146 /* 147 * Get an arbitary pid's session id. 148 */ 149 #ifndef _SYS_SYSPROTO_H_ 150 struct getsid_args { 151 pid_t pid; 152 }; 153 #endif 154 155 int 156 getsid(p, uap) 157 struct proc *p; 158 struct getsid_args *uap; 159 { 160 struct proc *pt; 161 162 pt = p; 163 if (uap->pid == 0) 164 goto found; 165 166 if ((pt == pfind(uap->pid)) == 0) 167 return ESRCH; 168 found: 169 p->p_retval[0] = pt->p_session->s_sid; 170 return 0; 171 } 172 173 174 /* 175 * getuid() - MP SAFE 176 */ 177 #ifndef _SYS_SYSPROTO_H_ 178 struct getuid_args { 179 int dummy; 180 }; 181 #endif 182 183 /* ARGSUSED */ 184 int 185 getuid(p, uap) 186 struct proc *p; 187 struct getuid_args *uap; 188 { 189 190 p->p_retval[0] = p->p_cred->p_ruid; 191 #if defined(COMPAT_43) || defined(COMPAT_SUNOS) 192 p->p_retval[1] = p->p_ucred->cr_uid; 193 #endif 194 return (0); 195 } 196 197 /* 198 * geteuid() - MP SAFE 199 */ 200 #ifndef _SYS_SYSPROTO_H_ 201 struct geteuid_args { 202 int dummy; 203 }; 204 #endif 205 206 /* ARGSUSED */ 207 int 208 geteuid(p, uap) 209 struct proc *p; 210 struct geteuid_args *uap; 211 { 212 213 p->p_retval[0] = p->p_ucred->cr_uid; 214 return (0); 215 } 216 217 /* 218 * getgid() - MP SAFE 219 */ 220 #ifndef _SYS_SYSPROTO_H_ 221 struct getgid_args { 222 int dummy; 223 }; 224 #endif 225 226 /* ARGSUSED */ 227 int 228 getgid(p, uap) 229 struct proc *p; 230 struct getgid_args *uap; 231 { 232 233 p->p_retval[0] = p->p_cred->p_rgid; 234 #if defined(COMPAT_43) || defined(COMPAT_SUNOS) 235 p->p_retval[1] = p->p_ucred->cr_groups[0]; 236 #endif 237 return (0); 238 } 239 240 /* 241 * Get effective group ID. The "egid" is groups[0], and could be obtained 242 * via getgroups. This syscall exists because it is somewhat painful to do 243 * correctly in a library function. 244 */ 245 #ifndef _SYS_SYSPROTO_H_ 246 struct getegid_args { 247 int dummy; 248 }; 249 #endif 250 251 /* ARGSUSED */ 252 int 253 getegid(p, uap) 254 struct proc *p; 255 struct getegid_args *uap; 256 { 257 258 p->p_retval[0] = p->p_ucred->cr_groups[0]; 259 return (0); 260 } 261 262 #ifndef _SYS_SYSPROTO_H_ 263 struct getgroups_args { 264 u_int gidsetsize; 265 gid_t *gidset; 266 }; 267 #endif 268 int 269 getgroups(p, uap) 270 struct proc *p; 271 register struct getgroups_args *uap; 272 { 273 register struct pcred *pc = p->p_cred; 274 register u_int ngrp; 275 int error; 276 277 if ((ngrp = uap->gidsetsize) == 0) { 278 p->p_retval[0] = pc->pc_ucred->cr_ngroups; 279 return (0); 280 } 281 if (ngrp < pc->pc_ucred->cr_ngroups) 282 return (EINVAL); 283 ngrp = pc->pc_ucred->cr_ngroups; 284 if ((error = copyout((caddr_t)pc->pc_ucred->cr_groups, 285 (caddr_t)uap->gidset, ngrp * sizeof(gid_t)))) 286 return (error); 287 p->p_retval[0] = ngrp; 288 return (0); 289 } 290 291 #ifndef _SYS_SYSPROTO_H_ 292 struct setsid_args { 293 int dummy; 294 }; 295 #endif 296 297 /* ARGSUSED */ 298 int 299 setsid(p, uap) 300 register struct proc *p; 301 struct setsid_args *uap; 302 { 303 304 if (p->p_pgid == p->p_pid || pgfind(p->p_pid)) { 305 return (EPERM); 306 } else { 307 (void)enterpgrp(p, p->p_pid, 1); 308 p->p_retval[0] = p->p_pid; 309 return (0); 310 } 311 } 312 313 /* 314 * set process group (setpgid/old setpgrp) 315 * 316 * caller does setpgid(targpid, targpgid) 317 * 318 * pid must be caller or child of caller (ESRCH) 319 * if a child 320 * pid must be in same session (EPERM) 321 * pid can't have done an exec (EACCES) 322 * if pgid != pid 323 * there must exist some pid in same session having pgid (EPERM) 324 * pid must not be session leader (EPERM) 325 */ 326 #ifndef _SYS_SYSPROTO_H_ 327 struct setpgid_args { 328 int pid; /* target process id */ 329 int pgid; /* target pgrp id */ 330 }; 331 #endif 332 /* ARGSUSED */ 333 int 334 setpgid(curp, uap) 335 struct proc *curp; 336 register struct setpgid_args *uap; 337 { 338 register struct proc *targp; /* target process */ 339 register struct pgrp *pgrp; /* target pgrp */ 340 341 if (uap->pgid < 0) 342 return (EINVAL); 343 if (uap->pid != 0 && uap->pid != curp->p_pid) { 344 if ((targp = pfind(uap->pid)) == 0 || !inferior(targp)) 345 return (ESRCH); 346 if (targp->p_pgrp == NULL || targp->p_session != curp->p_session) 347 return (EPERM); 348 if (targp->p_flag & P_EXEC) 349 return (EACCES); 350 } else 351 targp = curp; 352 if (SESS_LEADER(targp)) 353 return (EPERM); 354 if (uap->pgid == 0) 355 uap->pgid = targp->p_pid; 356 else if (uap->pgid != targp->p_pid) 357 if ((pgrp = pgfind(uap->pgid)) == 0 || 358 pgrp->pg_session != curp->p_session) 359 return (EPERM); 360 return (enterpgrp(targp, uap->pgid, 0)); 361 } 362 363 /* 364 * Use the clause in B.4.2.2 that allows setuid/setgid to be 4.2/4.3BSD 365 * compatable. It says that setting the uid/gid to euid/egid is a special 366 * case of "appropriate privilege". Once the rules are expanded out, this 367 * basically means that setuid(nnn) sets all three id's, in all permitted 368 * cases unless _POSIX_SAVED_IDS is enabled. In that case, setuid(getuid()) 369 * does not set the saved id - this is dangerous for traditional BSD 370 * programs. For this reason, we *really* do not want to set 371 * _POSIX_SAVED_IDS and do not want to clear POSIX_APPENDIX_B_4_2_2. 372 */ 373 #define POSIX_APPENDIX_B_4_2_2 374 375 #ifndef _SYS_SYSPROTO_H_ 376 struct setuid_args { 377 uid_t uid; 378 }; 379 #endif 380 /* ARGSUSED */ 381 int 382 setuid(p, uap) 383 struct proc *p; 384 struct setuid_args *uap; 385 { 386 register struct pcred *pc = p->p_cred; 387 register uid_t uid; 388 int error; 389 390 /* 391 * See if we have "permission" by POSIX 1003.1 rules. 392 * 393 * Note that setuid(geteuid()) is a special case of 394 * "appropriate privileges" in appendix B.4.2.2. We need 395 * to use this clause to be compatable with traditional BSD 396 * semantics. Basically, it means that "setuid(xx)" sets all 397 * three id's (assuming you have privs). 398 * 399 * Notes on the logic. We do things in three steps. 400 * 1: We determine if the euid is going to change, and do EPERM 401 * right away. We unconditionally change the euid later if this 402 * test is satisfied, simplifying that part of the logic. 403 * 2: We determine if the real and/or saved uid's are going to 404 * change. Determined by compile options. 405 * 3: Change euid last. (after tests in #2 for "appropriate privs") 406 */ 407 uid = uap->uid; 408 if (uid != pc->p_ruid && /* allow setuid(getuid()) */ 409 #ifdef _POSIX_SAVED_IDS 410 uid != pc->p_svuid && /* allow setuid(saved gid) */ 411 #endif 412 #ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */ 413 uid != pc->pc_ucred->cr_uid && /* allow setuid(geteuid()) */ 414 #endif 415 (error = suser_xxx(0, p, PRISON_ROOT))) 416 return (error); 417 418 #ifdef _POSIX_SAVED_IDS 419 /* 420 * Do we have "appropriate privileges" (are we root or uid == euid) 421 * If so, we are changing the real uid and/or saved uid. 422 */ 423 if ( 424 #ifdef POSIX_APPENDIX_B_4_2_2 /* Use the clause from B.4.2.2 */ 425 uid == pc->pc_ucred->cr_uid || 426 #endif 427 suser_xxx(0, p, PRISON_ROOT) == 0) /* we are using privs */ 428 #endif 429 { 430 /* 431 * Set the real uid and transfer proc count to new user. 432 */ 433 if (uid != pc->p_ruid) { 434 change_ruid(p, uid); 435 setsugid(p); 436 } 437 /* 438 * Set saved uid 439 * 440 * XXX always set saved uid even if not _POSIX_SAVED_IDS, as 441 * the security of seteuid() depends on it. B.4.2.2 says it 442 * is important that we should do this. 443 */ 444 if (pc->p_svuid != uid) { 445 pc->p_svuid = uid; 446 setsugid(p); 447 } 448 } 449 450 /* 451 * In all permitted cases, we are changing the euid. 452 * Copy credentials so other references do not see our changes. 453 */ 454 if (pc->pc_ucred->cr_uid != uid) { 455 change_euid(p, uid); 456 setsugid(p); 457 } 458 return (0); 459 } 460 461 #ifndef _SYS_SYSPROTO_H_ 462 struct seteuid_args { 463 uid_t euid; 464 }; 465 #endif 466 /* ARGSUSED */ 467 int 468 seteuid(p, uap) 469 struct proc *p; 470 struct seteuid_args *uap; 471 { 472 register struct pcred *pc = p->p_cred; 473 register uid_t euid; 474 int error; 475 476 euid = uap->euid; 477 if (euid != pc->p_ruid && /* allow seteuid(getuid()) */ 478 euid != pc->p_svuid && /* allow seteuid(saved uid) */ 479 (error = suser_xxx(0, p, PRISON_ROOT))) 480 return (error); 481 /* 482 * Everything's okay, do it. Copy credentials so other references do 483 * not see our changes. 484 */ 485 if (pc->pc_ucred->cr_uid != euid) { 486 change_euid(p, euid); 487 setsugid(p); 488 } 489 return (0); 490 } 491 492 #ifndef _SYS_SYSPROTO_H_ 493 struct setgid_args { 494 gid_t gid; 495 }; 496 #endif 497 /* ARGSUSED */ 498 int 499 setgid(p, uap) 500 struct proc *p; 501 struct setgid_args *uap; 502 { 503 register struct pcred *pc = p->p_cred; 504 register gid_t gid; 505 int error; 506 507 /* 508 * See if we have "permission" by POSIX 1003.1 rules. 509 * 510 * Note that setgid(getegid()) is a special case of 511 * "appropriate privileges" in appendix B.4.2.2. We need 512 * to use this clause to be compatable with traditional BSD 513 * semantics. Basically, it means that "setgid(xx)" sets all 514 * three id's (assuming you have privs). 515 * 516 * For notes on the logic here, see setuid() above. 517 */ 518 gid = uap->gid; 519 if (gid != pc->p_rgid && /* allow setgid(getgid()) */ 520 #ifdef _POSIX_SAVED_IDS 521 gid != pc->p_svgid && /* allow setgid(saved gid) */ 522 #endif 523 #ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */ 524 gid != pc->pc_ucred->cr_groups[0] && /* allow setgid(getegid()) */ 525 #endif 526 (error = suser_xxx(0, p, PRISON_ROOT))) 527 return (error); 528 529 #ifdef _POSIX_SAVED_IDS 530 /* 531 * Do we have "appropriate privileges" (are we root or gid == egid) 532 * If so, we are changing the real uid and saved gid. 533 */ 534 if ( 535 #ifdef POSIX_APPENDIX_B_4_2_2 /* use the clause from B.4.2.2 */ 536 gid == pc->pc_ucred->cr_groups[0] || 537 #endif 538 suser_xxx(0, p, PRISON_ROOT) == 0) /* we are using privs */ 539 #endif 540 { 541 /* 542 * Set real gid 543 */ 544 if (pc->p_rgid != gid) { 545 pc->p_rgid = gid; 546 setsugid(p); 547 } 548 /* 549 * Set saved gid 550 * 551 * XXX always set saved gid even if not _POSIX_SAVED_IDS, as 552 * the security of setegid() depends on it. B.4.2.2 says it 553 * is important that we should do this. 554 */ 555 if (pc->p_svgid != gid) { 556 pc->p_svgid = gid; 557 setsugid(p); 558 } 559 } 560 /* 561 * In all cases permitted cases, we are changing the egid. 562 * Copy credentials so other references do not see our changes. 563 */ 564 if (pc->pc_ucred->cr_groups[0] != gid) { 565 pc->pc_ucred = crcopy(pc->pc_ucred); 566 pc->pc_ucred->cr_groups[0] = gid; 567 setsugid(p); 568 } 569 return (0); 570 } 571 572 #ifndef _SYS_SYSPROTO_H_ 573 struct setegid_args { 574 gid_t egid; 575 }; 576 #endif 577 /* ARGSUSED */ 578 int 579 setegid(p, uap) 580 struct proc *p; 581 struct setegid_args *uap; 582 { 583 register struct pcred *pc = p->p_cred; 584 register gid_t egid; 585 int error; 586 587 egid = uap->egid; 588 if (egid != pc->p_rgid && /* allow setegid(getgid()) */ 589 egid != pc->p_svgid && /* allow setegid(saved gid) */ 590 (error = suser_xxx(0, p, PRISON_ROOT))) 591 return (error); 592 if (pc->pc_ucred->cr_groups[0] != egid) { 593 pc->pc_ucred = crcopy(pc->pc_ucred); 594 pc->pc_ucred->cr_groups[0] = egid; 595 setsugid(p); 596 } 597 return (0); 598 } 599 600 #ifndef _SYS_SYSPROTO_H_ 601 struct setgroups_args { 602 u_int gidsetsize; 603 gid_t *gidset; 604 }; 605 #endif 606 /* ARGSUSED */ 607 int 608 setgroups(p, uap) 609 struct proc *p; 610 struct setgroups_args *uap; 611 { 612 register struct pcred *pc = p->p_cred; 613 register u_int ngrp; 614 int error; 615 616 if ((error = suser_xxx(0, p, PRISON_ROOT))) 617 return (error); 618 ngrp = uap->gidsetsize; 619 if (ngrp > NGROUPS) 620 return (EINVAL); 621 /* 622 * XXX A little bit lazy here. We could test if anything has 623 * changed before crcopy() and setting P_SUGID. 624 */ 625 pc->pc_ucred = crcopy(pc->pc_ucred); 626 if (ngrp < 1) { 627 /* 628 * setgroups(0, NULL) is a legitimate way of clearing the 629 * groups vector on non-BSD systems (which generally do not 630 * have the egid in the groups[0]). We risk security holes 631 * when running non-BSD software if we do not do the same. 632 */ 633 pc->pc_ucred->cr_ngroups = 1; 634 } else { 635 if ((error = copyin((caddr_t)uap->gidset, 636 (caddr_t)pc->pc_ucred->cr_groups, ngrp * sizeof(gid_t)))) 637 return (error); 638 pc->pc_ucred->cr_ngroups = ngrp; 639 } 640 setsugid(p); 641 return (0); 642 } 643 644 #ifndef _SYS_SYSPROTO_H_ 645 struct setreuid_args { 646 uid_t ruid; 647 uid_t euid; 648 }; 649 #endif 650 /* ARGSUSED */ 651 int 652 setreuid(p, uap) 653 register struct proc *p; 654 struct setreuid_args *uap; 655 { 656 register struct pcred *pc = p->p_cred; 657 register uid_t ruid, euid; 658 int error; 659 660 ruid = uap->ruid; 661 euid = uap->euid; 662 if (((ruid != (uid_t)-1 && ruid != pc->p_ruid && ruid != pc->p_svuid) || 663 (euid != (uid_t)-1 && euid != pc->pc_ucred->cr_uid && 664 euid != pc->p_ruid && euid != pc->p_svuid)) && 665 (error = suser_xxx(0, p, PRISON_ROOT)) != 0) 666 return (error); 667 668 if (euid != (uid_t)-1 && pc->pc_ucred->cr_uid != euid) { 669 change_euid(p, euid); 670 setsugid(p); 671 } 672 if (ruid != (uid_t)-1 && pc->p_ruid != ruid) { 673 change_ruid(p, ruid); 674 setsugid(p); 675 } 676 if ((ruid != (uid_t)-1 || pc->pc_ucred->cr_uid != pc->p_ruid) && 677 pc->p_svuid != pc->pc_ucred->cr_uid) { 678 pc->p_svuid = pc->pc_ucred->cr_uid; 679 setsugid(p); 680 } 681 return (0); 682 } 683 684 #ifndef _SYS_SYSPROTO_H_ 685 struct setregid_args { 686 gid_t rgid; 687 gid_t egid; 688 }; 689 #endif 690 /* ARGSUSED */ 691 int 692 setregid(p, uap) 693 register struct proc *p; 694 struct setregid_args *uap; 695 { 696 register struct pcred *pc = p->p_cred; 697 register gid_t rgid, egid; 698 int error; 699 700 rgid = uap->rgid; 701 egid = uap->egid; 702 if (((rgid != (gid_t)-1 && rgid != pc->p_rgid && rgid != pc->p_svgid) || 703 (egid != (gid_t)-1 && egid != pc->pc_ucred->cr_groups[0] && 704 egid != pc->p_rgid && egid != pc->p_svgid)) && 705 (error = suser_xxx(0, p, PRISON_ROOT)) != 0) 706 return (error); 707 708 if (egid != (gid_t)-1 && pc->pc_ucred->cr_groups[0] != egid) { 709 pc->pc_ucred = crcopy(pc->pc_ucred); 710 pc->pc_ucred->cr_groups[0] = egid; 711 setsugid(p); 712 } 713 if (rgid != (gid_t)-1 && pc->p_rgid != rgid) { 714 pc->p_rgid = rgid; 715 setsugid(p); 716 } 717 if ((rgid != (gid_t)-1 || pc->pc_ucred->cr_groups[0] != pc->p_rgid) && 718 pc->p_svgid != pc->pc_ucred->cr_groups[0]) { 719 pc->p_svgid = pc->pc_ucred->cr_groups[0]; 720 setsugid(p); 721 } 722 return (0); 723 } 724 725 /* 726 * setresuid(ruid, euid, suid) is like setreuid except control over the 727 * saved uid is explicit. 728 */ 729 730 #ifndef _SYS_SYSPROTO_H_ 731 struct setresuid_args { 732 uid_t ruid; 733 uid_t euid; 734 uid_t suid; 735 }; 736 #endif 737 /* ARGSUSED */ 738 int 739 setresuid(p, uap) 740 register struct proc *p; 741 struct setresuid_args *uap; 742 { 743 register struct pcred *pc = p->p_cred; 744 register uid_t ruid, euid, suid; 745 int error; 746 747 ruid = uap->ruid; 748 euid = uap->euid; 749 suid = uap->suid; 750 if (((ruid != (uid_t)-1 && ruid != pc->p_ruid && ruid != pc->p_svuid && 751 ruid != pc->pc_ucred->cr_uid) || 752 (euid != (uid_t)-1 && euid != pc->p_ruid && euid != pc->p_svuid && 753 euid != pc->pc_ucred->cr_uid) || 754 (suid != (uid_t)-1 && suid != pc->p_ruid && suid != pc->p_svuid && 755 suid != pc->pc_ucred->cr_uid)) && 756 (error = suser_xxx(0, p, PRISON_ROOT)) != 0) 757 return (error); 758 if (euid != (uid_t)-1 && pc->pc_ucred->cr_uid != euid) { 759 change_euid(p, euid); 760 setsugid(p); 761 } 762 if (ruid != (uid_t)-1 && pc->p_ruid != ruid) { 763 change_ruid(p, ruid); 764 setsugid(p); 765 } 766 if (suid != (uid_t)-1 && pc->p_svuid != suid) { 767 pc->p_svuid = suid; 768 setsugid(p); 769 } 770 return (0); 771 } 772 773 /* 774 * setresgid(rgid, egid, sgid) is like setregid except control over the 775 * saved gid is explicit. 776 */ 777 778 #ifndef _SYS_SYSPROTO_H_ 779 struct setresgid_args { 780 gid_t rgid; 781 gid_t egid; 782 gid_t sgid; 783 }; 784 #endif 785 /* ARGSUSED */ 786 int 787 setresgid(p, uap) 788 register struct proc *p; 789 struct setresgid_args *uap; 790 { 791 register struct pcred *pc = p->p_cred; 792 register gid_t rgid, egid, sgid; 793 int error; 794 795 rgid = uap->rgid; 796 egid = uap->egid; 797 sgid = uap->sgid; 798 if (((rgid != (gid_t)-1 && rgid != pc->p_rgid && rgid != pc->p_svgid && 799 rgid != pc->pc_ucred->cr_groups[0]) || 800 (egid != (gid_t)-1 && egid != pc->p_rgid && egid != pc->p_svgid && 801 egid != pc->pc_ucred->cr_groups[0]) || 802 (sgid != (gid_t)-1 && sgid != pc->p_rgid && sgid != pc->p_svgid && 803 sgid != pc->pc_ucred->cr_groups[0])) && 804 (error = suser_xxx(0, p, PRISON_ROOT)) != 0) 805 return (error); 806 807 if (egid != (gid_t)-1 && pc->pc_ucred->cr_groups[0] != egid) { 808 pc->pc_ucred = crcopy(pc->pc_ucred); 809 pc->pc_ucred->cr_groups[0] = egid; 810 setsugid(p); 811 } 812 if (rgid != (gid_t)-1 && pc->p_rgid != rgid) { 813 pc->p_rgid = rgid; 814 setsugid(p); 815 } 816 if (sgid != (gid_t)-1 && pc->p_svgid != sgid) { 817 pc->p_svgid = sgid; 818 setsugid(p); 819 } 820 return (0); 821 } 822 823 #ifndef _SYS_SYSPROTO_H_ 824 struct getresuid_args { 825 uid_t *ruid; 826 uid_t *euid; 827 uid_t *suid; 828 }; 829 #endif 830 /* ARGSUSED */ 831 int 832 getresuid(p, uap) 833 register struct proc *p; 834 struct getresuid_args *uap; 835 { 836 struct pcred *pc = p->p_cred; 837 int error1 = 0, error2 = 0, error3 = 0; 838 839 if (uap->ruid) 840 error1 = copyout((caddr_t)&pc->p_ruid, 841 (caddr_t)uap->ruid, sizeof(pc->p_ruid)); 842 if (uap->euid) 843 error2 = copyout((caddr_t)&pc->pc_ucred->cr_uid, 844 (caddr_t)uap->euid, sizeof(pc->pc_ucred->cr_uid)); 845 if (uap->suid) 846 error3 = copyout((caddr_t)&pc->p_svuid, 847 (caddr_t)uap->suid, sizeof(pc->p_svuid)); 848 return error1 ? error1 : (error2 ? error2 : error3); 849 } 850 851 #ifndef _SYS_SYSPROTO_H_ 852 struct getresgid_args { 853 gid_t *rgid; 854 gid_t *egid; 855 gid_t *sgid; 856 }; 857 #endif 858 /* ARGSUSED */ 859 int 860 getresgid(p, uap) 861 register struct proc *p; 862 struct getresgid_args *uap; 863 { 864 struct pcred *pc = p->p_cred; 865 int error1 = 0, error2 = 0, error3 = 0; 866 867 if (uap->rgid) 868 error1 = copyout((caddr_t)&pc->p_rgid, 869 (caddr_t)uap->rgid, sizeof(pc->p_rgid)); 870 if (uap->egid) 871 error2 = copyout((caddr_t)&pc->pc_ucred->cr_groups[0], 872 (caddr_t)uap->egid, sizeof(pc->pc_ucred->cr_groups[0])); 873 if (uap->sgid) 874 error3 = copyout((caddr_t)&pc->p_svgid, 875 (caddr_t)uap->sgid, sizeof(pc->p_svgid)); 876 return error1 ? error1 : (error2 ? error2 : error3); 877 } 878 879 880 #ifndef _SYS_SYSPROTO_H_ 881 struct issetugid_args { 882 int dummy; 883 }; 884 #endif 885 /* ARGSUSED */ 886 int 887 issetugid(p, uap) 888 register struct proc *p; 889 struct issetugid_args *uap; 890 { 891 /* 892 * Note: OpenBSD sets a P_SUGIDEXEC flag set at execve() time, 893 * we use P_SUGID because we consider changing the owners as 894 * "tainting" as well. 895 * This is significant for procs that start as root and "become" 896 * a user without an exec - programs cannot know *everything* 897 * that libc *might* have put in their data segment. 898 */ 899 p->p_retval[0] = (p->p_flag & P_SUGID) ? 1 : 0; 900 return (0); 901 } 902 903 /* 904 * Check if gid is a member of the group set. 905 */ 906 int 907 groupmember(gid, cred) 908 gid_t gid; 909 register struct ucred *cred; 910 { 911 register gid_t *gp; 912 gid_t *egp; 913 914 egp = &(cred->cr_groups[cred->cr_ngroups]); 915 for (gp = cred->cr_groups; gp < egp; gp++) 916 if (*gp == gid) 917 return (1); 918 return (0); 919 } 920 921 static int suser_permitted = 1; 922 923 SYSCTL_INT(_kern, OID_AUTO, suser_permitted, CTLFLAG_RW, &suser_permitted, 0, 924 "processes with uid 0 have privilege"); 925 926 /* 927 * Test whether the specified credentials imply "super-user" 928 * privilege; if so, and we have accounting info, set the flag 929 * indicating use of super-powers. 930 * Returns 0 or error. 931 */ 932 int 933 suser(p) 934 const struct proc *p; 935 { 936 return suser_xxx(0, p, 0); 937 } 938 939 int 940 suser_xxx(cred, proc, flag) 941 const struct ucred *cred; 942 const struct proc *proc; 943 int flag; 944 { 945 if (!suser_permitted) 946 return (EPERM); 947 if (!cred && !proc) { 948 printf("suser_xxx(): THINK!\n"); 949 return (EPERM); 950 } 951 if (!cred) 952 cred = proc->p_ucred; 953 if (cred->cr_uid != 0) 954 return (EPERM); 955 if (proc && proc->p_prison && !(flag & PRISON_ROOT)) 956 return (EPERM); 957 return (0); 958 } 959 960 static int 961 p_cansee(const struct proc *p1, const struct proc *p2, int *privused) 962 { 963 964 if (privused != NULL) 965 *privused = 0; 966 967 if (!PRISON_CHECK(p1, p2)) 968 return (ESRCH); 969 970 if (!ps_showallprocs && p1->p_ucred->cr_uid != p2->p_ucred->cr_uid) { 971 if (suser_xxx(NULL, p1, PRISON_ROOT) == 0) { 972 if (privused != NULL) 973 *privused = 1; 974 return (0); 975 } 976 return (ESRCH); 977 } 978 979 return (0); 980 } 981 982 static int 983 p_cankill(const struct proc *p1, const struct proc *p2, int *privused) 984 { 985 986 if (privused != NULL) 987 *privused = 0; 988 989 if (p1 == p2) 990 return (0); 991 992 if (!PRISON_CHECK(p1, p2)) 993 return (ESRCH); 994 995 if (p1->p_cred->p_ruid == p2->p_cred->p_ruid) 996 return (0); 997 if (p1->p_ucred->cr_uid == p2->p_cred->p_ruid) 998 return (0); 999 /* 1000 * XXX should a process be able to affect another process 1001 * acting as the same uid (i.e., a userland nfsd or the like?) 1002 */ 1003 if (p1->p_cred->p_ruid == p2->p_ucred->cr_uid) 1004 return (0); 1005 if (p1->p_ucred->cr_uid == p2->p_ucred->cr_uid) 1006 return (0); 1007 1008 if (!suser_xxx(0, p1, PRISON_ROOT)) { 1009 if (privused != NULL) 1010 *privused = 1; 1011 return (0); 1012 } 1013 1014 #ifdef CAPABILITIES 1015 if (!cap_check_xxx(0, p1, CAP_KILL, PRISON_ROOT)) { 1016 if (privused != NULL) 1017 *privused = 1; 1018 return (0); 1019 } 1020 #endif 1021 1022 return (EPERM); 1023 } 1024 1025 static int 1026 p_cansched(const struct proc *p1, const struct proc *p2, int *privused) 1027 { 1028 1029 if (privused != NULL) 1030 *privused = 0; 1031 1032 if (p1 == p2) 1033 return (0); 1034 1035 if (!PRISON_CHECK(p1, p2)) 1036 return (ESRCH); 1037 1038 if (p1->p_cred->p_ruid == p2->p_cred->p_ruid) 1039 return (0); 1040 if (p1->p_ucred->cr_uid == p2->p_cred->p_ruid) 1041 return (0); 1042 /* 1043 * XXX should a process be able to affect another process 1044 * acting as the same uid (i.e., a userland nfsd or the like?) 1045 */ 1046 if (p1->p_cred->p_ruid == p2->p_ucred->cr_uid) 1047 return (0); 1048 if (p1->p_ucred->cr_uid == p2->p_ucred->cr_uid) 1049 return (0); 1050 1051 if (!suser_xxx(0, p1, PRISON_ROOT)) { 1052 if (privused != NULL) 1053 *privused = 1; 1054 return (0); 1055 } 1056 1057 #ifdef CAPABILITIES 1058 if (!cap_check_xxx(0, p1, CAP_SYS_NICE, PRISON_ROOT)) { 1059 if (privused != NULL) 1060 *privused = 1; 1061 return (0); 1062 } 1063 #endif 1064 1065 return (EPERM); 1066 } 1067 1068 static int 1069 p_candebug(const struct proc *p1, const struct proc *p2, int *privused) 1070 { 1071 int error; 1072 1073 if (privused != NULL) 1074 *privused = 0; 1075 1076 /* XXX it is authorized, but semantics don't permit it */ 1077 if (p1 == p2) 1078 return (0); 1079 1080 if (!PRISON_CHECK(p1, p2)) 1081 return (ESRCH); 1082 1083 /* not owned by you, has done setuid (unless you're root) */ 1084 /* add a CAP_SYS_PTRACE here? */ 1085 if (p1->p_cred->pc_ucred->cr_uid != p2->p_cred->p_ruid || 1086 p1->p_cred->p_ruid != p2->p_cred->p_ruid || 1087 p1->p_cred->p_svuid != p2->p_cred->p_ruid || 1088 p2->p_flag & P_SUGID) { 1089 if ((error = suser_xxx(0, p1, PRISON_ROOT))) 1090 return (error); 1091 if (privused != NULL) 1092 *privused = 1; 1093 } 1094 1095 /* can't trace init when securelevel > 0 */ 1096 if (securelevel > 0 && p2->p_pid == 1) 1097 return (EPERM); 1098 1099 return (0); 1100 } 1101 1102 int 1103 p_can(const struct proc *p1, const struct proc *p2, int operation, 1104 int *privused) 1105 { 1106 1107 switch(operation) { 1108 case P_CAN_SEE: 1109 return (p_cansee(p1, p2, privused)); 1110 1111 case P_CAN_KILL: 1112 return (p_cankill(p1, p2, privused)); 1113 1114 case P_CAN_SCHED: 1115 return (p_cansched(p1, p2, privused)); 1116 1117 case P_CAN_DEBUG: 1118 return (p_candebug(p1, p2, privused)); 1119 1120 default: 1121 panic("p_can: invalid operation"); 1122 } 1123 } 1124 1125 1126 /* 1127 * Allocate a zeroed cred structure. 1128 */ 1129 struct ucred * 1130 crget() 1131 { 1132 register struct ucred *cr; 1133 1134 MALLOC(cr, struct ucred *, sizeof(*cr), M_CRED, M_WAITOK|M_ZERO); 1135 cr->cr_ref = 1; 1136 mtx_init(&cr->cr_mtx, "ucred", MTX_DEF); 1137 return (cr); 1138 } 1139 1140 /* 1141 * Free a cred structure. 1142 * Throws away space when ref count gets to 0. 1143 */ 1144 void 1145 crfree(cr) 1146 struct ucred *cr; 1147 { 1148 1149 mtx_enter(&cr->cr_mtx, MTX_DEF); 1150 if (--cr->cr_ref == 0) { 1151 mtx_destroy(&cr->cr_mtx); 1152 /* 1153 * Some callers of crget(), such as nfs_statfs(), 1154 * allocate a temporary credential, but don't 1155 * allocate a uidinfo structure. 1156 */ 1157 if (cr->cr_uidinfo != NULL) 1158 uifree(cr->cr_uidinfo); 1159 FREE((caddr_t)cr, M_CRED); 1160 } else { 1161 mtx_exit(&cr->cr_mtx, MTX_DEF); 1162 } 1163 } 1164 1165 /* 1166 * Copy cred structure to a new one and free the old one. 1167 */ 1168 struct ucred * 1169 crcopy(cr) 1170 struct ucred *cr; 1171 { 1172 struct ucred *newcr; 1173 1174 mtx_enter(&cr->cr_mtx, MTX_DEF); 1175 if (cr->cr_ref == 1) { 1176 mtx_exit(&cr->cr_mtx, MTX_DEF); 1177 return (cr); 1178 } 1179 mtx_exit(&cr->cr_mtx, MTX_DEF); 1180 newcr = crdup(cr); 1181 crfree(cr); 1182 return (newcr); 1183 } 1184 1185 /* 1186 * Dup cred struct to a new held one. 1187 */ 1188 struct ucred * 1189 crdup(cr) 1190 struct ucred *cr; 1191 { 1192 struct ucred *newcr; 1193 1194 MALLOC(newcr, struct ucred *, sizeof(*cr), M_CRED, M_WAITOK); 1195 *newcr = *cr; 1196 mtx_init(&newcr->cr_mtx, "ucred", MTX_DEF); 1197 uihold(newcr->cr_uidinfo); 1198 newcr->cr_ref = 1; 1199 return (newcr); 1200 } 1201 1202 /* 1203 * Get login name, if available. 1204 */ 1205 #ifndef _SYS_SYSPROTO_H_ 1206 struct getlogin_args { 1207 char *namebuf; 1208 u_int namelen; 1209 }; 1210 #endif 1211 /* ARGSUSED */ 1212 int 1213 getlogin(p, uap) 1214 struct proc *p; 1215 struct getlogin_args *uap; 1216 { 1217 1218 if (uap->namelen > MAXLOGNAME) 1219 uap->namelen = MAXLOGNAME; 1220 return (copyout((caddr_t) p->p_pgrp->pg_session->s_login, 1221 (caddr_t) uap->namebuf, uap->namelen)); 1222 } 1223 1224 /* 1225 * Set login name. 1226 */ 1227 #ifndef _SYS_SYSPROTO_H_ 1228 struct setlogin_args { 1229 char *namebuf; 1230 }; 1231 #endif 1232 /* ARGSUSED */ 1233 int 1234 setlogin(p, uap) 1235 struct proc *p; 1236 struct setlogin_args *uap; 1237 { 1238 int error; 1239 char logintmp[MAXLOGNAME]; 1240 1241 if ((error = suser_xxx(0, p, PRISON_ROOT))) 1242 return (error); 1243 error = copyinstr((caddr_t) uap->namebuf, (caddr_t) logintmp, 1244 sizeof(logintmp), (size_t *)0); 1245 if (error == ENAMETOOLONG) 1246 error = EINVAL; 1247 else if (!error) 1248 (void) memcpy(p->p_pgrp->pg_session->s_login, logintmp, 1249 sizeof(logintmp)); 1250 return (error); 1251 } 1252 1253 void 1254 setsugid(p) 1255 struct proc *p; 1256 { 1257 p->p_flag |= P_SUGID; 1258 if (!(p->p_pfsflags & PF_ISUGID)) 1259 p->p_stops = 0; 1260 } 1261 1262 /* 1263 * Helper function to change the effective uid of a process 1264 */ 1265 void 1266 change_euid(p, euid) 1267 struct proc *p; 1268 uid_t euid; 1269 { 1270 struct pcred *pc; 1271 struct uidinfo *uip; 1272 1273 pc = p->p_cred; 1274 /* 1275 * crcopy is essentially a NOP if ucred has a reference count 1276 * of 1, which is true if it has already been copied. 1277 */ 1278 pc->pc_ucred = crcopy(pc->pc_ucred); 1279 uip = pc->pc_ucred->cr_uidinfo; 1280 pc->pc_ucred->cr_uid = euid; 1281 pc->pc_ucred->cr_uidinfo = uifind(euid); 1282 uifree(uip); 1283 } 1284 1285 /* 1286 * Helper function to change the real uid of a process 1287 * 1288 * The per-uid process count for this process is transfered from 1289 * the old uid to the new uid. 1290 */ 1291 void 1292 change_ruid(p, ruid) 1293 struct proc *p; 1294 uid_t ruid; 1295 { 1296 struct pcred *pc; 1297 struct uidinfo *uip; 1298 1299 pc = p->p_cred; 1300 (void)chgproccnt(pc->p_uidinfo, -1, 0); 1301 uip = pc->p_uidinfo; 1302 /* It is assumed that pcred is not shared between processes */ 1303 pc->p_ruid = ruid; 1304 pc->p_uidinfo = uifind(ruid); 1305 (void)chgproccnt(pc->p_uidinfo, 1, 0); 1306 uifree(uip); 1307 } 1308