Deleted Added
full compact
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 ---