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. --- 23 unchanged lines hidden (view full) --- 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 * SUCH DAMAGE. 38 * 39 * @(#)kern_prot.c 8.6 (Berkeley) 1/21/94 |
40 * $FreeBSD: head/sys/kern/kern_prot.c 91140 2002-02-23 11:12:57Z tanimura $ |
41 */ 42 43/* 44 * System calls related to processes and protection 45 */ 46 47#include "opt_compat.h" 48 49#include <sys/param.h> 50#include <sys/systm.h> 51#include <sys/acct.h> 52#include <sys/kernel.h> 53#include <sys/lock.h> |
54#include <sys/malloc.h> |
55#include <sys/mutex.h> |
56#include <sys/sx.h> |
57#include <sys/proc.h> |
58#include <sys/sysproto.h> 59#include <sys/jail.h> |
60#include <sys/pioctl.h> 61#include <sys/resourcevar.h> 62#include <sys/sysctl.h> 63 64static MALLOC_DEFINE(M_CRED, "cred", "credentials"); 65 66SYSCTL_DECL(_security); 67SYSCTL_NODE(_security, OID_AUTO, bsd, CTLFLAG_RW, 0, --- 64 unchanged lines hidden (view full) --- 132 * MPSAFE 133 */ 134int 135getpgrp(td, uap) 136 struct thread *td; 137 struct getpgrp_args *uap; 138{ 139 struct proc *p = td->td_proc; |
140 int s; |
141 |
142 s = mtx_lock_giant(kern_giant_proc); 143 PROC_LOCK(p); |
144 td->td_retval[0] = p->p_pgrp->pg_id; |
145 PROC_UNLOCK(p); 146 mtx_unlock_giant(s); |
147 return (0); 148} 149 150/* Get an arbitary pid's process group id */ 151#ifndef _SYS_SYSPROTO_H_ 152struct getpgid_args { 153 pid_t pid; 154}; --- 7 unchanged lines hidden (view full) --- 162 struct getpgid_args *uap; 163{ 164 struct proc *p = td->td_proc; 165 struct proc *pt; 166 int error, s; 167 168 s = mtx_lock_giant(kern_giant_proc); 169 error = 0; |
170 if (uap->pid == 0) { 171 PROC_LOCK(p); |
172 td->td_retval[0] = p->p_pgrp->pg_id; |
173 PROC_UNLOCK(p); 174 } else if ((pt = pfind(uap->pid)) == NULL) |
175 error = ESRCH; 176 else { 177 error = p_cansee(p, pt); 178 if (error == 0) 179 td->td_retval[0] = pt->p_pgrp->pg_id; 180 PROC_UNLOCK(pt); 181 } 182 mtx_unlock_giant(s); --- 14 unchanged lines hidden (view full) --- 197int 198getsid(td, uap) 199 struct thread *td; 200 struct getsid_args *uap; 201{ 202 struct proc *p = td->td_proc; 203 struct proc *pt; 204 int error; |
205 int s; |
206 |
207 s = mtx_lock_giant(kern_giant_proc); |
208 error = 0; |
209 if (uap->pid == 0) { 210 PROC_LOCK(p); |
211 td->td_retval[0] = p->p_session->s_sid; |
212 PROC_UNLOCK(p); 213 } else if ((pt = pfind(uap->pid)) == NULL) |
214 error = ESRCH; 215 else { 216 error = p_cansee(p, pt); 217 if (error == 0) 218 td->td_retval[0] = pt->p_session->s_sid; 219 PROC_UNLOCK(pt); 220 } |
221 mtx_unlock_giant(s); |
222 return (error); 223} 224 225#ifndef _SYS_SYSPROTO_H_ 226struct getuid_args { 227 int dummy; 228}; 229#endif --- 138 unchanged lines hidden (view full) --- 368 * MPSAFE 369 */ 370/* ARGSUSED */ 371int 372setsid(td, uap) 373 register struct thread *td; 374 struct setsid_args *uap; 375{ |
376 struct pgrp *pgrp; |
377 int error; 378 struct proc *p = td->td_proc; |
379 struct pgrp *newpgrp; 380 struct session *newsess; |
381 |
382 error = 0; 383 pgrp = NULL; 384 |
385 mtx_lock(&Giant); |
386 387 MALLOC(newpgrp, struct pgrp *, sizeof(struct pgrp), M_PGRP, M_WAITOK | M_ZERO); 388 MALLOC(newsess, struct session *, sizeof(struct session), M_SESSION, M_WAITOK | M_ZERO); 389 390 PGRPSESS_XLOCK(); 391 392 if (p->p_pgid == p->p_pid || (pgrp = pgfind(p->p_pid)) != NULL) { 393 if (pgrp != NULL) 394 PGRP_UNLOCK(pgrp); |
395 error = EPERM; |
396 goto fail; 397 } else { 398 (void)enterpgrp(p, p->p_pid, newpgrp, newsess); |
399 td->td_retval[0] = p->p_pid; 400 error = 0; 401 } |
402 PGRPSESS_XUNLOCK(); |
403 mtx_unlock(&Giant); |
404 return (0); 405 406fail: 407 PGRPSESS_XUNLOCK(); 408 409 FREE(newpgrp, M_PGRP); 410 FREE(newsess, M_SESSION); 411 412 mtx_unlock(&Giant); 413 return (0); |
414} 415 416/* 417 * set process group (setpgid/old setpgrp) 418 * 419 * caller does setpgid(targpid, targpgid) 420 * 421 * pid must be caller or child of caller (ESRCH) --- 18 unchanged lines hidden (view full) --- 440setpgid(td, uap) 441 struct thread *td; 442 register struct setpgid_args *uap; 443{ 444 struct proc *curp = td->td_proc; 445 register struct proc *targp; /* target process */ 446 register struct pgrp *pgrp; /* target pgrp */ 447 int error; |
448 struct pgrp *newpgrp; |
449 450 if (uap->pgid < 0) 451 return (EINVAL); |
452 453 error = 0; 454 |
455 mtx_lock(&Giant); |
456 457 MALLOC(newpgrp, struct pgrp *, sizeof(struct pgrp), M_PGRP, M_WAITOK | M_ZERO); 458 459 PGRPSESS_XLOCK(); 460 |
461 if (uap->pid != 0 && uap->pid != curp->p_pid) { |
462 sx_slock(&proctree_lock); 463 if ((targp = pfind(uap->pid)) == NULL) { |
464 if (targp) 465 PROC_UNLOCK(targp); |
466 sx_sunlock(&proctree_lock); |
467 error = ESRCH; |
468 goto fail; |
469 } |
470 if (!inferior(targp)) { 471 PROC_UNLOCK(targp); 472 sx_sunlock(&proctree_lock); 473 goto fail; 474 } 475 sx_sunlock(&proctree_lock); |
476 if ((error = p_cansee(curproc, targp))) { 477 PROC_UNLOCK(targp); |
478 goto fail; |
479 } 480 if (targp->p_pgrp == NULL || 481 targp->p_session != curp->p_session) { 482 PROC_UNLOCK(targp); 483 error = EPERM; |
484 goto fail; |
485 } 486 if (targp->p_flag & P_EXEC) { 487 PROC_UNLOCK(targp); 488 error = EACCES; |
489 goto fail; |
490 } |
491 PROC_UNLOCK(targp); 492 } else |
493 targp = curp; |
494 if (SESS_LEADER(targp)) { |
495 error = EPERM; |
496 goto fail; |
497 } 498 if (uap->pgid == 0) 499 uap->pgid = targp->p_pid; |
500 if (uap->pgid == targp->p_pid) { 501 if (targp->p_pgid == uap->pgid) 502 goto done; 503 error = enterpgrp(targp, uap->pgid, newpgrp, NULL); 504 if (error == 0) 505 newpgrp = NULL; 506 } else { 507 if ((pgrp = pgfind(uap->pgid)) == NULL || |
508 pgrp->pg_session != curp->p_session) { |
509 if (pgrp != NULL) 510 PGRP_UNLOCK(pgrp); |
511 error = EPERM; |
512 goto fail; |
513 } |
514 if (pgrp == targp->p_pgrp) { 515 PGRP_UNLOCK(pgrp); 516 goto done; 517 } 518 PGRP_UNLOCK(pgrp); 519 error = enterthispgrp(targp, pgrp); |
520 } |
521done: 522 PGRPSESS_XUNLOCK(); 523 if (newpgrp != NULL) 524 FREE(newpgrp, M_PGRP); |
525 mtx_unlock(&Giant); |
526 return (0); 527 528fail: 529 PGRPSESS_XUNLOCK(); 530 531 KASSERT(newpgrp != NULL, ("setpgid failed and newpgrp is null.")); 532 FREE(newpgrp, M_PGRP); 533 534 mtx_unlock(&Giant); |
535 return (error); 536} 537 538/* 539 * Use the clause in B.4.2.2 that allows setuid/setgid to be 4.2/4.3BSD 540 * compatible. It says that setting the uid/gid to euid/egid is a special 541 * case of "appropriate privilege". Once the rules are expanded out, this 542 * basically means that setuid(nnn) sets all three id's, in all permitted --- 654 unchanged lines hidden (view full) --- 1197 /* 1198 * Note: OpenBSD sets a P_SUGIDEXEC flag set at execve() time, 1199 * we use P_SUGID because we consider changing the owners as 1200 * "tainting" as well. 1201 * This is significant for procs that start as root and "become" 1202 * a user without an exec - programs cannot know *everything* 1203 * that libc *might* have put in their data segment. 1204 */ |
1205 PROC_LOCK(p); |
1206 td->td_retval[0] = (p->p_flag & P_SUGID) ? 1 : 0; |
1207 PROC_UNLOCK(p); |
1208 return (0); 1209} 1210 1211/* 1212 * MPSAFE 1213 */ 1214int 1215__setugid(td, uap) 1216 struct thread *td; 1217 struct __setugid_args *uap; 1218{ 1219#ifdef REGRESSION 1220 int error; 1221 1222 mtx_lock(&Giant); 1223 error = 0; 1224 switch (uap->flag) { 1225 case 0: |
1226 PROC_LOCK(td->td_proc); |
1227 td->td_proc->p_flag &= ~P_SUGID; |
1228 PROC_UNLOCK(td->td_proc); |
1229 break; 1230 case 1: |
1231 PROC_LOCK(td->td_proc); |
1232 td->td_proc->p_flag |= P_SUGID; |
1233 PROC_UNLOCK(td->td_proc); |
1234 break; 1235 default: 1236 error = EINVAL; 1237 break; 1238 } 1239 mtx_unlock(&Giant); 1240 return (error); 1241#else /* !REGRESSION */ --- 552 unchanged lines hidden (view full) --- 1794 */ 1795/* ARGSUSED */ 1796int 1797getlogin(td, uap) 1798 struct thread *td; 1799 struct getlogin_args *uap; 1800{ 1801 int error; |
1802 char login[MAXLOGNAME]; |
1803 struct proc *p = td->td_proc; 1804 1805 mtx_lock(&Giant); 1806 if (uap->namelen > MAXLOGNAME) 1807 uap->namelen = MAXLOGNAME; |
1808 PROC_LOCK(p); 1809 SESS_LOCK(p->p_session); 1810 bcopy(p->p_session->s_login, login, uap->namelen); 1811 SESS_UNLOCK(p->p_session); 1812 PROC_UNLOCK(p); 1813 error = copyout((caddr_t) login, (caddr_t) uap->namebuf, uap->namelen); |
1814 mtx_unlock(&Giant); 1815 return(error); 1816} 1817 1818/* 1819 * Set login name. 1820 */ 1821#ifndef _SYS_SYSPROTO_H_ --- 16 unchanged lines hidden (view full) --- 1838 1839 mtx_lock(&Giant); 1840 if ((error = suser_xxx(0, p, PRISON_ROOT)) != 0) 1841 goto done2; 1842 error = copyinstr((caddr_t) uap->namebuf, (caddr_t) logintmp, 1843 sizeof(logintmp), (size_t *)0); 1844 if (error == ENAMETOOLONG) 1845 error = EINVAL; |
1846 else if (!error) { 1847 PGRPSESS_XLOCK(); 1848 PROC_LOCK(p); 1849 SESS_LOCK(p->p_session); 1850 (void) memcpy(p->p_session->s_login, logintmp, |
1851 sizeof(logintmp)); |
1852 SESS_UNLOCK(p->p_session); 1853 PROC_UNLOCK(p); 1854 PGRPSESS_XUNLOCK(); 1855 } |
1856done2: 1857 mtx_unlock(&Giant); 1858 return (error); 1859} 1860 1861void 1862setsugid(p) 1863 struct proc *p; --- 103 unchanged lines hidden --- |