summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_prot.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/kern_prot.c')
-rw-r--r--sys/kern/kern_prot.c152
1 files changed, 143 insertions, 9 deletions
diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c
index 33007e7..0750466 100644
--- a/sys/kern/kern_prot.c
+++ b/sys/kern/kern_prot.c
@@ -945,15 +945,15 @@ SYSCTL_INT(_kern, OID_AUTO, suser_permitted, CTLFLAG_RW, &suser_permitted, 0,
*/
int
suser(p)
- struct proc *p;
+ const struct proc *p;
{
return suser_xxx(0, p, 0);
}
int
suser_xxx(cred, proc, flag)
- struct ucred *cred;
- struct proc *proc;
+ const struct ucred *cred;
+ const struct proc *proc;
int flag;
{
if (!suser_permitted)
@@ -971,31 +971,165 @@ suser_xxx(cred, proc, flag)
return (0);
}
-/*
- * Return zero if p1 can fondle p2, return errno (EPERM/ESRCH) otherwise.
- */
+static int
+p_cansee(const struct proc *p1, const struct proc *p2, int *privused)
+{
-int
-p_trespass(struct proc *p1, struct proc *p2)
+ if (privused != NULL)
+ *privused = 0;
+
+ if (!PRISON_CHECK(p1, p2))
+ return (ESRCH);
+
+ if (!ps_showallprocs && (p1->p_ucred->cr_uid != p2->p_ucred->cr_uid) &&
+ suser_xxx(NULL, p1, PRISON_ROOT))
+ return (ESRCH);
+
+ return (0);
+}
+
+static int
+p_cankill(const struct proc *p1, const struct proc *p2, int *privused)
+{
+
+ if (privused != NULL)
+ *privused = 0;
+
+ if (p1 == p2)
+ return (0);
+
+ if (!PRISON_CHECK(p1, p2))
+ return (ESRCH);
+
+ 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?)
+ */
+ if (p1->p_cred->p_ruid == p2->p_ucred->cr_uid)
+ return (0);
+ if (p1->p_ucred->cr_uid == p2->p_ucred->cr_uid)
+ 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);
+ }
+#endif
+
+ return (EPERM);
+}
+
+static int
+p_cansched(const struct proc *p1, const struct proc *p2, int *privused)
{
+ if (privused != NULL)
+ *privused = 0;
+
if (p1 == p2)
return (0);
+
if (!PRISON_CHECK(p1, p2))
return (ESRCH);
+
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?)
+ */
if (p1->p_cred->p_ruid == p2->p_ucred->cr_uid)
return (0);
if (p1->p_ucred->cr_uid == p2->p_ucred->cr_uid)
return (0);
- if (!suser_xxx(0, p1, PRISON_ROOT))
+
+ if (!suser_xxx(0, p1, PRISON_ROOT)) {
+ if (privused != NULL)
+ *privused = 1;
+ return (0);
+ }
+
+#ifdef CAPABILITIES
+ if (!cap_check_xxx(0, p1, CAP_SYS_NICE, PRISON_ROOT)) {
+ if (privused != NULL)
+ *privused = 1;
return (0);
+ }
+#endif
+
return (EPERM);
}
+static int
+p_candebug(const struct proc *p1, const struct proc *p2, int *privused)
+{
+ int error;
+
+ if (privused != NULL)
+ *privused = 0;
+
+ /* XXX it is authorized, but semantics don't permit it */
+ if (p1 == p2)
+ return (0);
+
+ if (!PRISON_CHECK(p1, p2))
+ return (ESRCH);
+
+ /* not owned by you, has done setuid (unless you're root) */
+ /* add a CAP_SYS_PTRACE here? */
+ if ((p1->p_cred->p_ruid != p2->p_cred->p_ruid) ||
+ (p2->p_flag & P_SUGID)) {
+ if ((error = suser_xxx(0, p1, PRISON_ROOT)))
+ return (error);
+ if (privused != NULL)
+ *privused = 1;
+ }
+
+ /* can't trace init when securelevel > 0 */
+ if (securelevel > 0 && p2->p_pid == 1)
+ return (EPERM);
+
+ return (0);
+}
+
+int
+p_can(const struct proc *p1, const struct proc *p2, int operation,
+ int *privused)
+{
+
+ switch(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));
+
+ case P_CAN_DEBUG:
+ return (p_candebug(p1, p2, privused));
+
+ default:
+ panic("p_can: invalid operation");
+ }
+}
+
+
/*
* Allocate a zeroed cred structure.
*/
OpenPOWER on IntegriCloud