From efe80496468c598981d1e815625ec541d27d9f3c Mon Sep 17 00:00:00 2001 From: rwatson Date: Tue, 13 Aug 2002 02:47:13 +0000 Subject: 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 --- sys/kern/sys_pipe.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) (limited to 'sys') 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 #include #include @@ -57,6 +59,7 @@ #include #include #include +#include #include #include #include @@ -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 */ -- cgit v1.1