summaryrefslogtreecommitdiffstats
path: root/sys/kern/sys_pipe.c
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2002-08-13 02:47:13 +0000
committerrwatson <rwatson@FreeBSD.org>2002-08-13 02:47:13 +0000
commitefe80496468c598981d1e815625ec541d27d9f3c (patch)
treef2237e51452efd9b788588c51fddd5a7960baf3d /sys/kern/sys_pipe.c
parenta61492fada16d9fbae97dccf5cd1db60b24667b1 (diff)
downloadFreeBSD-src-efe80496468c598981d1e815625ec541d27d9f3c.zip
FreeBSD-src-efe80496468c598981d1e815625ec541d27d9f3c.tar.gz
Introduce support for labeling and access control of pipe objects
as part of the TrustedBSD MAC framework. Instrument the creation and destruction of pipes, as well as relevant operations, with necessary calls to the MAC framework. Note that the locking here is probably not quite right yet, but fixes will be forthcoming. Obtained from: TrustedBSD Project Sponsored by: DARPA, NAI Labs
Diffstat (limited to 'sys/kern/sys_pipe.c')
-rw-r--r--sys/kern/sys_pipe.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c
index e0cff3c..861a8b6 100644
--- a/sys/kern/sys_pipe.c
+++ b/sys/kern/sys_pipe.c
@@ -49,6 +49,8 @@
* amount of kernel virtual memory.
*/
+#include "opt_mac.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/fcntl.h>
@@ -57,6 +59,7 @@
#include <sys/filio.h>
#include <sys/kernel.h>
#include <sys/lock.h>
+#include <sys/mac.h>
#include <sys/mutex.h>
#include <sys/ttycom.h>
#include <sys/stat.h>
@@ -266,6 +269,16 @@ pipe(td, uap)
td->td_retval[1] = fd;
rpipe->pipe_peer = wpipe;
wpipe->pipe_peer = rpipe;
+#ifdef MAC
+ /*
+ * struct pipe represents a pipe endpoint. The MAC label is shared
+ * between the connected endpoints. As a result mac_init_pipe() and
+ * mac_create_pipe() should only be called on one of the endpoints
+ * after they have been connected.
+ */
+ mac_init_pipe(rpipe);
+ mac_create_pipe(td->td_ucred, rpipe);
+#endif
mtx_init(pmtx, "pipe mutex", NULL, MTX_DEF | MTX_RECURSE);
rpipe->pipe_mtxp = wpipe->pipe_mtxp = pmtx;
fdrop(rf, td);
@@ -454,6 +467,12 @@ pipe_read(fp, uio, cred, flags, td)
if (error)
goto unlocked_error;
+#ifdef MAC
+ error = mac_check_pipe_op(td->td_ucred, rpipe, MAC_OP_PIPE_READ);
+ if (error)
+ goto locked_error;
+#endif
+
while (uio->uio_resid) {
/*
* normal pipe buffer receive
@@ -559,6 +578,9 @@ pipe_read(fp, uio, cred, flags, td)
goto unlocked_error;
}
}
+#ifdef MAC
+locked_error:
+#endif
pipeunlock(rpipe);
/* XXX: should probably do this before getting any locks. */
@@ -861,6 +883,13 @@ pipe_write(fp, uio, cred, flags, td)
PIPE_UNLOCK(rpipe);
return (EPIPE);
}
+#ifdef MAC
+ error = mac_check_pipe_op(td->td_ucred, wpipe, MAC_OP_PIPE_WRITE);
+ if (error) {
+ PIPE_UNLOCK(rpipe);
+ return (error);
+ }
+#endif
++wpipe->pipe_busy;
/*
@@ -1132,6 +1161,14 @@ pipe_ioctl(fp, cmd, data, td)
struct thread *td;
{
struct pipe *mpipe = (struct pipe *)fp->f_data;
+#ifdef MAC
+ int error;
+
+ /* XXXMAC: Pipe should be locked for this check. */
+ error = mac_check_pipe_ioctl(td->td_ucred, mpipe, cmd, data);
+ if (error)
+ return (error);
+#endif
switch (cmd) {
@@ -1187,9 +1224,17 @@ pipe_poll(fp, events, cred, td)
struct pipe *rpipe = (struct pipe *)fp->f_data;
struct pipe *wpipe;
int revents = 0;
+#ifdef MAC
+ int error;
+#endif
wpipe = rpipe->pipe_peer;
PIPE_LOCK(rpipe);
+#ifdef MAC
+ error = mac_check_pipe_op(td->td_ucred, rpipe, MAC_OP_PIPE_POLL);
+ if (error)
+ goto locked_error;
+#endif
if (events & (POLLIN | POLLRDNORM))
if ((rpipe->pipe_state & PIPE_DIRECTW) ||
(rpipe->pipe_buffer.cnt > 0) ||
@@ -1218,6 +1263,9 @@ pipe_poll(fp, events, cred, td)
wpipe->pipe_state |= PIPE_SEL;
}
}
+#ifdef MAC
+locked_error:
+#endif
PIPE_UNLOCK(rpipe);
return (revents);
@@ -1234,7 +1282,14 @@ pipe_stat(fp, ub, td)
struct thread *td;
{
struct pipe *pipe = (struct pipe *)fp->f_data;
+#ifdef MAC
+ int error;
+ /* XXXMAC: Pipe should be locked for this check. */
+ error = mac_check_pipe_op(td->td_ucred, pipe, MAC_OP_PIPE_STAT);
+ if (error)
+ return (error);
+#endif
bzero(ub, sizeof(*ub));
ub->st_mode = S_IFIFO;
ub->st_blksize = pipe->pipe_buffer.size;
@@ -1330,6 +1385,11 @@ pipeclose(cpipe)
msleep(cpipe, PIPE_MTX(cpipe), PRIBIO, "pipecl", 0);
}
+#ifdef MAC
+ if (cpipe->pipe_label != NULL && cpipe->pipe_peer == NULL)
+ mac_destroy_pipe(cpipe);
+#endif
+
/*
* Disconnect from peer
*/
OpenPOWER on IntegriCloud