From 1aa37f5392f111ece3c1bf14db8dcca397bcd7b5 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Tue, 1 Oct 2002 04:30:19 +0000 Subject: Improve locking of pipe mutexes in the context of MAC: (1) Where previously the pipe mutex was selectively grabbed during pipe_ioctl(), now always grab it and then release if if not needed. This protects the call to mac_check_pipe_ioctl() to make sure the label remains consistent. (Note: it looks like sigio locking may be incorrect for fgetown() since we call it not-by-reference and sigio locking assumes call by reference). (2) In pipe_stat(), lock the pipe if MAC is compiled in so that the call to mac_check_pipe_stat() gets a locked pipe to protect label consistency. We still release the lock before returning actual stat() data, risking inconsistency, but apparently our pipe locking model accepts that risk. (3) In various pipe MAC authorization checks, assert that the pipe lock is held. (4) Grab the lock when performing a pipe relabel operation, and assert it a little deeper in the stack. Obtained from: TrustedBSD Project Sponsored by: DARPA, Network Associates Laboratories --- sys/security/mac/mac_framework.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'sys/security/mac/mac_framework.c') diff --git a/sys/security/mac/mac_framework.c b/sys/security/mac/mac_framework.c index 607113e4cf8d..43a52bf43382 100644 --- a/sys/security/mac/mac_framework.c +++ b/sys/security/mac/mac_framework.c @@ -2572,6 +2572,11 @@ mac_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, unsigned long cmd, { int error; + PIPE_LOCK_ASSERT(pipe, MA_OWNED); + + if (!mac_enforce_pipe) + return (0); + MAC_CHECK(check_pipe_ioctl, cred, pipe, pipe->pipe_label, cmd, data); return (error); @@ -2582,6 +2587,11 @@ mac_check_pipe_poll(struct ucred *cred, struct pipe *pipe) { int error; + PIPE_LOCK_ASSERT(pipe, MA_OWNED); + + if (!mac_enforce_pipe) + return (0); + MAC_CHECK(check_pipe_poll, cred, pipe, pipe->pipe_label); return (error); @@ -2592,6 +2602,11 @@ mac_check_pipe_read(struct ucred *cred, struct pipe *pipe) { int error; + PIPE_LOCK_ASSERT(pipe, MA_OWNED); + + if (!mac_enforce_pipe) + return (0); + MAC_CHECK(check_pipe_read, cred, pipe, pipe->pipe_label); return (error); @@ -2603,6 +2618,11 @@ mac_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, { int error; + PIPE_LOCK_ASSERT(pipe, MA_OWNED); + + if (!mac_enforce_pipe) + return (0); + MAC_CHECK(check_pipe_relabel, cred, pipe, pipe->pipe_label, newlabel); return (error); @@ -2613,6 +2633,11 @@ mac_check_pipe_stat(struct ucred *cred, struct pipe *pipe) { int error; + PIPE_LOCK_ASSERT(pipe, MA_OWNED); + + if (!mac_enforce_pipe) + return (0); + MAC_CHECK(check_pipe_stat, cred, pipe, pipe->pipe_label); return (error); @@ -2623,6 +2648,11 @@ mac_check_pipe_write(struct ucred *cred, struct pipe *pipe) { int error; + PIPE_LOCK_ASSERT(pipe, MA_OWNED); + + if (!mac_enforce_pipe) + return (0); + MAC_CHECK(check_pipe_write, cred, pipe, pipe->pipe_label); return (error); @@ -2889,6 +2919,8 @@ mac_pipe_label_set(struct ucred *cred, struct pipe *pipe, struct label *label) { int error; + PIPE_LOCK_ASSERT(pipe, MA_OWNED); + error = mac_check_pipe_relabel(cred, pipe, label); if (error) return (error); @@ -3192,7 +3224,9 @@ __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) break; case DTYPE_PIPE: pipe = (struct pipe *)fp->f_data; + PIPE_LOCK(pipe); error = mac_pipe_label_set(td->td_ucred, pipe, &intlabel); + PIPE_UNLOCK(pipe); break; default: error = EINVAL; -- cgit v1.2.3