diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index e27e9b0cf750..8b31e351641e 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 56ec0dd4bcbc..ebe4b18f469d 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 f72733d6618d..8e5037aa7916 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 402d622b915f..e519cb35930d 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 8dda7b113874..436c55b878e2 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 9a7f567afa78..64a06d918d2a 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 1ce97a34b0bd..b2fa8532b291 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 f72733d6618d..8e5037aa7916 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 402d622b915f..e519cb35930d 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 1af6b7166a79..7a151bbead49 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);