summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_prot.c
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2002-01-06 00:20:12 +0000
committerrwatson <rwatson@FreeBSD.org>2002-01-06 00:20:12 +0000
commit6b7ac7804da0a1604cb1c94d6797ed24eb584a44 (patch)
tree6507530e4497a5bf6aafba2cf33fed56c75b00b1 /sys/kern/kern_prot.c
parentf974b4f783102e55899b7b1ba8354561c699cb2e (diff)
downloadFreeBSD-src-6b7ac7804da0a1604cb1c94d6797ed24eb584a44.zip
FreeBSD-src-6b7ac7804da0a1604cb1c94d6797ed24eb584a44.tar.gz
- Push much of the logic for p_cansignal() behind cr_cansignal, which
authorized based on a subject credential rather than a subject process. This will permit the same logic to be reused in situations where only the credential generating the signal is available, such as in the delivery of SIGIO. - Because of two clauses, the automatic success against curproc, and the session semantics for SIGCONT, not all logic can be pushed into cr_cansignal(), but those cases should not apply for most other consumers of cr_cansignal(). - This brings the base system inter-process authorization code more into line with the MAC implementation. Obtained from: TrustedBSD Project Sponsored by: DARPA, NAI Labs
Diffstat (limited to 'sys/kern/kern_prot.c')
-rw-r--r--sys/kern/kern_prot.c75
1 files changed, 45 insertions, 30 deletions
diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c
index 0db1f81..6164a44 100644
--- a/sys/kern/kern_prot.c
+++ b/sys/kern/kern_prot.c
@@ -1354,42 +1354,30 @@ p_cansee(struct proc *p1, struct proc *p2)
}
/*-
- * Determine whether p1 may deliver the specified signal to p2.
- * 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
+ * Determine whether cred may deliver the specified signal to proc.
+ * Returns: 0 for permitted, an errno value otherwise.
+ * Locks: A lock must be held for proc.
+ * References: cred and proc must be valid for the lifetime of the call.
*/
int
-p_cansignal(struct proc *p1, struct proc *p2, int signum)
+cr_cansignal(struct ucred *cred, struct proc *proc, int signum)
{
int error;
- if (p1 == p2)
- return (0);
-
/*
- * Jail semantics limit the scope of signalling to p2 in the same
- * jail as p1, if p1 is in jail.
+ * Jail semantics limit the scope of signalling to proc in the
+ * same jail as cred, if cred is in jail.
*/
- if ((error = prison_check(p1->p_ucred, p2->p_ucred)))
+ error = prison_check(cred, proc->p_ucred);
+ if (error)
return (error);
/*
- * UNIX signalling semantics require that processes in the same
- * session always be able to deliver SIGCONT to one another,
- * overriding the remaining protections.
- */
- if (signum == SIGCONT && p1->p_session == p2->p_session)
- return (0);
-
- /*
* UNIX signal semantics depend on the status of the P_SUGID
* bit on the target process. If the bit is set, then additional
* restrictions are placed on the set of available signals.
*/
- if (p2->p_flag & P_SUGID) {
+ if (proc->p_flag & P_SUGID) {
switch (signum) {
case 0:
case SIGKILL:
@@ -1408,8 +1396,8 @@ p_cansignal(struct proc *p1, struct proc *p2, int signum)
*/
break;
default:
- /* Not permitted, privilege is required. */
- error = suser_xxx(NULL, p1, PRISON_ROOT);
+ /* Not permitted without privilege. */
+ error = suser_xxx(cred, NULL, PRISON_ROOT);
if (error)
return (error);
}
@@ -1419,12 +1407,12 @@ p_cansignal(struct proc *p1, struct proc *p2, int signum)
* Generally, the target credential's ruid or svuid must match the
* subject credential's ruid or euid.
*/
- if (p1->p_ucred->cr_ruid != p2->p_ucred->cr_ruid &&
- p1->p_ucred->cr_ruid != p2->p_ucred->cr_svuid &&
- p1->p_ucred->cr_uid != p2->p_ucred->cr_ruid &&
- p1->p_ucred->cr_uid != p2->p_ucred->cr_svuid) {
- /* Not permitted, try privilege. */
- error = suser_xxx(NULL, p1, PRISON_ROOT);
+ if (cred->cr_ruid != proc->p_ucred->cr_ruid &&
+ cred->cr_ruid != proc->p_ucred->cr_svuid &&
+ cred->cr_uid != proc->p_ucred->cr_ruid &&
+ cred->cr_uid != proc->p_ucred->cr_svuid) {
+ /* Not permitted without privilege. */
+ error = suser_xxx(cred, NULL, PRISON_ROOT);
if (error)
return (error);
}
@@ -1432,6 +1420,33 @@ p_cansignal(struct proc *p1, struct proc *p2, int signum)
return (0);
}
+
+/*-
+ * Determine whether p1 may deliver the specified signal to p2.
+ * 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
+ */
+int
+p_cansignal(struct proc *p1, struct proc *p2, int signum)
+{
+
+ if (p1 == p2)
+ return (0);
+
+ /*
+ * UNIX signalling semantics require that processes in the same
+ * session always be able to deliver SIGCONT to one another,
+ * overriding the remaining protections.
+ */
+ if (signum == SIGCONT && p1->p_session == p2->p_session)
+ return (0);
+
+ return (cr_cansignal(p1->p_ucred, p2, signum));
+}
+
/*-
* Determine whether p1 may reschedule p2.
* Returns: 0 for permitted, an errno value otherwise
OpenPOWER on IntegriCloud