diff options
author | rwatson <rwatson@FreeBSD.org> | 2002-08-13 02:47:13 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2002-08-13 02:47:13 +0000 |
commit | efe80496468c598981d1e815625ec541d27d9f3c (patch) | |
tree | f2237e51452efd9b788588c51fddd5a7960baf3d /sys | |
parent | a61492fada16d9fbae97dccf5cd1db60b24667b1 (diff) | |
download | FreeBSD-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')
-rw-r--r-- | sys/kern/sys_pipe.c | 60 |
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 */ |