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