From babe9a2bb37a1c0a1e87cbe5c3ce5fd40c70d990 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Mon, 18 Apr 2005 13:36:57 +0000 Subject: [PATCH] Introduce p_canwait() and MAC Framework and MAC Policy entry points mac_check_proc_wait(), which control the ability to wait4() specific processes. This permits MAC policies to limit information flow from children that have changed label, although has to be handled carefully due to common programming expectations regarding the behavior of wait4(). The cr_seeotheruids() check in p_canwait() is #if 0'd for this reason. The mac_stub and mac_test policies are updated to reflect these new entry points. Sponsored by: SPAWAR, SPARTA Obtained from: TrustedBSD Project --- sys/kern/kern_exit.c | 4 ++++ sys/kern/kern_prot.c | 31 +++++++++++++++++++++++++++++++ sys/security/mac/mac_framework.h | 1 + sys/security/mac/mac_policy.h | 2 ++ sys/security/mac/mac_process.c | 15 +++++++++++++++ sys/security/mac_stub/mac_stub.c | 8 ++++++++ sys/security/mac_test/mac_test.c | 11 +++++++++++ sys/sys/mac.h | 1 + sys/sys/mac_policy.h | 2 ++ sys/sys/proc.h | 1 + 10 files changed, 76 insertions(+) diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index e27e9b0cf75..8b31e351641 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -597,6 +597,10 @@ loop: PROC_UNLOCK(p); continue; } + if (p_canwait(td, p)) { + PROC_UNLOCK(p); + continue; + } /* * This special case handles a kthread spawned by linux_clone diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c index 56ec0dd4bcb..ebe4b18f469 100644 --- a/sys/kern/kern_prot.c +++ b/sys/kern/kern_prot.c @@ -1800,6 +1800,37 @@ cr_canseesocket(struct ucred *cred, struct socket *so) return (0); } +/*- + * Determine whether td can wait for the exit of p. + * Returns: 0 for permitted, an errno value otherwise + * 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_canwait(struct thread *td, struct proc *p) +{ + int error; + + KASSERT(td == curthread, ("%s: td not curthread", __func__)); + PROC_LOCK_ASSERT(p, MA_OWNED); + if ((error = prison_check(td->td_ucred, p->p_ucred))) + return (error); +#ifdef MAC + if ((error = mac_check_proc_wait(td->td_ucred, p))) + return (error); +#endif +#if 0 + /* XXXMAC: This could have odd effects on some shells. */ + if ((error = cr_seeotheruids(td->td_ucred, p->p_ucred))) + return (error); +#endif + + return (0); +} + /* * Allocate a zeroed cred structure. * MPSAFE diff --git a/sys/security/mac/mac_framework.h b/sys/security/mac/mac_framework.h index f72733d6618..8e5037aa791 100644 --- a/sys/security/mac/mac_framework.h +++ b/sys/security/mac/mac_framework.h @@ -351,6 +351,7 @@ int mac_check_proc_setresgid(struct proc *proc, struct ucred *cred, gid_t rgid, gid_t egid, gid_t sgid); int mac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum); +int mac_check_proc_wait(struct ucred *cred, struct proc *proc); int mac_check_socket_accept(struct ucred *cred, struct socket *so); int mac_check_socket_bind(struct ucred *cred, struct socket *so, struct sockaddr *sockaddr); diff --git a/sys/security/mac/mac_policy.h b/sys/security/mac/mac_policy.h index 402d622b915..e519cb35930 100644 --- a/sys/security/mac/mac_policy.h +++ b/sys/security/mac/mac_policy.h @@ -424,6 +424,8 @@ struct mac_policy_ops { gid_t egid, gid_t sgid); int (*mpo_check_proc_signal)(struct ucred *cred, struct proc *proc, int signum); + int (*mpo_check_proc_wait)(struct ucred *cred, + struct proc *proc); int (*mpo_check_socket_accept)(struct ucred *cred, struct socket *so, struct label *socketlabel); int (*mpo_check_socket_bind)(struct ucred *cred, diff --git a/sys/security/mac/mac_process.c b/sys/security/mac/mac_process.c index 8dda7b11387..436c55b878e 100644 --- a/sys/security/mac/mac_process.c +++ b/sys/security/mac/mac_process.c @@ -650,3 +650,18 @@ mac_check_proc_setresgid(struct proc *proc, struct ucred *cred, gid_t rgid, MAC_CHECK(check_proc_setresgid, cred, rgid, egid, sgid); return (error); } + +int +mac_check_proc_wait(struct ucred *cred, struct proc *proc) +{ + int error; + + PROC_LOCK_ASSERT(proc, MA_OWNED); + + if (!mac_enforce_process) + return (0); + + MAC_CHECK(check_proc_wait, cred, proc); + + return (error); +} diff --git a/sys/security/mac_stub/mac_stub.c b/sys/security/mac_stub/mac_stub.c index 9a7f567afa7..64a06d918d2 100644 --- a/sys/security/mac_stub/mac_stub.c +++ b/sys/security/mac_stub/mac_stub.c @@ -841,6 +841,13 @@ stub_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) return (0); } +static int +stub_check_proc_wait(struct ucred *cred, struct proc *proc) +{ + + return (0); +} + static int stub_check_proc_setuid(struct ucred *cred, uid_t uid) { @@ -1456,6 +1463,7 @@ static struct mac_policy_ops mac_stub_ops = .mpo_check_proc_setresuid = stub_check_proc_setresuid, .mpo_check_proc_setresgid = stub_check_proc_setresgid, .mpo_check_proc_signal = stub_check_proc_signal, + .mpo_check_proc_wait = stub_check_proc_wait, .mpo_check_socket_accept = stub_check_socket_accept, .mpo_check_socket_bind = stub_check_socket_bind, .mpo_check_socket_connect = stub_check_socket_connect, diff --git a/sys/security/mac_test/mac_test.c b/sys/security/mac_test/mac_test.c index 1ce97a34b0b..b2fa8532b29 100644 --- a/sys/security/mac_test/mac_test.c +++ b/sys/security/mac_test/mac_test.c @@ -1790,6 +1790,16 @@ mac_test_check_proc_setresgid(struct ucred *cred, gid_t rgid, gid_t egid, return (0); } +static int +mac_test_check_proc_wait(struct ucred *cred, struct proc *proc) +{ + + ASSERT_CRED_LABEL(cred->cr_label); + ASSERT_CRED_LABEL(proc->p_ucred->cr_label); + + return (0); +} + static int mac_test_check_socket_accept(struct ucred *cred, struct socket *socket, struct label *socketlabel) @@ -2506,6 +2516,7 @@ static struct mac_policy_ops mac_test_ops = .mpo_check_proc_setresuid = mac_test_check_proc_setresuid, .mpo_check_proc_setresgid = mac_test_check_proc_setresgid, .mpo_check_proc_signal = mac_test_check_proc_signal, + .mpo_check_proc_wait = mac_test_check_proc_wait, .mpo_check_socket_accept = mac_test_check_socket_accept, .mpo_check_socket_bind = mac_test_check_socket_bind, .mpo_check_socket_connect = mac_test_check_socket_connect, diff --git a/sys/sys/mac.h b/sys/sys/mac.h index f72733d6618..8e5037aa791 100644 --- a/sys/sys/mac.h +++ b/sys/sys/mac.h @@ -351,6 +351,7 @@ int mac_check_proc_setresgid(struct proc *proc, struct ucred *cred, gid_t rgid, gid_t egid, gid_t sgid); int mac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum); +int mac_check_proc_wait(struct ucred *cred, struct proc *proc); int mac_check_socket_accept(struct ucred *cred, struct socket *so); int mac_check_socket_bind(struct ucred *cred, struct socket *so, struct sockaddr *sockaddr); diff --git a/sys/sys/mac_policy.h b/sys/sys/mac_policy.h index 402d622b915..e519cb35930 100644 --- a/sys/sys/mac_policy.h +++ b/sys/sys/mac_policy.h @@ -424,6 +424,8 @@ struct mac_policy_ops { gid_t egid, gid_t sgid); int (*mpo_check_proc_signal)(struct ucred *cred, struct proc *proc, int signum); + int (*mpo_check_proc_wait)(struct ucred *cred, + struct proc *proc); int (*mpo_check_socket_accept)(struct ucred *cred, struct socket *so, struct label *socketlabel); int (*mpo_check_socket_bind)(struct ucred *cred, diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 1af6b7166a7..7a151bbead4 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -851,6 +851,7 @@ int p_candebug(struct thread *td, struct proc *p); int p_cansee(struct thread *td, struct proc *p); int p_cansched(struct thread *td, struct proc *p); int p_cansignal(struct thread *td, struct proc *p, int signum); +int p_canwait(struct thread *td, struct proc *p); struct pargs *pargs_alloc(int len); void pargs_drop(struct pargs *pa); void pargs_free(struct pargs *pa);