diff options
author | John Baldwin <jhb@FreeBSD.org> | 2002-05-19 00:14:50 +0000 |
---|---|---|
committer | John Baldwin <jhb@FreeBSD.org> | 2002-05-19 00:14:50 +0000 |
commit | f44d9e24fbb396076ebabf326c6f80e166d3d4a5 (patch) | |
tree | 0642e3c6447c397fe8442630e46788930550bb42 /sys/kern | |
parent | 2bab796d96af8c985c3258e20e5459a7a64d9c6d (diff) | |
download | src-f44d9e24fbb396076ebabf326c6f80e166d3d4a5.tar.gz src-f44d9e24fbb396076ebabf326c6f80e166d3d4a5.zip |
Change p_can{debug,see,sched,signal}()'s first argument to be a thread
pointer instead of a proc pointer and require the process pointed to
by the second argument to be locked. We now use the thread ucred reference
for the credential checks in p_can*() as a result. p_canfoo() should now
no longer need Giant.
Notes
Notes:
svn path=/head/; revision=96886
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_event.c | 2 | ||||
-rw-r--r-- | sys/kern/kern_ktrace.c | 2 | ||||
-rw-r--r-- | sys/kern/kern_proc.c | 6 | ||||
-rw-r--r-- | sys/kern/kern_prot.c | 129 | ||||
-rw-r--r-- | sys/kern/kern_resource.c | 18 | ||||
-rw-r--r-- | sys/kern/kern_sig.c | 7 | ||||
-rw-r--r-- | sys/kern/p1003_1b.c | 10 | ||||
-rw-r--r-- | sys/kern/sys_process.c | 4 |
8 files changed, 93 insertions, 85 deletions
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c index d9e6c8fce6fc..3e2cbf745381 100644 --- a/sys/kern/kern_event.c +++ b/sys/kern/kern_event.c @@ -196,7 +196,7 @@ filt_procattach(struct knote *kn) p = pfind(kn->kn_id); if (p == NULL) return (ESRCH); - if ((error = p_cansee(curproc, p))) { + if ((error = p_cansee(curthread, p))) { PROC_UNLOCK(p); return (error); } diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c index 5f7701110dd3..92560fca2a68 100644 --- a/sys/kern/kern_ktrace.c +++ b/sys/kern/kern_ktrace.c @@ -622,7 +622,7 @@ ktrcanset(td, targetp) suser_cred(td->td_ucred, PRISON_ROOT)) return (0); - if (p_candebug(td->td_proc, targetp) != 0) + if (p_candebug(td, targetp) != 0) return (0); return (1); diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index 8f923319fa03..ebef4a65b094 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -830,7 +830,7 @@ sysctl_kern_proc(SYSCTL_HANDLER_ARGS) p = pfind((pid_t)name[0]); if (!p) return (0); - if (p_cansee(curproc, p)) { + if (p_cansee(curthread, p)) { PROC_UNLOCK(p); return (0); } @@ -861,7 +861,7 @@ sysctl_kern_proc(SYSCTL_HANDLER_ARGS) /* * Show a user only appropriate processes. */ - if (p_cansee(curproc, p)) { + if (p_cansee(curthread, p)) { PROC_UNLOCK(p); continue; } @@ -998,7 +998,7 @@ sysctl_kern_proc_args(SYSCTL_HANDLER_ARGS) if (!p) return (0); - if ((!ps_argsopen) && p_cansee(curproc, p)) { + if ((!ps_argsopen) && p_cansee(curthread, p)) { PROC_UNLOCK(p); return (0); } diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c index e4f9d3ad9834..e3d857d2d2c6 100644 --- a/sys/kern/kern_prot.c +++ b/sys/kern/kern_prot.c @@ -168,7 +168,7 @@ getpgid(struct thread *td, struct getpgid_args *uap) } else if ((pt = pfind(uap->pid)) == NULL) error = ESRCH; else { - error = p_cansee(p, pt); + error = p_cansee(td, pt); if (error == 0) td->td_retval[0] = pt->p_pgrp->pg_id; PROC_UNLOCK(pt); @@ -204,7 +204,7 @@ getsid(struct thread *td, struct getsid_args *uap) } else if ((pt = pfind(uap->pid)) == NULL) error = ESRCH; else { - error = p_cansee(p, pt); + error = p_cansee(td, pt); if (error == 0) td->td_retval[0] = pt->p_session->s_sid; PROC_UNLOCK(pt); @@ -422,7 +422,7 @@ setpgid(struct thread *td, register struct setpgid_args *uap) error = ESRCH; goto done; } - if ((error = p_cansee(curproc, targp))) { + if ((error = p_cansee(curthread, targp))) { PROC_UNLOCK(targp); goto done; } @@ -1361,19 +1361,20 @@ cr_cansee(struct ucred *u1, struct ucred *u2) } /*- - * Determine if p1 "can see" the subject specified by p2. + * Determine if td "can see" the subject specified by p. * Returns: 0 for permitted, an errno value otherwise - * Locks: Sufficient locks to protect p1->p_ucred and p2->p_ucred must - * be held. Normally, p1 will be curproc, and a lock must be held - * for p2. - * References: p1 and p2 must be valid for the lifetime of the call + * Locks: Sufficient locks to protect p->p_ucred must be held. td really + * should be curthread. + * References: td and p must be valid for the lifetime of the call */ int -p_cansee(struct proc *p1, struct proc *p2) +p_cansee(struct thread *td, struct proc *p) { /* Wrap cr_cansee() for all functionality. */ - return (cr_cansee(p1->p_ucred, p2->p_ucred)); + KASSERT(td == curthread, ("%s: td not curthread", __func__)); + PROC_LOCK_ASSERT(p, MA_OWNED); + return (cr_cansee(td->td_ucred, p->p_ucred)); } /*- @@ -1387,6 +1388,7 @@ cr_cansignal(struct ucred *cred, struct proc *proc, int signum) { int error; + PROC_LOCK_ASSERT(proc, MA_OWNED); /* * Jail semantics limit the scope of signalling to proc in the * same jail as cred, if cred is in jail. @@ -1448,18 +1450,20 @@ cr_cansignal(struct ucred *cred, struct proc *proc, int signum) /*- - * Determine whether p1 may deliver the specified signal to p2. + * Determine whether td may deliver the specified signal to p. * Returns: 0 for permitted, an errno value otherwise - * Locks: Sufficient locks to protect various components of p1 and p2 - * must be held. Normally, p1 will be curproc, and a lock must - * be held for p2. - * References: p1 and p2 must be valid for the lifetime of the call + * Locks: Sufficient locks to protect various components of td and p + * must be held. td must be curthread, and a lock must be + * held for p. + * References: td and p must be valid for the lifetime of the call */ int -p_cansignal(struct proc *p1, struct proc *p2, int signum) +p_cansignal(struct thread *td, struct proc *p, int signum) { - if (p1 == p2) + KASSERT(td == curthread, ("%s: td not curthread", __func__)); + PROC_LOCK_ASSERT(p, MA_OWNED); + if (td->td_proc == p) return (0); /* @@ -1467,40 +1471,43 @@ p_cansignal(struct proc *p1, struct proc *p2, int signum) * session always be able to deliver SIGCONT to one another, * overriding the remaining protections. */ - if (signum == SIGCONT && p1->p_session == p2->p_session) + /* XXX: This will require an additional lock of some sort. */ + if (signum == SIGCONT && td->td_proc->p_session == p->p_session) return (0); - return (cr_cansignal(p1->p_ucred, p2, signum)); + return (cr_cansignal(td->td_ucred, p, signum)); } /*- - * Determine whether p1 may reschedule p2. + * Determine whether td may reschedule p. * Returns: 0 for permitted, an errno value otherwise - * Locks: Sufficient locks to protect various components of p1 and p2 - * must be held. Normally, p1 will be curproc, and a lock must - * be held for p2. - * References: p1 and p2 must be valid for the lifetime of the call + * Locks: Sufficient locks to protect various components of td and p + * must be held. td must be curthread, and a lock must + * be held for p. + * References: td and p must be valid for the lifetime of the call */ int -p_cansched(struct proc *p1, struct proc *p2) +p_cansched(struct thread *td, struct proc *p) { int error; - if (p1 == p2) + KASSERT(td == curthread, ("%s: td not curthread", __func__)); + PROC_LOCK_ASSERT(p, MA_OWNED); + if (td->td_proc == p) return (0); - if ((error = prison_check(p1->p_ucred, p2->p_ucred))) + if ((error = prison_check(td->td_ucred, p->p_ucred))) return (error); - if ((error = cr_seeotheruids(p1->p_ucred, p2->p_ucred))) + if ((error = cr_seeotheruids(td->td_ucred, p->p_ucred))) return (error); - if (p1->p_ucred->cr_ruid == p2->p_ucred->cr_ruid) + if (td->td_ucred->cr_ruid == p->p_ucred->cr_ruid) return (0); - if (p1->p_ucred->cr_uid == p2->p_ucred->cr_ruid) + if (td->td_ucred->cr_uid == p->p_ucred->cr_ruid) return (0); - if (suser_cred(p1->p_ucred, PRISON_ROOT) == 0) + if (suser_cred(td->td_ucred, PRISON_ROOT) == 0) return (0); #ifdef CAPABILITIES - if (!cap_check(NULL, p1, CAP_SYS_NICE, PRISON_ROOT)) + if (!cap_check(NULL, td, CAP_SYS_NICE, PRISON_ROOT)) return (0); #endif @@ -1524,73 +1531,75 @@ SYSCTL_INT(_security_bsd, OID_AUTO, unprivileged_proc_debug, CTLFLAG_RW, "Unprivileged processes may use process debugging facilities"); /*- - * Determine whether p1 may debug p2. + * Determine whether td may debug p. * Returns: 0 for permitted, an errno value otherwise - * Locks: Sufficient locks to protect various components of p1 and p2 - * must be held. Normally, p1 will be curproc, and a lock must - * be held for p2. - * References: p1 and p2 must be valid for the lifetime of the call + * Locks: Sufficient locks to protect various components of td and p + * must be held. td must be curthread, and a lock must + * be held for p. + * References: td and p must be valid for the lifetime of the call */ int -p_candebug(struct proc *p1, struct proc *p2) +p_candebug(struct thread *td, struct proc *p) { int credentialchanged, error, grpsubset, i, uidsubset; + KASSERT(td == curthread, ("%s: td not curthread", __func__)); + PROC_LOCK_ASSERT(p, MA_OWNED); if (!unprivileged_proc_debug) { - error = suser_cred(p1->p_ucred, PRISON_ROOT); + error = suser_cred(td->td_ucred, PRISON_ROOT); if (error) return (error); } - if (p1 == p2) + if (td->td_proc == p) return (0); - if ((error = prison_check(p1->p_ucred, p2->p_ucred))) + if ((error = prison_check(td->td_ucred, p->p_ucred))) return (error); - if ((error = cr_seeotheruids(p1->p_ucred, p2->p_ucred))) + if ((error = cr_seeotheruids(td->td_ucred, p->p_ucred))) return (error); /* - * Is p2's group set a subset of p1's effective group set? This - * includes p2's egid, group access list, rgid, and svgid. + * Is p's group set a subset of td's effective group set? This + * includes p's egid, group access list, rgid, and svgid. */ grpsubset = 1; - for (i = 0; i < p2->p_ucred->cr_ngroups; i++) { - if (!groupmember(p2->p_ucred->cr_groups[i], p1->p_ucred)) { + for (i = 0; i < p->p_ucred->cr_ngroups; i++) { + if (!groupmember(p->p_ucred->cr_groups[i], td->td_ucred)) { grpsubset = 0; break; } } grpsubset = grpsubset && - groupmember(p2->p_ucred->cr_rgid, p1->p_ucred) && - groupmember(p2->p_ucred->cr_svgid, p1->p_ucred); + groupmember(p->p_ucred->cr_rgid, td->td_ucred) && + groupmember(p->p_ucred->cr_svgid, td->td_ucred); /* - * Are the uids present in p2's credential equal to p1's - * effective uid? This includes p2's euid, svuid, and ruid. + * Are the uids present in p's credential equal to td's + * effective uid? This includes p's euid, svuid, and ruid. */ - uidsubset = (p1->p_ucred->cr_uid == p2->p_ucred->cr_uid && - p1->p_ucred->cr_uid == p2->p_ucred->cr_svuid && - p1->p_ucred->cr_uid == p2->p_ucred->cr_ruid); + uidsubset = (td->td_ucred->cr_uid == p->p_ucred->cr_uid && + td->td_ucred->cr_uid == p->p_ucred->cr_svuid && + td->td_ucred->cr_uid == p->p_ucred->cr_ruid); /* * Has the credential of the process changed since the last exec()? */ - credentialchanged = (p2->p_flag & P_SUGID); + credentialchanged = (p->p_flag & P_SUGID); /* - * If p2's gids aren't a subset, or the uids aren't a subset, + * If p's gids aren't a subset, or the uids aren't a subset, * or the credential has changed, require appropriate privilege - * for p1 to debug p2. For POSIX.1e capabilities, this will + * for td to debug p. For POSIX.1e capabilities, this will * require CAP_SYS_PTRACE. */ if (!grpsubset || !uidsubset || credentialchanged) { - error = suser_cred(p1->p_ucred, PRISON_ROOT); + error = suser_cred(td->td_ucred, PRISON_ROOT); if (error) return (error); } /* Can't trace init when securelevel > 0. */ - if (p2 == initproc) { - error = securelevel_gt(p1->p_ucred, 0); + if (p == initproc) { + error = securelevel_gt(td->td_ucred, 0); if (error) return (error); } @@ -1601,7 +1610,7 @@ p_candebug(struct proc *p1, struct proc *p2) * basic correctness/functionality decision. Therefore, this check * should be moved to the caller's of p_candebug(). */ - if ((p2->p_flag & P_INEXEC) != 0) + if ((p->p_flag & P_INEXEC) != 0) return (EAGAIN); return (0); diff --git a/sys/kern/kern_resource.c b/sys/kern/kern_resource.c index b89ccc0a572e..d467c1ad30b3 100644 --- a/sys/kern/kern_resource.c +++ b/sys/kern/kern_resource.c @@ -101,7 +101,7 @@ getpriority(td, uap) p = pfind(uap->who); if (p == NULL) break; - if (p_cansee(td->td_proc, p) == 0) + if (p_cansee(td, p) == 0) low = p->p_ksegrp.kg_nice /* XXXKSE */ ; PROC_UNLOCK(p); } @@ -124,7 +124,7 @@ getpriority(td, uap) sx_sunlock(&proctree_lock); LIST_FOREACH(p, &pg->pg_members, p_pglist) { PROC_LOCK(p); - if (!p_cansee(td->td_proc, p) && p->p_ksegrp.kg_nice /* XXXKSE */ < low) + if (!p_cansee(td, p) && p->p_ksegrp.kg_nice /* XXXKSE */ < low) low = p->p_ksegrp.kg_nice /* XXXKSE */ ; PROC_UNLOCK(p); } @@ -138,7 +138,7 @@ getpriority(td, uap) sx_slock(&allproc_lock); LIST_FOREACH(p, &allproc, p_list) { PROC_LOCK(p); - if (!p_cansee(td->td_proc, p) && + if (!p_cansee(td, p) && p->p_ucred->cr_uid == uap->who && p->p_ksegrp.kg_nice /* XXXKSE */ < low) low = p->p_ksegrp.kg_nice /* XXXKSE */ ; @@ -190,7 +190,7 @@ setpriority(td, uap) p = pfind(uap->who); if (p == 0) break; - if (p_cansee(td->td_proc, p) == 0) + if (p_cansee(td, p) == 0) error = donice(td, p, uap->prio); PROC_UNLOCK(p); } @@ -214,7 +214,7 @@ setpriority(td, uap) sx_sunlock(&proctree_lock); LIST_FOREACH(p, &pg->pg_members, p_pglist) { PROC_LOCK(p); - if (!p_cansee(td->td_proc, p)) { + if (!p_cansee(td, p)) { error = donice(td, p, uap->prio); found++; } @@ -231,7 +231,7 @@ setpriority(td, uap) FOREACH_PROC_IN_SYSTEM(p) { PROC_LOCK(p); if (p->p_ucred->cr_uid == uap->who && - !p_cansee(td->td_proc, p)) { + !p_cansee(td, p)) { error = donice(td, p, uap->prio); found++; } @@ -259,7 +259,7 @@ donice(td, chgp, n) int error; PROC_LOCK_ASSERT(chgp, MA_OWNED); - if ((error = p_cansched(td->td_proc, chgp))) + if ((error = p_cansched(td, chgp))) return (error); if (n > PRIO_MAX) n = PRIO_MAX; @@ -314,7 +314,7 @@ rtprio(td, uap) switch (uap->function) { case RTP_LOOKUP: - if ((error = p_cansee(td->td_proc, p))) + if ((error = p_cansee(td, p))) break; mtx_lock_spin(&sched_lock); pri_to_rtp(&p->p_ksegrp /* XXXKSE */ , &rtp); @@ -322,7 +322,7 @@ rtprio(td, uap) PROC_UNLOCK(p); return (copyout(&rtp, uap->rtp, sizeof(struct rtprio))); case RTP_SET: - if ((error = p_cansched(td->td_proc, p)) || (error = cierror)) + if ((error = p_cansched(td, p)) || (error = cierror)) break; /* disallow setting rtprio in most cases if not superuser */ if (suser(td) != 0) { diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 3b013666c3fa..2a57c91ba350 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -1012,7 +1012,7 @@ killpg1(td, sig, pgid, all) PROC_UNLOCK(p); continue; } - if (p_cansignal(td->td_proc, p, sig) == 0) { + if (p_cansignal(td, p, sig) == 0) { nfound++; if (sig) psignal(p, sig); @@ -1046,7 +1046,7 @@ killpg1(td, sig, pgid, all) PROC_UNLOCK(p); continue; } - if (p_cansignal(td->td_proc, p, sig) == 0) { + if (p_cansignal(td, p, sig) == 0) { nfound++; if (sig) psignal(p, sig); @@ -1084,8 +1084,7 @@ kill(td, uap) /* kill single process */ if ((p = pfind(uap->pid)) == NULL) { error = ESRCH; - } else if ((error = p_cansignal(td->td_proc, p, uap->signum)) - != 0) { + } else if ((error = p_cansignal(td, p, uap->signum)) != 0) { PROC_UNLOCK(p); } else { if (uap->signum) diff --git a/sys/kern/p1003_1b.c b/sys/kern/p1003_1b.c index e6bad42447d3..9e6fdcae3e0f 100644 --- a/sys/kern/p1003_1b.c +++ b/sys/kern/p1003_1b.c @@ -131,7 +131,7 @@ int sched_setparam(struct thread *td, targettd = FIRST_THREAD_IN_PROC(targetp); /* XXXKSE */ } - e = p_cansched(td->td_proc, targetp); + e = p_cansched(td, targetp); PROC_UNLOCK(targetp); if (e == 0) { e = ksched_setparam(&td->td_retval[0], ksched, targettd, @@ -167,7 +167,7 @@ int sched_getparam(struct thread *td, targettd = FIRST_THREAD_IN_PROC(targetp); /* XXXKSE */ } - e = p_cansee(td->td_proc, targetp); + e = p_cansee(td, targetp); PROC_UNLOCK(targetp); if (e) goto done2; @@ -209,7 +209,7 @@ int sched_setscheduler(struct thread *td, targettd = FIRST_THREAD_IN_PROC(targetp); /* XXXKSE */ } - e = p_cansched(td->td_proc, targetp); + e = p_cansched(td, targetp); PROC_UNLOCK(targetp); if (e == 0) { e = ksched_setscheduler(&td->td_retval[0], ksched, targettd, @@ -244,7 +244,7 @@ int sched_getscheduler(struct thread *td, targettd = FIRST_THREAD_IN_PROC(targetp); /* XXXKSE */ } - e = p_cansee(td->td_proc, targetp); + e = p_cansee(td, targetp); PROC_UNLOCK(targetp); if (e == 0) e = ksched_getscheduler(&td->td_retval[0], ksched, targettd); @@ -320,7 +320,7 @@ int sched_rr_get_interval(struct thread *td, targettd = FIRST_THREAD_IN_PROC(targetp); /* XXXKSE */ } - e = p_cansee(td->td_proc, targetp); + e = p_cansee(td, targetp); PROC_UNLOCK(targetp); if (e == 0) { e = ksched_rr_get_interval(&td->td_retval[0], ksched, targettd, diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c index 6faf442768ee..6fc7417ec7fe 100644 --- a/sys/kern/sys_process.c +++ b/sys/kern/sys_process.c @@ -388,12 +388,12 @@ ptrace(struct thread *td, struct ptrace_args *uap) return (ESRCH); } } - if (p_cansee(td->td_proc, p)) { + if (p_cansee(td, p)) { error = ESRCH; goto fail; } - if ((error = p_candebug(td->td_proc, p)) != 0) + if ((error = p_candebug(td, p)) != 0) goto fail; /* |