summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2001-04-12 02:38:08 +0000
committerrwatson <rwatson@FreeBSD.org>2001-04-12 02:38:08 +0000
commit366237b31fbdbae545c94f65e8f4042687ec44ae (patch)
treed92c96379a59106ffbf6652b655ede41bc6d232c /sys
parentc46318678ba76ee6902af48fa7493a07c0c24bd2 (diff)
downloadFreeBSD-src-366237b31fbdbae545c94f65e8f4042687ec44ae.zip
FreeBSD-src-366237b31fbdbae545c94f65e8f4042687ec44ae.tar.gz
o Replace p_cankill() with p_cansignal(), remove wrappage of p_can()
from signal authorization checking. o p_cansignal() takes three arguments: subject process, object process, and signal number, unlike p_cankill(), which only took into account the processes and not the signal number, improving the abstraction such that CANSIGNAL() from kern_sig.c can now also be eliminated; previously CANSIGNAL() special-cased the handling of SIGCONT based on process session. privused is now deprecated. o The new p_cansignal() further limits the set of signals that may be delivered to processes with P_SUGID set, and restructures the access control check to allow it to be extended more easily. o These changes take into account work done by the OpenBSD Project, as well as by Robert Watson and Thomas Moestl on the TrustedBSD Project. Obtained from: TrustedBSD Project
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_prot.c103
-rw-r--r--sys/kern/kern_sig.c13
-rw-r--r--sys/sys/proc.h2
3 files changed, 75 insertions, 43 deletions
diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c
index 003ff3b..8db2fb6 100644
--- a/sys/kern/kern_prot.c
+++ b/sys/kern/kern_prot.c
@@ -1024,48 +1024,90 @@ p_cansee(struct proc *p1, struct proc *p2, int *privused)
return (u_cansee(p1->p_ucred, p2->p_ucred));
}
-static int
-p_cankill(struct proc *p1, struct proc *p2, int *privused)
+/*
+ * Can process p1 send the signal signum to process p2?
+ */
+int
+p_cansignal(struct proc *p1, struct proc *p2, int signum)
{
- int error;
-
- if (privused != NULL)
- *privused = 0;
-
+ 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.
+ */
if ((error = prison_check(p1->p_ucred, p2->p_ucred)))
return (error);
- if (p1->p_cred->p_ruid == p2->p_cred->p_ruid)
- return (0);
- if (p1->p_ucred->cr_uid == p2->p_cred->p_ruid)
- return (0);
/*
- * XXX should a process be able to affect another process
- * acting as the same uid (i.e., a userland nfsd or the like?)
+ * UNIX signalling semantics require that processes in the same
+ * session always be able to deliver SIGCONT to one another,
+ * overriding the remaining protections.
*/
- if (p1->p_cred->p_ruid == p2->p_ucred->cr_uid)
- return (0);
- if (p1->p_ucred->cr_uid == p2->p_ucred->cr_uid)
+ if (signum == SIGCONT && p1->p_session == p2->p_session)
return (0);
- if (!suser_xxx(0, p1, PRISON_ROOT)) {
- if (privused != NULL)
- *privused = 1;
- return (0);
- }
-
-#ifdef CAPABILITIES
- if (!cap_check_xxx(0, p1, CAP_KILL, PRISON_ROOT)) {
- if (privused != NULL)
- *privused = 1;
- return (0);
+ /*
+ * UNIX uid semantics depend on the status of the P_SUGID
+ * bit on the target process. If the bit is set, then more
+ * restricted signal sets are permitted.
+ */
+ if (p2->p_flag & P_SUGID) {
+ switch (signum) {
+ case 0:
+ case SIGKILL:
+ case SIGINT:
+ case SIGTERM:
+ case SIGSTOP:
+ case SIGTTIN:
+ case SIGTTOU:
+ case SIGTSTP:
+ case SIGHUP:
+ case SIGUSR1:
+ case SIGUSR2:
+ /*
+ * Restricted rules allow a broadish scope of uid
+ * uid overlap.
+ * XXX: Maybe too broad.
+ */
+ if (p1->p_cred->p_ruid != p2->p_cred->p_ruid &&
+ p1->p_ucred->cr_uid != p2->p_cred->p_ruid &&
+ p1->p_cred->p_ruid != p2->p_ucred->cr_uid &&
+ p1->p_ucred->cr_uid != p2->p_ucred->cr_uid) {
+ /* Not permitted, try privilege. */
+ error = suser_xxx(NULL, p1, PRISON_ROOT);
+ if (error)
+ return (error);
+ }
+ break;
+ default:
+ /* Not permitted, try privilege. */
+ error = suser_xxx(NULL, p1, PRISON_ROOT);
+ if (error)
+ return (error);
+ }
+ } else {
+ /*
+ * Normal rules allow a broad scope of uid overlap.
+ * XXX: Maybe too broad.
+ */
+ if (p1->p_cred->p_ruid != p2->p_cred->p_ruid &&
+ p1->p_cred->p_ruid != p2->p_cred->p_svuid &&
+ p1->p_ucred->cr_uid != p2->p_cred->p_ruid &&
+ p1->p_ucred->cr_uid != p2->p_cred->p_svuid &&
+ p1->p_cred->p_ruid != p2->p_ucred->cr_uid &&
+ p1->p_ucred->cr_uid != p2->p_ucred->cr_uid) {
+ /* Not permitted, try privilege. */
+ error = suser_xxx(NULL, p1, PRISON_ROOT);
+ if (error)
+ return (error);
+ }
}
-#endif
- return (EPERM);
+ return (0);
}
static int
@@ -1155,9 +1197,6 @@ p_can(struct proc *p1, struct proc *p2, int operation,
case P_CAN_SEE:
return (p_cansee(p1, p2, privused));
- case P_CAN_KILL:
- return (p_cankill(p1, p2, privused));
-
case P_CAN_SCHED:
return (p_cansched(p1, p2, privused));
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index 6ed921a..e3f2fdb 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -98,13 +98,6 @@ SYSCTL_INT(_kern, KERN_LOGSIGEXIT, logsigexit, CTLFLAG_RW,
"Log processes quitting on abnormal signals to syslog(3)");
/*
- * Can process p, with pcred pc, send the signal sig to process q?
- */
-#define CANSIGNAL(p, q, sig) \
- (!p_can(p, q, P_CAN_KILL, NULL) || \
- ((sig) == SIGCONT && (q)->p_session == (p)->p_session))
-
-/*
* Policy -- Can real uid ruid with ucred uc send a signal to process q?
*/
#define CANSIGIO(ruid, uc, q) \
@@ -910,7 +903,7 @@ killpg1(cp, sig, pgid, all)
* XXX: this locking needs work.. specifically the
* session checks..
*/
- if (!CANSIGNAL(cp, p, sig))
+ if (p_cansignal(cp, p, sig))
continue;
nfound++;
if (sig) {
@@ -945,7 +938,7 @@ killpg1(cp, sig, pgid, all)
}
mtx_unlock_spin(&sched_lock);
/* XXX: locking b0rked */
- if (!CANSIGNAL(cp, p, sig))
+ if (p_cansignal(cp, p, sig))
continue;
nfound++;
if (sig) {
@@ -979,7 +972,7 @@ kill(cp, uap)
if ((p = pfind(uap->pid)) == NULL)
return (ESRCH);
/* XXX: locking b0rked */
- if (!CANSIGNAL(cp, p, uap->signum))
+ if (p_cansignal(cp, p, uap->signum))
return (EPERM);
if (uap->signum) {
PROC_LOCK(p);
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index 4a1c3ac..7ddd621 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -329,7 +329,6 @@ struct proc {
#define P_MAGIC 0xbeefface
#define P_CAN_SEE 1
-#define P_CAN_KILL 2
#define P_CAN_SCHED 3
#define P_CAN_DEBUG 4
@@ -530,6 +529,7 @@ int leavepgrp __P((struct proc *p));
void mi_switch __P((void));
int p_can __P((struct proc *p1, struct proc *p2, int operation,
int *privused));
+int p_cansignal __P((struct proc *p1, struct proc *p2, int signum));
int p_trespass __P((struct proc *p1, struct proc *p2));
void procinit __P((void));
void proc_reparent __P((struct proc *child, struct proc *newparent));
OpenPOWER on IntegriCloud