kern_prot.c revision 75893
1127668Sbms/* 2127668Sbms * Copyright (c) 1982, 1986, 1989, 1990, 1991, 1993 3127668Sbms * The Regents of the University of California. All rights reserved. 4127668Sbms * (c) UNIX System Laboratories, Inc. 5127668Sbms * All or some portions of this file are derived from material licensed 6127668Sbms * to the University of California by American Telephone and Telegraph 7127668Sbms * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8127668Sbms * the permission of UNIX System Laboratories, Inc. 9127668Sbms * 10127668Sbms * Redistribution and use in source and binary forms, with or without 11127668Sbms * modification, are permitted provided that the following conditions 12127668Sbms * are met: 13127668Sbms * 1. Redistributions of source code must retain the above copyright 14127668Sbms * notice, this list of conditions and the following disclaimer. 15127668Sbms * 2. Redistributions in binary form must reproduce the above copyright 16127668Sbms * notice, this list of conditions and the following disclaimer in the 17127668Sbms * documentation and/or other materials provided with the distribution. 18127668Sbms * 3. All advertising materials mentioning features or use of this software 19127668Sbms * must display the following acknowledgement: 20127668Sbms * This product includes software developed by the University of 21127668Sbms * California, Berkeley and its contributors. 22127668Sbms * 4. Neither the name of the University nor the names of its contributors 23127668Sbms * may be used to endorse or promote products derived from this software 24127668Sbms * without specific prior written permission. 25127668Sbms * 26127668Sbms * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27127668Sbms * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28127668Sbms * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29127668Sbms * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30127668Sbms * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31127668Sbms * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32214478Srpaulo * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33127668Sbms * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34127668Sbms * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35127668Sbms * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36127668Sbms * SUCH DAMAGE. 37127668Sbms * 38190207Srpaulo * @(#)kern_prot.c 8.6 (Berkeley) 1/21/94 39190207Srpaulo * $FreeBSD: head/sys/kern/kern_prot.c 75893 2001-04-24 00:51:53Z jhb $ 40190207Srpaulo */ 41190207Srpaulo 42190207Srpaulo/* 43190207Srpaulo * System calls related to processes and protection 44127668Sbms */ 45127668Sbms 46127668Sbms#include "opt_compat.h" 47127668Sbms#include "opt_global.h" 48127668Sbms 49127668Sbms#include <sys/param.h> 50127668Sbms#include <sys/acct.h> 51127668Sbms#include <sys/systm.h> 52127668Sbms#include <sys/sysproto.h> 53127668Sbms#include <sys/kernel.h> 54127668Sbms#include <sys/lock.h> 55127668Sbms#include <sys/proc.h> 56127668Sbms#include <sys/malloc.h> 57127668Sbms#include <sys/pioctl.h> 58127668Sbms#include <sys/resourcevar.h> 59127668Sbms#include <sys/sysctl.h> 60127668Sbms#include <sys/jail.h> 61127668Sbms 62127668Sbmsstatic MALLOC_DEFINE(M_CRED, "cred", "credentials"); 63127668Sbms 64127668Sbms#ifndef _SYS_SYSPROTO_H_ 65127668Sbmsstruct getpid_args { 66127668Sbms int dummy; 67127668Sbms}; 68127668Sbms#endif 69127668Sbms 70127668Sbms/* 71127668Sbms * getpid - MP SAFE 72127668Sbms */ 73127668Sbms 74127668Sbms/* ARGSUSED */ 75127668Sbmsint 76127668Sbmsgetpid(p, uap) 77127668Sbms struct proc *p; 78127668Sbms struct getpid_args *uap; 79127668Sbms{ 80127668Sbms 81127668Sbms p->p_retval[0] = p->p_pid; 82127668Sbms#if defined(COMPAT_43) || defined(COMPAT_SUNOS) 83127668Sbms PROC_LOCK(p); 84127668Sbms p->p_retval[1] = p->p_pptr->p_pid; 85127668Sbms PROC_UNLOCK(p); 86127668Sbms#endif 87127668Sbms return (0); 88} 89 90/* 91 * getppid - MP SAFE 92 */ 93 94#ifndef _SYS_SYSPROTO_H_ 95struct getppid_args { 96 int dummy; 97}; 98#endif 99/* ARGSUSED */ 100int 101getppid(p, uap) 102 struct proc *p; 103 struct getppid_args *uap; 104{ 105 106 PROC_LOCK(p); 107 p->p_retval[0] = p->p_pptr->p_pid; 108 PROC_UNLOCK(p); 109 return (0); 110} 111 112/* 113 * Get process group ID; note that POSIX getpgrp takes no parameter 114 * 115 * MP SAFE 116 */ 117#ifndef _SYS_SYSPROTO_H_ 118struct getpgrp_args { 119 int dummy; 120}; 121#endif 122 123int 124getpgrp(p, uap) 125 struct proc *p; 126 struct getpgrp_args *uap; 127{ 128 129 p->p_retval[0] = p->p_pgrp->pg_id; 130 return (0); 131} 132 133/* Get an arbitary pid's process group id */ 134#ifndef _SYS_SYSPROTO_H_ 135struct getpgid_args { 136 pid_t pid; 137}; 138#endif 139 140int 141getpgid(p, uap) 142 struct proc *p; 143 struct getpgid_args *uap; 144{ 145 struct proc *pt; 146 int error; 147 148 if (uap->pid == 0) 149 p->p_retval[0] = p->p_pgrp->pg_id; 150 else { 151 if ((pt = pfind(uap->pid)) == NULL) 152 return ESRCH; 153 if ((error = p_can(p, pt, P_CAN_SEE, NULL))) { 154 PROC_UNLOCK(pt); 155 return (error); 156 } 157 p->p_retval[0] = pt->p_pgrp->pg_id; 158 PROC_UNLOCK(pt); 159 } 160 return 0; 161} 162 163/* 164 * Get an arbitary pid's session id. 165 */ 166#ifndef _SYS_SYSPROTO_H_ 167struct getsid_args { 168 pid_t pid; 169}; 170#endif 171 172int 173getsid(p, uap) 174 struct proc *p; 175 struct getsid_args *uap; 176{ 177 struct proc *pt; 178 int error; 179 180 if (uap->pid == 0) 181 p->p_retval[0] = p->p_session->s_sid; 182 else { 183 if ((pt = pfind(uap->pid)) == NULL) 184 return ESRCH; 185 if ((error = p_can(p, pt, P_CAN_SEE, NULL))) { 186 PROC_UNLOCK(pt); 187 return (error); 188 } 189 p->p_retval[0] = pt->p_session->s_sid; 190 PROC_UNLOCK(pt); 191 } 192 return 0; 193} 194 195 196/* 197 * getuid() - MP SAFE 198 */ 199#ifndef _SYS_SYSPROTO_H_ 200struct getuid_args { 201 int dummy; 202}; 203#endif 204 205/* ARGSUSED */ 206int 207getuid(p, uap) 208 struct proc *p; 209 struct getuid_args *uap; 210{ 211 212 p->p_retval[0] = p->p_cred->p_ruid; 213#if defined(COMPAT_43) || defined(COMPAT_SUNOS) 214 p->p_retval[1] = p->p_ucred->cr_uid; 215#endif 216 return (0); 217} 218 219/* 220 * geteuid() - MP SAFE 221 */ 222#ifndef _SYS_SYSPROTO_H_ 223struct geteuid_args { 224 int dummy; 225}; 226#endif 227 228/* ARGSUSED */ 229int 230geteuid(p, uap) 231 struct proc *p; 232 struct geteuid_args *uap; 233{ 234 235 p->p_retval[0] = p->p_ucred->cr_uid; 236 return (0); 237} 238 239/* 240 * getgid() - MP SAFE 241 */ 242#ifndef _SYS_SYSPROTO_H_ 243struct getgid_args { 244 int dummy; 245}; 246#endif 247 248/* ARGSUSED */ 249int 250getgid(p, uap) 251 struct proc *p; 252 struct getgid_args *uap; 253{ 254 255 p->p_retval[0] = p->p_cred->p_rgid; 256#if defined(COMPAT_43) || defined(COMPAT_SUNOS) 257 p->p_retval[1] = p->p_ucred->cr_groups[0]; 258#endif 259 return (0); 260} 261 262/* 263 * Get effective group ID. The "egid" is groups[0], and could be obtained 264 * via getgroups. This syscall exists because it is somewhat painful to do 265 * correctly in a library function. 266 */ 267#ifndef _SYS_SYSPROTO_H_ 268struct getegid_args { 269 int dummy; 270}; 271#endif 272 273/* ARGSUSED */ 274int 275getegid(p, uap) 276 struct proc *p; 277 struct getegid_args *uap; 278{ 279 280 p->p_retval[0] = p->p_ucred->cr_groups[0]; 281 return (0); 282} 283 284#ifndef _SYS_SYSPROTO_H_ 285struct getgroups_args { 286 u_int gidsetsize; 287 gid_t *gidset; 288}; 289#endif 290int 291getgroups(p, uap) 292 struct proc *p; 293 register struct getgroups_args *uap; 294{ 295 register struct pcred *pc = p->p_cred; 296 register u_int ngrp; 297 int error; 298 299 if ((ngrp = uap->gidsetsize) == 0) { 300 p->p_retval[0] = pc->pc_ucred->cr_ngroups; 301 return (0); 302 } 303 if (ngrp < pc->pc_ucred->cr_ngroups) 304 return (EINVAL); 305 ngrp = pc->pc_ucred->cr_ngroups; 306 if ((error = copyout((caddr_t)pc->pc_ucred->cr_groups, 307 (caddr_t)uap->gidset, ngrp * sizeof(gid_t)))) 308 return (error); 309 p->p_retval[0] = ngrp; 310 return (0); 311} 312 313#ifndef _SYS_SYSPROTO_H_ 314struct setsid_args { 315 int dummy; 316}; 317#endif 318 319/* ARGSUSED */ 320int 321setsid(p, uap) 322 register struct proc *p; 323 struct setsid_args *uap; 324{ 325 326 if (p->p_pgid == p->p_pid || pgfind(p->p_pid)) { 327 return (EPERM); 328 } else { 329 (void)enterpgrp(p, p->p_pid, 1); 330 p->p_retval[0] = p->p_pid; 331 return (0); 332 } 333} 334 335/* 336 * set process group (setpgid/old setpgrp) 337 * 338 * caller does setpgid(targpid, targpgid) 339 * 340 * pid must be caller or child of caller (ESRCH) 341 * if a child 342 * pid must be in same session (EPERM) 343 * pid can't have done an exec (EACCES) 344 * if pgid != pid 345 * there must exist some pid in same session having pgid (EPERM) 346 * pid must not be session leader (EPERM) 347 */ 348#ifndef _SYS_SYSPROTO_H_ 349struct setpgid_args { 350 int pid; /* target process id */ 351 int pgid; /* target pgrp id */ 352}; 353#endif 354/* ARGSUSED */ 355int 356setpgid(curp, uap) 357 struct proc *curp; 358 register struct setpgid_args *uap; 359{ 360 register struct proc *targp; /* target process */ 361 register struct pgrp *pgrp; /* target pgrp */ 362 int error; 363 364 if (uap->pgid < 0) 365 return (EINVAL); 366 if (uap->pid != 0 && uap->pid != curp->p_pid) { 367 if ((targp = pfind(uap->pid)) == NULL || !inferior(targp)) { 368 if (targp) 369 PROC_UNLOCK(targp); 370 return (ESRCH); 371 } 372 if ((error = p_can(curproc, targp, P_CAN_SEE, NULL))) { 373 PROC_UNLOCK(targp); 374 return (error); 375 } 376 if (targp->p_pgrp == NULL || 377 targp->p_session != curp->p_session) { 378 PROC_UNLOCK(targp); 379 return (EPERM); 380 } 381 if (targp->p_flag & P_EXEC) { 382 PROC_UNLOCK(targp); 383 return (EACCES); 384 } 385 } else { 386 targp = curp; 387 PROC_LOCK(curp); /* XXX: not needed */ 388 } 389 if (SESS_LEADER(targp)) { 390 PROC_UNLOCK(targp); 391 return (EPERM); 392 } 393 if (uap->pgid == 0) 394 uap->pgid = targp->p_pid; 395 else if (uap->pgid != targp->p_pid) 396 if ((pgrp = pgfind(uap->pgid)) == 0 || 397 pgrp->pg_session != curp->p_session) { 398 PROC_UNLOCK(targp); 399 return (EPERM); 400 } 401 /* XXX: We should probably hold the lock across enterpgrp. */ 402 PROC_UNLOCK(targp); 403 return (enterpgrp(targp, uap->pgid, 0)); 404} 405 406/* 407 * Use the clause in B.4.2.2 that allows setuid/setgid to be 4.2/4.3BSD 408 * compatible. It says that setting the uid/gid to euid/egid is a special 409 * case of "appropriate privilege". Once the rules are expanded out, this 410 * basically means that setuid(nnn) sets all three id's, in all permitted 411 * cases unless _POSIX_SAVED_IDS is enabled. In that case, setuid(getuid()) 412 * does not set the saved id - this is dangerous for traditional BSD 413 * programs. For this reason, we *really* do not want to set 414 * _POSIX_SAVED_IDS and do not want to clear POSIX_APPENDIX_B_4_2_2. 415 */ 416#define POSIX_APPENDIX_B_4_2_2 417 418#ifndef _SYS_SYSPROTO_H_ 419struct setuid_args { 420 uid_t uid; 421}; 422#endif 423/* ARGSUSED */ 424int 425setuid(p, uap) 426 struct proc *p; 427 struct setuid_args *uap; 428{ 429 register struct pcred *pc = p->p_cred; 430 register uid_t uid; 431 int error; 432 433 /* 434 * See if we have "permission" by POSIX 1003.1 rules. 435 * 436 * Note that setuid(geteuid()) is a special case of 437 * "appropriate privileges" in appendix B.4.2.2. We need 438 * to use this clause to be compatible with traditional BSD 439 * semantics. Basically, it means that "setuid(xx)" sets all 440 * three id's (assuming you have privs). 441 * 442 * Notes on the logic. We do things in three steps. 443 * 1: We determine if the euid is going to change, and do EPERM 444 * right away. We unconditionally change the euid later if this 445 * test is satisfied, simplifying that part of the logic. 446 * 2: We determine if the real and/or saved uid's are going to 447 * change. Determined by compile options. 448 * 3: Change euid last. (after tests in #2 for "appropriate privs") 449 */ 450 uid = uap->uid; 451 if (uid != pc->p_ruid && /* allow setuid(getuid()) */ 452#ifdef _POSIX_SAVED_IDS 453 uid != pc->p_svuid && /* allow setuid(saved gid) */ 454#endif 455#ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */ 456 uid != pc->pc_ucred->cr_uid && /* allow setuid(geteuid()) */ 457#endif 458 (error = suser_xxx(0, p, PRISON_ROOT))) 459 return (error); 460 461#ifdef _POSIX_SAVED_IDS 462 /* 463 * Do we have "appropriate privileges" (are we root or uid == euid) 464 * If so, we are changing the real uid and/or saved uid. 465 */ 466 if ( 467#ifdef POSIX_APPENDIX_B_4_2_2 /* Use the clause from B.4.2.2 */ 468 uid == pc->pc_ucred->cr_uid || 469#endif 470 suser_xxx(0, p, PRISON_ROOT) == 0) /* we are using privs */ 471#endif 472 { 473 /* 474 * Set the real uid and transfer proc count to new user. 475 */ 476 if (uid != pc->p_ruid) { 477 change_ruid(p, uid); 478 setsugid(p); 479 } 480 /* 481 * Set saved uid 482 * 483 * XXX always set saved uid even if not _POSIX_SAVED_IDS, as 484 * the security of seteuid() depends on it. B.4.2.2 says it 485 * is important that we should do this. 486 */ 487 if (pc->p_svuid != uid) { 488 pc->p_svuid = uid; 489 setsugid(p); 490 } 491 } 492 493 /* 494 * In all permitted cases, we are changing the euid. 495 * Copy credentials so other references do not see our changes. 496 */ 497 if (pc->pc_ucred->cr_uid != uid) { 498 change_euid(p, uid); 499 setsugid(p); 500 } 501 return (0); 502} 503 504#ifndef _SYS_SYSPROTO_H_ 505struct seteuid_args { 506 uid_t euid; 507}; 508#endif 509/* ARGSUSED */ 510int 511seteuid(p, uap) 512 struct proc *p; 513 struct seteuid_args *uap; 514{ 515 register struct pcred *pc = p->p_cred; 516 register uid_t euid; 517 int error; 518 519 euid = uap->euid; 520 if (euid != pc->p_ruid && /* allow seteuid(getuid()) */ 521 euid != pc->p_svuid && /* allow seteuid(saved uid) */ 522 (error = suser_xxx(0, p, PRISON_ROOT))) 523 return (error); 524 /* 525 * Everything's okay, do it. Copy credentials so other references do 526 * not see our changes. 527 */ 528 if (pc->pc_ucred->cr_uid != euid) { 529 change_euid(p, euid); 530 setsugid(p); 531 } 532 return (0); 533} 534 535#ifndef _SYS_SYSPROTO_H_ 536struct setgid_args { 537 gid_t gid; 538}; 539#endif 540/* ARGSUSED */ 541int 542setgid(p, uap) 543 struct proc *p; 544 struct setgid_args *uap; 545{ 546 register struct pcred *pc = p->p_cred; 547 register gid_t gid; 548 int error; 549 550 /* 551 * See if we have "permission" by POSIX 1003.1 rules. 552 * 553 * Note that setgid(getegid()) is a special case of 554 * "appropriate privileges" in appendix B.4.2.2. We need 555 * to use this clause to be compatible with traditional BSD 556 * semantics. Basically, it means that "setgid(xx)" sets all 557 * three id's (assuming you have privs). 558 * 559 * For notes on the logic here, see setuid() above. 560 */ 561 gid = uap->gid; 562 if (gid != pc->p_rgid && /* allow setgid(getgid()) */ 563#ifdef _POSIX_SAVED_IDS 564 gid != pc->p_svgid && /* allow setgid(saved gid) */ 565#endif 566#ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */ 567 gid != pc->pc_ucred->cr_groups[0] && /* allow setgid(getegid()) */ 568#endif 569 (error = suser_xxx(0, p, PRISON_ROOT))) 570 return (error); 571 572#ifdef _POSIX_SAVED_IDS 573 /* 574 * Do we have "appropriate privileges" (are we root or gid == egid) 575 * If so, we are changing the real uid and saved gid. 576 */ 577 if ( 578#ifdef POSIX_APPENDIX_B_4_2_2 /* use the clause from B.4.2.2 */ 579 gid == pc->pc_ucred->cr_groups[0] || 580#endif 581 suser_xxx(0, p, PRISON_ROOT) == 0) /* we are using privs */ 582#endif 583 { 584 /* 585 * Set real gid 586 */ 587 if (pc->p_rgid != gid) { 588 pc->p_rgid = gid; 589 setsugid(p); 590 } 591 /* 592 * Set saved gid 593 * 594 * XXX always set saved gid even if not _POSIX_SAVED_IDS, as 595 * the security of setegid() depends on it. B.4.2.2 says it 596 * is important that we should do this. 597 */ 598 if (pc->p_svgid != gid) { 599 pc->p_svgid = gid; 600 setsugid(p); 601 } 602 } 603 /* 604 * In all cases permitted cases, we are changing the egid. 605 * Copy credentials so other references do not see our changes. 606 */ 607 if (pc->pc_ucred->cr_groups[0] != gid) { 608 pc->pc_ucred = crcopy(pc->pc_ucred); 609 pc->pc_ucred->cr_groups[0] = gid; 610 setsugid(p); 611 } 612 return (0); 613} 614 615#ifndef _SYS_SYSPROTO_H_ 616struct setegid_args { 617 gid_t egid; 618}; 619#endif 620/* ARGSUSED */ 621int 622setegid(p, uap) 623 struct proc *p; 624 struct setegid_args *uap; 625{ 626 register struct pcred *pc = p->p_cred; 627 register gid_t egid; 628 int error; 629 630 egid = uap->egid; 631 if (egid != pc->p_rgid && /* allow setegid(getgid()) */ 632 egid != pc->p_svgid && /* allow setegid(saved gid) */ 633 (error = suser_xxx(0, p, PRISON_ROOT))) 634 return (error); 635 if (pc->pc_ucred->cr_groups[0] != egid) { 636 pc->pc_ucred = crcopy(pc->pc_ucred); 637 pc->pc_ucred->cr_groups[0] = egid; 638 setsugid(p); 639 } 640 return (0); 641} 642 643#ifndef _SYS_SYSPROTO_H_ 644struct setgroups_args { 645 u_int gidsetsize; 646 gid_t *gidset; 647}; 648#endif 649/* ARGSUSED */ 650int 651setgroups(p, uap) 652 struct proc *p; 653 struct setgroups_args *uap; 654{ 655 register struct pcred *pc = p->p_cred; 656 register u_int ngrp; 657 int error; 658 659 if ((error = suser_xxx(0, p, PRISON_ROOT))) 660 return (error); 661 ngrp = uap->gidsetsize; 662 if (ngrp > NGROUPS) 663 return (EINVAL); 664 /* 665 * XXX A little bit lazy here. We could test if anything has 666 * changed before crcopy() and setting P_SUGID. 667 */ 668 pc->pc_ucred = crcopy(pc->pc_ucred); 669 if (ngrp < 1) { 670 /* 671 * setgroups(0, NULL) is a legitimate way of clearing the 672 * groups vector on non-BSD systems (which generally do not 673 * have the egid in the groups[0]). We risk security holes 674 * when running non-BSD software if we do not do the same. 675 */ 676 pc->pc_ucred->cr_ngroups = 1; 677 } else { 678 if ((error = copyin((caddr_t)uap->gidset, 679 (caddr_t)pc->pc_ucred->cr_groups, ngrp * sizeof(gid_t)))) 680 return (error); 681 pc->pc_ucred->cr_ngroups = ngrp; 682 } 683 setsugid(p); 684 return (0); 685} 686 687#ifndef _SYS_SYSPROTO_H_ 688struct setreuid_args { 689 uid_t ruid; 690 uid_t euid; 691}; 692#endif 693/* ARGSUSED */ 694int 695setreuid(p, uap) 696 register struct proc *p; 697 struct setreuid_args *uap; 698{ 699 register struct pcred *pc = p->p_cred; 700 register uid_t ruid, euid; 701 int error; 702 703 ruid = uap->ruid; 704 euid = uap->euid; 705 if (((ruid != (uid_t)-1 && ruid != pc->p_ruid && ruid != pc->p_svuid) || 706 (euid != (uid_t)-1 && euid != pc->pc_ucred->cr_uid && 707 euid != pc->p_ruid && euid != pc->p_svuid)) && 708 (error = suser_xxx(0, p, PRISON_ROOT)) != 0) 709 return (error); 710 711 if (euid != (uid_t)-1 && pc->pc_ucred->cr_uid != euid) { 712 change_euid(p, euid); 713 setsugid(p); 714 } 715 if (ruid != (uid_t)-1 && pc->p_ruid != ruid) { 716 change_ruid(p, ruid); 717 setsugid(p); 718 } 719 if ((ruid != (uid_t)-1 || pc->pc_ucred->cr_uid != pc->p_ruid) && 720 pc->p_svuid != pc->pc_ucred->cr_uid) { 721 pc->p_svuid = pc->pc_ucred->cr_uid; 722 setsugid(p); 723 } 724 return (0); 725} 726 727#ifndef _SYS_SYSPROTO_H_ 728struct setregid_args { 729 gid_t rgid; 730 gid_t egid; 731}; 732#endif 733/* ARGSUSED */ 734int 735setregid(p, uap) 736 register struct proc *p; 737 struct setregid_args *uap; 738{ 739 register struct pcred *pc = p->p_cred; 740 register gid_t rgid, egid; 741 int error; 742 743 rgid = uap->rgid; 744 egid = uap->egid; 745 if (((rgid != (gid_t)-1 && rgid != pc->p_rgid && rgid != pc->p_svgid) || 746 (egid != (gid_t)-1 && egid != pc->pc_ucred->cr_groups[0] && 747 egid != pc->p_rgid && egid != pc->p_svgid)) && 748 (error = suser_xxx(0, p, PRISON_ROOT)) != 0) 749 return (error); 750 751 if (egid != (gid_t)-1 && pc->pc_ucred->cr_groups[0] != egid) { 752 pc->pc_ucred = crcopy(pc->pc_ucred); 753 pc->pc_ucred->cr_groups[0] = egid; 754 setsugid(p); 755 } 756 if (rgid != (gid_t)-1 && pc->p_rgid != rgid) { 757 pc->p_rgid = rgid; 758 setsugid(p); 759 } 760 if ((rgid != (gid_t)-1 || pc->pc_ucred->cr_groups[0] != pc->p_rgid) && 761 pc->p_svgid != pc->pc_ucred->cr_groups[0]) { 762 pc->p_svgid = pc->pc_ucred->cr_groups[0]; 763 setsugid(p); 764 } 765 return (0); 766} 767 768/* 769 * setresuid(ruid, euid, suid) is like setreuid except control over the 770 * saved uid is explicit. 771 */ 772 773#ifndef _SYS_SYSPROTO_H_ 774struct setresuid_args { 775 uid_t ruid; 776 uid_t euid; 777 uid_t suid; 778}; 779#endif 780/* ARGSUSED */ 781int 782setresuid(p, uap) 783 register struct proc *p; 784 struct setresuid_args *uap; 785{ 786 register struct pcred *pc = p->p_cred; 787 register uid_t ruid, euid, suid; 788 int error; 789 790 ruid = uap->ruid; 791 euid = uap->euid; 792 suid = uap->suid; 793 if (((ruid != (uid_t)-1 && ruid != pc->p_ruid && ruid != pc->p_svuid && 794 ruid != pc->pc_ucred->cr_uid) || 795 (euid != (uid_t)-1 && euid != pc->p_ruid && euid != pc->p_svuid && 796 euid != pc->pc_ucred->cr_uid) || 797 (suid != (uid_t)-1 && suid != pc->p_ruid && suid != pc->p_svuid && 798 suid != pc->pc_ucred->cr_uid)) && 799 (error = suser_xxx(0, p, PRISON_ROOT)) != 0) 800 return (error); 801 if (euid != (uid_t)-1 && pc->pc_ucred->cr_uid != euid) { 802 change_euid(p, euid); 803 setsugid(p); 804 } 805 if (ruid != (uid_t)-1 && pc->p_ruid != ruid) { 806 change_ruid(p, ruid); 807 setsugid(p); 808 } 809 if (suid != (uid_t)-1 && pc->p_svuid != suid) { 810 pc->p_svuid = suid; 811 setsugid(p); 812 } 813 return (0); 814} 815 816/* 817 * setresgid(rgid, egid, sgid) is like setregid except control over the 818 * saved gid is explicit. 819 */ 820 821#ifndef _SYS_SYSPROTO_H_ 822struct setresgid_args { 823 gid_t rgid; 824 gid_t egid; 825 gid_t sgid; 826}; 827#endif 828/* ARGSUSED */ 829int 830setresgid(p, uap) 831 register struct proc *p; 832 struct setresgid_args *uap; 833{ 834 register struct pcred *pc = p->p_cred; 835 register gid_t rgid, egid, sgid; 836 int error; 837 838 rgid = uap->rgid; 839 egid = uap->egid; 840 sgid = uap->sgid; 841 if (((rgid != (gid_t)-1 && rgid != pc->p_rgid && rgid != pc->p_svgid && 842 rgid != pc->pc_ucred->cr_groups[0]) || 843 (egid != (gid_t)-1 && egid != pc->p_rgid && egid != pc->p_svgid && 844 egid != pc->pc_ucred->cr_groups[0]) || 845 (sgid != (gid_t)-1 && sgid != pc->p_rgid && sgid != pc->p_svgid && 846 sgid != pc->pc_ucred->cr_groups[0])) && 847 (error = suser_xxx(0, p, PRISON_ROOT)) != 0) 848 return (error); 849 850 if (egid != (gid_t)-1 && pc->pc_ucred->cr_groups[0] != egid) { 851 pc->pc_ucred = crcopy(pc->pc_ucred); 852 pc->pc_ucred->cr_groups[0] = egid; 853 setsugid(p); 854 } 855 if (rgid != (gid_t)-1 && pc->p_rgid != rgid) { 856 pc->p_rgid = rgid; 857 setsugid(p); 858 } 859 if (sgid != (gid_t)-1 && pc->p_svgid != sgid) { 860 pc->p_svgid = sgid; 861 setsugid(p); 862 } 863 return (0); 864} 865 866#ifndef _SYS_SYSPROTO_H_ 867struct getresuid_args { 868 uid_t *ruid; 869 uid_t *euid; 870 uid_t *suid; 871}; 872#endif 873/* ARGSUSED */ 874int 875getresuid(p, uap) 876 register struct proc *p; 877 struct getresuid_args *uap; 878{ 879 struct pcred *pc = p->p_cred; 880 int error1 = 0, error2 = 0, error3 = 0; 881 882 if (uap->ruid) 883 error1 = copyout((caddr_t)&pc->p_ruid, 884 (caddr_t)uap->ruid, sizeof(pc->p_ruid)); 885 if (uap->euid) 886 error2 = copyout((caddr_t)&pc->pc_ucred->cr_uid, 887 (caddr_t)uap->euid, sizeof(pc->pc_ucred->cr_uid)); 888 if (uap->suid) 889 error3 = copyout((caddr_t)&pc->p_svuid, 890 (caddr_t)uap->suid, sizeof(pc->p_svuid)); 891 return error1 ? error1 : (error2 ? error2 : error3); 892} 893 894#ifndef _SYS_SYSPROTO_H_ 895struct getresgid_args { 896 gid_t *rgid; 897 gid_t *egid; 898 gid_t *sgid; 899}; 900#endif 901/* ARGSUSED */ 902int 903getresgid(p, uap) 904 register struct proc *p; 905 struct getresgid_args *uap; 906{ 907 struct pcred *pc = p->p_cred; 908 int error1 = 0, error2 = 0, error3 = 0; 909 910 if (uap->rgid) 911 error1 = copyout((caddr_t)&pc->p_rgid, 912 (caddr_t)uap->rgid, sizeof(pc->p_rgid)); 913 if (uap->egid) 914 error2 = copyout((caddr_t)&pc->pc_ucred->cr_groups[0], 915 (caddr_t)uap->egid, sizeof(pc->pc_ucred->cr_groups[0])); 916 if (uap->sgid) 917 error3 = copyout((caddr_t)&pc->p_svgid, 918 (caddr_t)uap->sgid, sizeof(pc->p_svgid)); 919 return error1 ? error1 : (error2 ? error2 : error3); 920} 921 922 923#ifndef _SYS_SYSPROTO_H_ 924struct issetugid_args { 925 int dummy; 926}; 927#endif 928/* ARGSUSED */ 929int 930issetugid(p, uap) 931 register struct proc *p; 932 struct issetugid_args *uap; 933{ 934 /* 935 * Note: OpenBSD sets a P_SUGIDEXEC flag set at execve() time, 936 * we use P_SUGID because we consider changing the owners as 937 * "tainting" as well. 938 * This is significant for procs that start as root and "become" 939 * a user without an exec - programs cannot know *everything* 940 * that libc *might* have put in their data segment. 941 */ 942 p->p_retval[0] = (p->p_flag & P_SUGID) ? 1 : 0; 943 return (0); 944} 945 946int 947__setugid(p, uap) 948 struct proc *p; 949 struct __setugid_args *uap; 950{ 951 952#ifdef REGRESSION 953 switch (uap->flag) { 954 case 0: 955 p->p_flag &= ~P_SUGID; 956 return (0); 957 case 1: 958 p->p_flag |= P_SUGID; 959 return (0); 960 default: 961 return (EINVAL); 962 } 963#else /* !REGRESSION */ 964 return (ENOSYS); 965#endif /* !REGRESSION */ 966} 967 968/* 969 * Check if gid is a member of the group set. 970 */ 971int 972groupmember(gid, cred) 973 gid_t gid; 974 register struct ucred *cred; 975{ 976 register gid_t *gp; 977 gid_t *egp; 978 979 egp = &(cred->cr_groups[cred->cr_ngroups]); 980 for (gp = cred->cr_groups; gp < egp; gp++) 981 if (*gp == gid) 982 return (1); 983 return (0); 984} 985 986static int suser_permitted = 1; 987 988SYSCTL_INT(_kern, OID_AUTO, suser_permitted, CTLFLAG_RW, &suser_permitted, 0, 989 "processes with uid 0 have privilege"); 990 991/* 992 * Test whether the specified credentials imply "super-user" 993 * privilege; if so, and we have accounting info, set the flag 994 * indicating use of super-powers. 995 * Returns 0 or error. 996 */ 997int 998suser(p) 999 struct proc *p; 1000{ 1001 return suser_xxx(0, p, 0); 1002} 1003 1004int 1005suser_xxx(cred, proc, flag) 1006 struct ucred *cred; 1007 struct proc *proc; 1008 int flag; 1009{ 1010 if (!suser_permitted) 1011 return (EPERM); 1012 if (!cred && !proc) { 1013 printf("suser_xxx(): THINK!\n"); 1014 return (EPERM); 1015 } 1016 if (!cred) 1017 cred = proc->p_ucred; 1018 if (cred->cr_uid != 0) 1019 return (EPERM); 1020 if (jailed(cred) && !(flag & PRISON_ROOT)) 1021 return (EPERM); 1022 return (0); 1023} 1024 1025/* 1026 * u_cansee(u1, u2): determine if u1 "can see" the subject specified by u2 1027 * Arguments: imutable credentials u1, u2 1028 * Returns: 0 for permitted, an errno value otherwise 1029 * Locks: none 1030 * References: u1 and u2 must be valid for the lifetime of the call 1031 * u1 may equal u2, in which case only one reference is required 1032 */ 1033int 1034u_cansee(struct ucred *u1, struct ucred *u2) 1035{ 1036 int error; 1037 1038 if ((error = prison_check(u1, u2))) 1039 return (error); 1040 if (!ps_showallprocs && u1->cr_uid != u2->cr_uid) { 1041 if (suser_xxx(u1, NULL, PRISON_ROOT) != 0) 1042 return (ESRCH); 1043 } 1044 return (0); 1045} 1046 1047static int 1048p_cansee(struct proc *p1, struct proc *p2, int *privused) 1049{ 1050 1051 /* XXX: privused is going away, so don't do that here. */ 1052 if (privused != NULL) 1053 *privused = 0; 1054 /* Wrap u_cansee() for all functionality. */ 1055 return (u_cansee(p1->p_ucred, p2->p_ucred)); 1056} 1057 1058/* 1059 * Can process p1 send the signal signum to process p2? 1060 */ 1061int 1062p_cansignal(struct proc *p1, struct proc *p2, int signum) 1063{ 1064 int error; 1065 1066 if (p1 == p2) 1067 return (0); 1068 1069 /* 1070 * Jail semantics limit the scope of signalling to p2 in the same 1071 * jail as p1, if p1 is in jail. 1072 */ 1073 if ((error = prison_check(p1->p_ucred, p2->p_ucred))) 1074 return (error); 1075 1076 /* 1077 * UNIX signalling semantics require that processes in the same 1078 * session always be able to deliver SIGCONT to one another, 1079 * overriding the remaining protections. 1080 */ 1081 if (signum == SIGCONT && p1->p_session == p2->p_session) 1082 return (0); 1083 1084 /* 1085 * UNIX uid semantics depend on the status of the P_SUGID 1086 * bit on the target process. If the bit is set, then more 1087 * restricted signal sets are permitted. 1088 */ 1089 if (p2->p_flag & P_SUGID) { 1090 switch (signum) { 1091 case 0: 1092 case SIGKILL: 1093 case SIGINT: 1094 case SIGTERM: 1095 case SIGSTOP: 1096 case SIGTTIN: 1097 case SIGTTOU: 1098 case SIGTSTP: 1099 case SIGHUP: 1100 case SIGUSR1: 1101 case SIGUSR2: 1102 break; 1103 default: 1104 /* Not permitted, try privilege. */ 1105 error = suser_xxx(NULL, p1, PRISON_ROOT); 1106 if (error) 1107 return (error); 1108 } 1109 } 1110 1111 /* 1112 * Generally, the object credential's ruid or svuid must match the 1113 * subject credential's ruid or euid. 1114 */ 1115 if (p1->p_cred->p_ruid != p2->p_cred->p_ruid && 1116 p1->p_cred->p_ruid != p2->p_cred->p_svuid && 1117 p1->p_ucred->cr_uid != p2->p_cred->p_ruid && 1118 p1->p_ucred->cr_uid != p2->p_cred->p_svuid) { 1119 /* Not permitted, try privilege. */ 1120 error = suser_xxx(NULL, p1, PRISON_ROOT); 1121 if (error) 1122 return (error); 1123 } 1124 1125 return (0); 1126} 1127 1128static int 1129p_cansched(struct proc *p1, struct proc *p2, int *privused) 1130{ 1131 int error; 1132 1133 if (privused != NULL) 1134 *privused = 0; 1135 1136 if (p1 == p2) 1137 return (0); 1138 1139 if ((error = prison_check(p1->p_ucred, p2->p_ucred))) 1140 return (error); 1141 1142 if (p1->p_cred->p_ruid == p2->p_cred->p_ruid) 1143 return (0); 1144 if (p1->p_ucred->cr_uid == p2->p_cred->p_ruid) 1145 return (0); 1146#if 0 1147 /* 1148 * XXX should a process be able to affect another process 1149 * acting as the same uid (i.e., sendmail delivery, lpd, 1150 * et al?) 1151 */ 1152 if (p1->p_cred->p_ruid == p2->p_ucred->cr_uid) 1153 return (0); 1154 if (p1->p_ucred->cr_uid == p2->p_ucred->cr_uid) 1155 return (0); 1156#endif /* 0 */ 1157 1158 if (!suser_xxx(0, p1, PRISON_ROOT)) { 1159 if (privused != NULL) 1160 *privused = 1; 1161 return (0); 1162 } 1163 1164#ifdef CAPABILITIES 1165 if (!cap_check_xxx(0, p1, CAP_SYS_NICE, PRISON_ROOT)) { 1166 if (privused != NULL) 1167 *privused = 1; 1168 return (0); 1169 } 1170#endif 1171 1172 return (EPERM); 1173} 1174 1175static int 1176p_candebug(struct proc *p1, struct proc *p2, int *privused) 1177{ 1178 int error; 1179 1180 if (privused != NULL) 1181 *privused = 0; 1182 1183 if (p1 == p2) 1184 return (0); 1185 1186 if ((error = prison_check(p1->p_ucred, p2->p_ucred))) 1187 return (error); 1188 1189 /* not owned by you, has done setuid (unless you're root) */ 1190 /* add a CAP_SYS_PTRACE here? */ 1191 if (p1->p_cred->pc_ucred->cr_uid != p2->p_cred->p_ruid || 1192 p1->p_cred->p_ruid != p2->p_cred->p_ruid || 1193 p1->p_cred->p_svuid != p2->p_cred->p_ruid || 1194 p2->p_flag & P_SUGID) { 1195 if ((error = suser_xxx(0, p1, PRISON_ROOT))) 1196 return (error); 1197 if (privused != NULL) 1198 *privused = 1; 1199 } 1200 1201 /* can't trace init when securelevel > 0 */ 1202 if (securelevel > 0 && p2->p_pid == 1) 1203 return (EPERM); 1204 1205 return (0); 1206} 1207 1208int 1209p_can(struct proc *p1, struct proc *p2, int operation, 1210 int *privused) 1211{ 1212 1213 switch(operation) { 1214 case P_CAN_SEE: 1215 return (p_cansee(p1, p2, privused)); 1216 1217 case P_CAN_SCHED: 1218 return (p_cansched(p1, p2, privused)); 1219 1220 case P_CAN_DEBUG: 1221 return (p_candebug(p1, p2, privused)); 1222 1223 default: 1224 panic("p_can: invalid operation"); 1225 } 1226} 1227 1228 1229/* 1230 * Allocate a zeroed cred structure. 1231 */ 1232struct ucred * 1233crget() 1234{ 1235 register struct ucred *cr; 1236 1237 MALLOC(cr, struct ucred *, sizeof(*cr), M_CRED, M_WAITOK|M_ZERO); 1238 cr->cr_ref = 1; 1239 mtx_init(&cr->cr_mtx, "ucred", MTX_DEF); 1240 return (cr); 1241} 1242 1243/* 1244 * Claim another reference to a ucred structure 1245 */ 1246void 1247crhold(cr) 1248 struct ucred *cr; 1249{ 1250 1251 mtx_lock(&cr->cr_mtx); 1252 cr->cr_ref++; 1253 mtx_unlock(&(cr)->cr_mtx); 1254} 1255 1256 1257/* 1258 * Free a cred structure. 1259 * Throws away space when ref count gets to 0. 1260 */ 1261void 1262crfree(cr) 1263 struct ucred *cr; 1264{ 1265 1266 mtx_lock(&cr->cr_mtx); 1267 KASSERT(cr->cr_ref > 0, ("bad ucred refcount: %d", cr->cr_ref)); 1268 if (--cr->cr_ref == 0) { 1269 mtx_destroy(&cr->cr_mtx); 1270 /* 1271 * Some callers of crget(), such as nfs_statfs(), 1272 * allocate a temporary credential, but don't 1273 * allocate a uidinfo structure. 1274 */ 1275 if (cr->cr_uidinfo != NULL) 1276 uifree(cr->cr_uidinfo); 1277 /* 1278 * Free a prison, if any. 1279 */ 1280 if (jailed(cr)) 1281 prison_free(cr->cr_prison); 1282 FREE((caddr_t)cr, M_CRED); 1283 } else { 1284 mtx_unlock(&cr->cr_mtx); 1285 } 1286} 1287 1288/* 1289 * Copy cred structure to a new one and free the old one. 1290 */ 1291struct ucred * 1292crcopy(cr) 1293 struct ucred *cr; 1294{ 1295 struct ucred *newcr; 1296 1297 mtx_lock(&cr->cr_mtx); 1298 if (cr->cr_ref == 1) { 1299 mtx_unlock(&cr->cr_mtx); 1300 return (cr); 1301 } 1302 mtx_unlock(&cr->cr_mtx); 1303 newcr = crdup(cr); 1304 crfree(cr); 1305 return (newcr); 1306} 1307 1308/* 1309 * Dup cred struct to a new held one. 1310 */ 1311struct ucred * 1312crdup(cr) 1313 struct ucred *cr; 1314{ 1315 struct ucred *newcr; 1316 1317 MALLOC(newcr, struct ucred *, sizeof(*cr), M_CRED, M_WAITOK); 1318 *newcr = *cr; 1319 mtx_init(&newcr->cr_mtx, "ucred", MTX_DEF); 1320 uihold(newcr->cr_uidinfo); 1321 if (jailed(newcr)) 1322 prison_hold(newcr->cr_prison); 1323 newcr->cr_ref = 1; 1324 return (newcr); 1325} 1326 1327/* 1328 * Get login name, if available. 1329 */ 1330#ifndef _SYS_SYSPROTO_H_ 1331struct getlogin_args { 1332 char *namebuf; 1333 u_int namelen; 1334}; 1335#endif 1336/* ARGSUSED */ 1337int 1338getlogin(p, uap) 1339 struct proc *p; 1340 struct getlogin_args *uap; 1341{ 1342 1343 if (uap->namelen > MAXLOGNAME) 1344 uap->namelen = MAXLOGNAME; 1345 return (copyout((caddr_t) p->p_pgrp->pg_session->s_login, 1346 (caddr_t) uap->namebuf, uap->namelen)); 1347} 1348 1349/* 1350 * Set login name. 1351 */ 1352#ifndef _SYS_SYSPROTO_H_ 1353struct setlogin_args { 1354 char *namebuf; 1355}; 1356#endif 1357/* ARGSUSED */ 1358int 1359setlogin(p, uap) 1360 struct proc *p; 1361 struct setlogin_args *uap; 1362{ 1363 int error; 1364 char logintmp[MAXLOGNAME]; 1365 1366 if ((error = suser_xxx(0, p, PRISON_ROOT))) 1367 return (error); 1368 error = copyinstr((caddr_t) uap->namebuf, (caddr_t) logintmp, 1369 sizeof(logintmp), (size_t *)0); 1370 if (error == ENAMETOOLONG) 1371 error = EINVAL; 1372 else if (!error) 1373 (void) memcpy(p->p_pgrp->pg_session->s_login, logintmp, 1374 sizeof(logintmp)); 1375 return (error); 1376} 1377 1378void 1379setsugid(p) 1380 struct proc *p; 1381{ 1382 p->p_flag |= P_SUGID; 1383 if (!(p->p_pfsflags & PF_ISUGID)) 1384 p->p_stops = 0; 1385} 1386 1387/* 1388 * Helper function to change the effective uid of a process 1389 */ 1390void 1391change_euid(p, euid) 1392 struct proc *p; 1393 uid_t euid; 1394{ 1395 struct pcred *pc; 1396 struct uidinfo *uip; 1397 1398 pc = p->p_cred; 1399 /* 1400 * crcopy is essentially a NOP if ucred has a reference count 1401 * of 1, which is true if it has already been copied. 1402 */ 1403 pc->pc_ucred = crcopy(pc->pc_ucred); 1404 uip = pc->pc_ucred->cr_uidinfo; 1405 pc->pc_ucred->cr_uid = euid; 1406 pc->pc_ucred->cr_uidinfo = uifind(euid); 1407 uifree(uip); 1408} 1409 1410/* 1411 * Helper function to change the real uid of a process 1412 * 1413 * The per-uid process count for this process is transfered from 1414 * the old uid to the new uid. 1415 */ 1416void 1417change_ruid(p, ruid) 1418 struct proc *p; 1419 uid_t ruid; 1420{ 1421 struct pcred *pc; 1422 struct uidinfo *uip; 1423 1424 pc = p->p_cred; 1425 (void)chgproccnt(pc->p_uidinfo, -1, 0); 1426 uip = pc->p_uidinfo; 1427 /* It is assumed that pcred is not shared between processes */ 1428 pc->p_ruid = ruid; 1429 pc->p_uidinfo = uifind(ruid); 1430 (void)chgproccnt(pc->p_uidinfo, 1, 0); 1431 uifree(uip); 1432} 1433