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 $
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/mutex.h>
55#include <sys/proc.h>
56#include <sys/sx.h>
57#include <sys/sysproto.h>
58#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;
140
141 mtx_lock(&Giant);
142 td->td_retval[0] = p->p_pgrp->pg_id;
143 mtx_unlock(&Giant);
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;
167 if (uap->pid == 0)
168 td->td_retval[0] = p->p_pgrp->pg_id;
169 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;
200
201 mtx_lock(&Giant);
202 error = 0;
203 if (uap->pid == 0)
204 td->td_retval[0] = p->p_session->s_sid;
205 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 }
213 mtx_unlock(&Giant);
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{
368 int error;
369 struct proc *p = td->td_proc;
370
371 mtx_lock(&Giant);
372 if (p->p_pgid == p->p_pid || pgfind(p->p_pid))
373 error = EPERM;
374 else {
375 (void)enterpgrp(p, p->p_pid, 1);
376 td->td_retval[0] = p->p_pid;
377 error = 0;
378 }
379 mtx_unlock(&Giant);
380 return (error);
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;
415
416 if (uap->pgid < 0)
417 return (EINVAL);
418 mtx_lock(&Giant);
419 sx_slock(&proctree_lock);
420 if (uap->pid != 0 && uap->pid != curp->p_pid) {
421 if ((targp = pfind(uap->pid)) == NULL || !inferior(targp)) {
422 if (targp)
423 PROC_UNLOCK(targp);
424 error = ESRCH;
425 goto done2;
426 }
427 if ((error = p_cansee(curproc, targp))) {
428 PROC_UNLOCK(targp);
429 goto done2;
430 }
431 if (targp->p_pgrp == NULL ||
432 targp->p_session != curp->p_session) {
433 PROC_UNLOCK(targp);
434 error = EPERM;
435 goto done2;
436 }
437 if (targp->p_flag & P_EXEC) {
438 PROC_UNLOCK(targp);
439 error = EACCES;
440 goto done2;
441 }
442 } else {
443 targp = curp;
444 PROC_LOCK(curp); /* XXX: not needed */
445 }
446 if (SESS_LEADER(targp)) {
447 PROC_UNLOCK(targp);
448 error = EPERM;
449 goto done2;
450 }
451 if (uap->pgid == 0)
452 uap->pgid = targp->p_pid;
453 else if (uap->pgid != targp->p_pid) {
454 if ((pgrp = pgfind(uap->pgid)) == 0 ||
455 pgrp->pg_session != curp->p_session) {
456 PROC_UNLOCK(targp);
457 error = EPERM;
458 goto done2;
459 }
460 }
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);
466 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 */
1137 td->td_retval[0] = (p->p_flag & P_SUGID) ? 1 : 0;
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:
1156 td->td_proc->p_flag &= ~P_SUGID;
1157 break;
1158 case 1:
1159 td->td_proc->p_flag |= P_SUGID;
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;
1728 struct proc *p = td->td_proc;
1729
1730 mtx_lock(&Giant);
1731 if (uap->namelen > MAXLOGNAME)
1732 uap->namelen = MAXLOGNAME;
1733 error = copyout((caddr_t) p->p_pgrp->pg_session->s_login,
1734 (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;
1767 else if (!error)
1768 (void)memcpy(p->p_pgrp->pg_session->s_login, logintmp,
1769 sizeof(logintmp));
1770done2:
1771 mtx_unlock(&Giant);
1772 return (error);
1773}
1774
1775void
1776setsugid(p)
1777 struct proc *p;
--- 103 unchanged lines hidden ---
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 $
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/mutex.h>
55#include <sys/proc.h>
56#include <sys/sx.h>
57#include <sys/sysproto.h>
58#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;
140
141 mtx_lock(&Giant);
142 td->td_retval[0] = p->p_pgrp->pg_id;
143 mtx_unlock(&Giant);
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;
167 if (uap->pid == 0)
168 td->td_retval[0] = p->p_pgrp->pg_id;
169 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;
200
201 mtx_lock(&Giant);
202 error = 0;
203 if (uap->pid == 0)
204 td->td_retval[0] = p->p_session->s_sid;
205 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 }
213 mtx_unlock(&Giant);
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{
368 int error;
369 struct proc *p = td->td_proc;
370
371 mtx_lock(&Giant);
372 if (p->p_pgid == p->p_pid || pgfind(p->p_pid))
373 error = EPERM;
374 else {
375 (void)enterpgrp(p, p->p_pid, 1);
376 td->td_retval[0] = p->p_pid;
377 error = 0;
378 }
379 mtx_unlock(&Giant);
380 return (error);
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;
415
416 if (uap->pgid < 0)
417 return (EINVAL);
418 mtx_lock(&Giant);
419 sx_slock(&proctree_lock);
420 if (uap->pid != 0 && uap->pid != curp->p_pid) {
421 if ((targp = pfind(uap->pid)) == NULL || !inferior(targp)) {
422 if (targp)
423 PROC_UNLOCK(targp);
424 error = ESRCH;
425 goto done2;
426 }
427 if ((error = p_cansee(curproc, targp))) {
428 PROC_UNLOCK(targp);
429 goto done2;
430 }
431 if (targp->p_pgrp == NULL ||
432 targp->p_session != curp->p_session) {
433 PROC_UNLOCK(targp);
434 error = EPERM;
435 goto done2;
436 }
437 if (targp->p_flag & P_EXEC) {
438 PROC_UNLOCK(targp);
439 error = EACCES;
440 goto done2;
441 }
442 } else {
443 targp = curp;
444 PROC_LOCK(curp); /* XXX: not needed */
445 }
446 if (SESS_LEADER(targp)) {
447 PROC_UNLOCK(targp);
448 error = EPERM;
449 goto done2;
450 }
451 if (uap->pgid == 0)
452 uap->pgid = targp->p_pid;
453 else if (uap->pgid != targp->p_pid) {
454 if ((pgrp = pgfind(uap->pgid)) == 0 ||
455 pgrp->pg_session != curp->p_session) {
456 PROC_UNLOCK(targp);
457 error = EPERM;
458 goto done2;
459 }
460 }
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);
466 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 */
1137 td->td_retval[0] = (p->p_flag & P_SUGID) ? 1 : 0;
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:
1156 td->td_proc->p_flag &= ~P_SUGID;
1157 break;
1158 case 1:
1159 td->td_proc->p_flag |= P_SUGID;
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;
1728 struct proc *p = td->td_proc;
1729
1730 mtx_lock(&Giant);
1731 if (uap->namelen > MAXLOGNAME)
1732 uap->namelen = MAXLOGNAME;
1733 error = copyout((caddr_t) p->p_pgrp->pg_session->s_login,
1734 (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;
1767 else if (!error)
1768 (void)memcpy(p->p_pgrp->pg_session->s_login, logintmp,
1769 sizeof(logintmp));
1770done2:
1771 mtx_unlock(&Giant);
1772 return (error);
1773}
1774
1775void
1776setsugid(p)
1777 struct proc *p;
--- 103 unchanged lines hidden ---