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
This commit is contained in:
Robert Watson 2005-04-18 13:36:57 +00:00
parent da833457eb
commit babe9a2bb3
10 changed files with 76 additions and 0 deletions

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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,

View File

@ -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);
}

View File

@ -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,

View File

@ -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,

View File

@ -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);

View File

@ -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,

View File

@ -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);