Deleted Added
sdiff udiff text old ( 90756 ) new ( 91140 )
full compact
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 ---