kern_prot.c (90756) | kern_prot.c (91140) |
---|---|
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 | 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 90756 2002-02-17 07:30:34Z dillon $ | 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> | 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> |
|
54#include <sys/mutex.h> | 55#include <sys/mutex.h> |
55#include <sys/proc.h> | |
56#include <sys/sx.h> | 56#include <sys/sx.h> |
57#include <sys/proc.h> |
|
57#include <sys/sysproto.h> 58#include <sys/jail.h> | 58#include <sys/sysproto.h> 59#include <sys/jail.h> |
59#include <sys/malloc.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; | 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; |
|
140 | 141 |
141 mtx_lock(&Giant); | 142 s = mtx_lock_giant(kern_giant_proc); 143 PROC_LOCK(p); |
142 td->td_retval[0] = p->p_pgrp->pg_id; | 144 td->td_retval[0] = p->p_pgrp->pg_id; |
143 mtx_unlock(&Giant); | 145 PROC_UNLOCK(p); 146 mtx_unlock_giant(s); |
144 return (0); 145} 146 147/* Get an arbitary pid's process group id */ 148#ifndef _SYS_SYSPROTO_H_ 149struct getpgid_args { 150 pid_t pid; 151}; --- 7 unchanged lines hidden (view full) --- 159 struct getpgid_args *uap; 160{ 161 struct proc *p = td->td_proc; 162 struct proc *pt; 163 int error, s; 164 165 s = mtx_lock_giant(kern_giant_proc); 166 error = 0; | 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; |
167 if (uap->pid == 0) | 170 if (uap->pid == 0) { 171 PROC_LOCK(p); |
168 td->td_retval[0] = p->p_pgrp->pg_id; | 172 td->td_retval[0] = p->p_pgrp->pg_id; |
169 else if ((pt = pfind(uap->pid)) == NULL) | 173 PROC_UNLOCK(p); 174 } else if ((pt = pfind(uap->pid)) == NULL) |
170 error = ESRCH; 171 else { 172 error = p_cansee(p, pt); 173 if (error == 0) 174 td->td_retval[0] = pt->p_pgrp->pg_id; 175 PROC_UNLOCK(pt); 176 } 177 mtx_unlock_giant(s); --- 14 unchanged lines hidden (view full) --- 192int 193getsid(td, uap) 194 struct thread *td; 195 struct getsid_args *uap; 196{ 197 struct proc *p = td->td_proc; 198 struct proc *pt; 199 int error; | 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; |
|
200 | 206 |
201 mtx_lock(&Giant); | 207 s = mtx_lock_giant(kern_giant_proc); |
202 error = 0; | 208 error = 0; |
203 if (uap->pid == 0) | 209 if (uap->pid == 0) { 210 PROC_LOCK(p); |
204 td->td_retval[0] = p->p_session->s_sid; | 211 td->td_retval[0] = p->p_session->s_sid; |
205 else if ((pt = pfind(uap->pid)) == NULL) | 212 PROC_UNLOCK(p); 213 } else if ((pt = pfind(uap->pid)) == NULL) |
206 error = ESRCH; 207 else { 208 error = p_cansee(p, pt); 209 if (error == 0) 210 td->td_retval[0] = pt->p_session->s_sid; 211 PROC_UNLOCK(pt); 212 } | 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 } |
213 mtx_unlock(&Giant); | 221 mtx_unlock_giant(s); |
214 return (error); 215} 216 217#ifndef _SYS_SYSPROTO_H_ 218struct getuid_args { 219 int dummy; 220}; 221#endif --- 138 unchanged lines hidden (view full) --- 360 * MPSAFE 361 */ 362/* ARGSUSED */ 363int 364setsid(td, uap) 365 register struct thread *td; 366 struct setsid_args *uap; 367{ | 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; |
|
368 int error; 369 struct proc *p = td->td_proc; | 377 int error; 378 struct proc *p = td->td_proc; |
379 struct pgrp *newpgrp; 380 struct session *newsess; |
|
370 | 381 |
382 error = 0; 383 pgrp = NULL; 384 |
|
371 mtx_lock(&Giant); | 385 mtx_lock(&Giant); |
372 if (p->p_pgid == p->p_pid || pgfind(p->p_pid)) | 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); |
373 error = EPERM; | 395 error = EPERM; |
374 else { 375 (void)enterpgrp(p, p->p_pid, 1); | 396 goto fail; 397 } else { 398 (void)enterpgrp(p, p->p_pid, newpgrp, newsess); |
376 td->td_retval[0] = p->p_pid; 377 error = 0; 378 } | 399 td->td_retval[0] = p->p_pid; 400 error = 0; 401 } |
402 PGRPSESS_XUNLOCK(); |
|
379 mtx_unlock(&Giant); | 403 mtx_unlock(&Giant); |
380 return (error); | 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); |
381} 382 383/* 384 * set process group (setpgid/old setpgrp) 385 * 386 * caller does setpgid(targpid, targpgid) 387 * 388 * pid must be caller or child of caller (ESRCH) --- 18 unchanged lines hidden (view full) --- 407setpgid(td, uap) 408 struct thread *td; 409 register struct setpgid_args *uap; 410{ 411 struct proc *curp = td->td_proc; 412 register struct proc *targp; /* target process */ 413 register struct pgrp *pgrp; /* target pgrp */ 414 int error; | 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; |
|
415 416 if (uap->pgid < 0) 417 return (EINVAL); | 449 450 if (uap->pgid < 0) 451 return (EINVAL); |
452 453 error = 0; 454 |
|
418 mtx_lock(&Giant); | 455 mtx_lock(&Giant); |
419 sx_slock(&proctree_lock); | 456 457 MALLOC(newpgrp, struct pgrp *, sizeof(struct pgrp), M_PGRP, M_WAITOK | M_ZERO); 458 459 PGRPSESS_XLOCK(); 460 |
420 if (uap->pid != 0 && uap->pid != curp->p_pid) { | 461 if (uap->pid != 0 && uap->pid != curp->p_pid) { |
421 if ((targp = pfind(uap->pid)) == NULL || !inferior(targp)) { | 462 sx_slock(&proctree_lock); 463 if ((targp = pfind(uap->pid)) == NULL) { |
422 if (targp) 423 PROC_UNLOCK(targp); | 464 if (targp) 465 PROC_UNLOCK(targp); |
466 sx_sunlock(&proctree_lock); |
|
424 error = ESRCH; | 467 error = ESRCH; |
425 goto done2; | 468 goto fail; |
426 } | 469 } |
470 if (!inferior(targp)) { 471 PROC_UNLOCK(targp); 472 sx_sunlock(&proctree_lock); 473 goto fail; 474 } 475 sx_sunlock(&proctree_lock); |
|
427 if ((error = p_cansee(curproc, targp))) { 428 PROC_UNLOCK(targp); | 476 if ((error = p_cansee(curproc, targp))) { 477 PROC_UNLOCK(targp); |
429 goto done2; | 478 goto fail; |
430 } 431 if (targp->p_pgrp == NULL || 432 targp->p_session != curp->p_session) { 433 PROC_UNLOCK(targp); 434 error = EPERM; | 479 } 480 if (targp->p_pgrp == NULL || 481 targp->p_session != curp->p_session) { 482 PROC_UNLOCK(targp); 483 error = EPERM; |
435 goto done2; | 484 goto fail; |
436 } 437 if (targp->p_flag & P_EXEC) { 438 PROC_UNLOCK(targp); 439 error = EACCES; | 485 } 486 if (targp->p_flag & P_EXEC) { 487 PROC_UNLOCK(targp); 488 error = EACCES; |
440 goto done2; | 489 goto fail; |
441 } | 490 } |
442 } else { | 491 PROC_UNLOCK(targp); 492 } else |
443 targp = curp; | 493 targp = curp; |
444 PROC_LOCK(curp); /* XXX: not needed */ 445 } | |
446 if (SESS_LEADER(targp)) { | 494 if (SESS_LEADER(targp)) { |
447 PROC_UNLOCK(targp); | |
448 error = EPERM; | 495 error = EPERM; |
449 goto done2; | 496 goto fail; |
450 } 451 if (uap->pgid == 0) 452 uap->pgid = targp->p_pid; | 497 } 498 if (uap->pgid == 0) 499 uap->pgid = targp->p_pid; |
453 else if (uap->pgid != targp->p_pid) { 454 if ((pgrp = pgfind(uap->pgid)) == 0 || | 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 || |
455 pgrp->pg_session != curp->p_session) { | 508 pgrp->pg_session != curp->p_session) { |
456 PROC_UNLOCK(targp); | 509 if (pgrp != NULL) 510 PGRP_UNLOCK(pgrp); |
457 error = EPERM; | 511 error = EPERM; |
458 goto done2; | 512 goto fail; |
459 } | 513 } |
514 if (pgrp == targp->p_pgrp) { 515 PGRP_UNLOCK(pgrp); 516 goto done; 517 } 518 PGRP_UNLOCK(pgrp); 519 error = enterthispgrp(targp, pgrp); |
|
460 } | 520 } |
461 /* XXX: We should probably hold the lock across enterpgrp. */ 462 PROC_UNLOCK(targp); 463 error = enterpgrp(targp, uap->pgid, 0); 464done2: 465 sx_sunlock(&proctree_lock); | 521done: 522 PGRPSESS_XUNLOCK(); 523 if (newpgrp != NULL) 524 FREE(newpgrp, M_PGRP); |
466 mtx_unlock(&Giant); | 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); |
|
467 return (error); 468} 469 470/* 471 * Use the clause in B.4.2.2 that allows setuid/setgid to be 4.2/4.3BSD 472 * compatible. It says that setting the uid/gid to euid/egid is a special 473 * case of "appropriate privilege". Once the rules are expanded out, this 474 * basically means that setuid(nnn) sets all three id's, in all permitted --- 654 unchanged lines hidden (view full) --- 1129 /* 1130 * Note: OpenBSD sets a P_SUGIDEXEC flag set at execve() time, 1131 * we use P_SUGID because we consider changing the owners as 1132 * "tainting" as well. 1133 * This is significant for procs that start as root and "become" 1134 * a user without an exec - programs cannot know *everything* 1135 * that libc *might* have put in their data segment. 1136 */ | 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); |
|
1137 td->td_retval[0] = (p->p_flag & P_SUGID) ? 1 : 0; | 1206 td->td_retval[0] = (p->p_flag & P_SUGID) ? 1 : 0; |
1207 PROC_UNLOCK(p); |
|
1138 return (0); 1139} 1140 1141/* 1142 * MPSAFE 1143 */ 1144int 1145__setugid(td, uap) 1146 struct thread *td; 1147 struct __setugid_args *uap; 1148{ 1149#ifdef REGRESSION 1150 int error; 1151 1152 mtx_lock(&Giant); 1153 error = 0; 1154 switch (uap->flag) { 1155 case 0: | 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); |
|
1156 td->td_proc->p_flag &= ~P_SUGID; | 1227 td->td_proc->p_flag &= ~P_SUGID; |
1228 PROC_UNLOCK(td->td_proc); |
|
1157 break; 1158 case 1: | 1229 break; 1230 case 1: |
1231 PROC_LOCK(td->td_proc); |
|
1159 td->td_proc->p_flag |= P_SUGID; | 1232 td->td_proc->p_flag |= P_SUGID; |
1233 PROC_UNLOCK(td->td_proc); |
|
1160 break; 1161 default: 1162 error = EINVAL; 1163 break; 1164 } 1165 mtx_unlock(&Giant); 1166 return (error); 1167#else /* !REGRESSION */ --- 552 unchanged lines hidden (view full) --- 1720 */ 1721/* ARGSUSED */ 1722int 1723getlogin(td, uap) 1724 struct thread *td; 1725 struct getlogin_args *uap; 1726{ 1727 int error; | 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]; |
|
1728 struct proc *p = td->td_proc; 1729 1730 mtx_lock(&Giant); 1731 if (uap->namelen > MAXLOGNAME) 1732 uap->namelen = MAXLOGNAME; | 1803 struct proc *p = td->td_proc; 1804 1805 mtx_lock(&Giant); 1806 if (uap->namelen > MAXLOGNAME) 1807 uap->namelen = MAXLOGNAME; |
1733 error = copyout((caddr_t) p->p_pgrp->pg_session->s_login, 1734 (caddr_t) uap->namebuf, uap->namelen); | 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); |
1735 mtx_unlock(&Giant); 1736 return(error); 1737} 1738 1739/* 1740 * Set login name. 1741 */ 1742#ifndef _SYS_SYSPROTO_H_ --- 16 unchanged lines hidden (view full) --- 1759 1760 mtx_lock(&Giant); 1761 if ((error = suser_xxx(0, p, PRISON_ROOT)) != 0) 1762 goto done2; 1763 error = copyinstr((caddr_t) uap->namebuf, (caddr_t) logintmp, 1764 sizeof(logintmp), (size_t *)0); 1765 if (error == ENAMETOOLONG) 1766 error = EINVAL; | 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; |
1767 else if (!error) 1768 (void)memcpy(p->p_pgrp->pg_session->s_login, logintmp, | 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, |
1769 sizeof(logintmp)); | 1851 sizeof(logintmp)); |
1852 SESS_UNLOCK(p->p_session); 1853 PROC_UNLOCK(p); 1854 PGRPSESS_XUNLOCK(); 1855 } |
|
1770done2: 1771 mtx_unlock(&Giant); 1772 return (error); 1773} 1774 1775void 1776setsugid(p) 1777 struct proc *p; --- 103 unchanged lines hidden --- | 1856done2: 1857 mtx_unlock(&Giant); 1858 return (error); 1859} 1860 1861void 1862setsugid(p) 1863 struct proc *p; --- 103 unchanged lines hidden --- |