summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/kern/sys_pipe.c33
-rw-r--r--sys/security/mac/mac_framework.c6
-rw-r--r--sys/security/mac/mac_framework.h25
-rw-r--r--sys/security/mac/mac_pipe.c2
-rw-r--r--sys/sys/pipe.h9
5 files changed, 53 insertions, 22 deletions
diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c
index 38b26c8e28f3..6940bbf3fa1f 100644
--- a/sys/kern/sys_pipe.c
+++ b/sys/kern/sys_pipe.c
@@ -140,7 +140,7 @@ __FBSDID("$FreeBSD$");
/* #define PIPE_NODIRECT */
#define PIPE_PEER(pipe) \
- (((pipe)->pipe_state & PIPE_NAMED) ? (pipe) : ((pipe)->pipe_peer))
+ (((pipe)->pipe_type & PIPE_TYPE_NAMED) ? (pipe) : ((pipe)->pipe_peer))
/*
* interfaces to the outside world
@@ -403,7 +403,7 @@ pipe_named_ctor(struct pipe **ppipe, struct thread *td)
error = pipe_paircreate(td, &pp);
if (error != 0)
return (error);
- pp->pp_rpipe.pipe_state |= PIPE_NAMED;
+ pp->pp_rpipe.pipe_type |= PIPE_TYPE_NAMED;
*ppipe = &pp->pp_rpipe;
return (0);
}
@@ -413,7 +413,7 @@ pipe_dtor(struct pipe *dpipe)
{
struct pipe *peer;
- peer = (dpipe->pipe_state & PIPE_NAMED) != 0 ? dpipe->pipe_peer : NULL;
+ peer = (dpipe->pipe_type & PIPE_TYPE_NAMED) != 0 ? dpipe->pipe_peer : NULL;
funsetown(&dpipe->pipe_sigio);
pipeclose(dpipe);
if (peer != NULL) {
@@ -1328,7 +1328,7 @@ pipe_truncate(struct file *fp, off_t length, struct ucred *active_cred,
int error;
cpipe = fp->f_data;
- if (cpipe->pipe_state & PIPE_NAMED)
+ if (cpipe->pipe_type & PIPE_TYPE_NAMED)
error = vnops.fo_truncate(fp, length, active_cred, td);
else
error = invfo_truncate(fp, length, active_cred, td);
@@ -1443,7 +1443,7 @@ pipe_poll(struct file *fp, int events, struct ucred *active_cred,
levents = events &
(POLLIN | POLLINIGNEOF | POLLPRI | POLLRDNORM | POLLRDBAND);
- if (rpipe->pipe_state & PIPE_NAMED && fp->f_flag & FREAD && levents &&
+ if (rpipe->pipe_type & PIPE_TYPE_NAMED && fp->f_flag & FREAD && levents &&
fp->f_pipegen == rpipe->pipe_wgen)
events |= POLLINIGNEOF;
@@ -1496,23 +1496,22 @@ pipe_stat(struct file *fp, struct stat *ub, struct ucred *active_cred,
#endif
pipe = fp->f_data;
- PIPE_LOCK(pipe);
#ifdef MAC
- error = mac_pipe_check_stat(active_cred, pipe->pipe_pair);
- if (error) {
+ if (mac_pipe_check_stat_enabled()) {
+ PIPE_LOCK(pipe);
+ error = mac_pipe_check_stat(active_cred, pipe->pipe_pair);
PIPE_UNLOCK(pipe);
- return (error);
+ if (error) {
+ return (error);
+ }
}
#endif
/* For named pipes ask the underlying filesystem. */
- if (pipe->pipe_state & PIPE_NAMED) {
- PIPE_UNLOCK(pipe);
+ if (pipe->pipe_type & PIPE_TYPE_NAMED) {
return (vnops.fo_stat(fp, ub, active_cred, td));
}
- PIPE_UNLOCK(pipe);
-
bzero(ub, sizeof(*ub));
ub->st_mode = S_IFIFO;
ub->st_blksize = PAGE_SIZE;
@@ -1554,7 +1553,7 @@ pipe_chmod(struct file *fp, mode_t mode, struct ucred *active_cred, struct threa
int error;
cpipe = fp->f_data;
- if (cpipe->pipe_state & PIPE_NAMED)
+ if (cpipe->pipe_type & PIPE_TYPE_NAMED)
error = vn_chmod(fp, mode, active_cred, td);
else
error = invfo_chmod(fp, mode, active_cred, td);
@@ -1569,7 +1568,7 @@ pipe_chown(struct file *fp, uid_t uid, gid_t gid, struct ucred *active_cred,
int error;
cpipe = fp->f_data;
- if (cpipe->pipe_state & PIPE_NAMED)
+ if (cpipe->pipe_type & PIPE_TYPE_NAMED)
error = vn_chown(fp, uid, gid, active_cred, td);
else
error = invfo_chown(fp, uid, gid, active_cred, td);
@@ -1758,7 +1757,7 @@ filt_piperead(struct knote *kn, long hint)
kn->kn_data = rpipe->pipe_pages.cnt;
if ((rpipe->pipe_state & PIPE_EOF) != 0 &&
- ((rpipe->pipe_state & PIPE_NAMED) == 0 ||
+ ((rpipe->pipe_type & PIPE_TYPE_NAMED) == 0 ||
fp->f_pipegen != rpipe->pipe_wgen)) {
kn->kn_flags |= EV_EOF;
return (1);
@@ -1778,7 +1777,7 @@ filt_pipewrite(struct knote *kn, long hint)
* knlist and the list lock (i.e., the pipe lock) is therefore not held.
*/
if (wpipe->pipe_present == PIPE_ACTIVE ||
- (wpipe->pipe_state & PIPE_NAMED) != 0) {
+ (wpipe->pipe_type & PIPE_TYPE_NAMED) != 0) {
PIPE_LOCK_ASSERT(wpipe, MA_OWNED);
if (wpipe->pipe_state & PIPE_DIRECTW) {
diff --git a/sys/security/mac/mac_framework.c b/sys/security/mac/mac_framework.c
index 60431b020782..3ec932147637 100644
--- a/sys/security/mac/mac_framework.c
+++ b/sys/security/mac/mac_framework.c
@@ -141,6 +141,8 @@ FPFLAG(vnode_check_mmap);
FPFLAG_RARE(vnode_check_poll);
FPFLAG_RARE(vnode_check_rename_from);
FPFLAG_RARE(vnode_check_access);
+FPFLAG_RARE(pipe_check_stat);
+FPFLAG_RARE(pipe_check_poll);
#undef FPFLAG
#undef FPFLAG_RARE
@@ -433,6 +435,10 @@ struct mac_policy_fastpath_elem mac_policy_fastpath_array[] = {
.flag = &mac_vnode_check_rename_from_fp_flag },
{ .offset = FPO(vnode_check_access),
.flag = &mac_vnode_check_access_fp_flag },
+ { .offset = FPO(pipe_check_stat),
+ .flag = &mac_pipe_check_stat_fp_flag },
+ { .offset = FPO(pipe_check_poll),
+ .flag = &mac_pipe_check_poll_fp_flag },
};
static void
diff --git a/sys/security/mac/mac_framework.h b/sys/security/mac/mac_framework.h
index c9a0ae3ce1da..ea061d6258ff 100644
--- a/sys/security/mac/mac_framework.h
+++ b/sys/security/mac/mac_framework.h
@@ -208,9 +208,30 @@ void mac_netinet6_nd6_send(struct ifnet *ifp, struct mbuf *m);
int mac_pipe_check_ioctl(struct ucred *cred, struct pipepair *pp,
unsigned long cmd, void *data);
-int mac_pipe_check_poll(struct ucred *cred, struct pipepair *pp);
-int mac_pipe_check_read(struct ucred *cred, struct pipepair *pp);
+int mac_pipe_check_poll_impl(struct ucred *cred, struct pipepair *pp);
+#ifdef MAC
+extern bool mac_pipe_check_poll_fp_flag;
+#else
+#define mac_pipe_check_poll_fp_flag 0
+#endif
+#define mac_pipe_check_poll_enabled() __predict_false(mac_pipe_check_poll_fp_flag)
+static inline int
+mac_pipe_check_poll(struct ucred *cred, struct pipepair *pp)
+{
+
+ if (mac_pipe_check_poll_enabled())
+ return (mac_pipe_check_poll_impl(cred, pp));
+ return (0);
+}
+
+#ifdef MAC
+extern bool mac_pipe_check_stat_fp_flag;
+#else
+#define mac_pipe_check_stat_fp_flag 0
+#endif
+#define mac_pipe_check_stat_enabled() __predict_false(mac_pipe_check_stat_fp_flag)
int mac_pipe_check_stat(struct ucred *cred, struct pipepair *pp);
+int mac_pipe_check_read(struct ucred *cred, struct pipepair *pp);
int mac_pipe_check_write(struct ucred *cred, struct pipepair *pp);
void mac_pipe_create(struct ucred *cred, struct pipepair *pp);
void mac_pipe_destroy(struct pipepair *);
diff --git a/sys/security/mac/mac_pipe.c b/sys/security/mac/mac_pipe.c
index d7cb86c1284d..799801905d54 100644
--- a/sys/security/mac/mac_pipe.c
+++ b/sys/security/mac/mac_pipe.c
@@ -163,7 +163,7 @@ MAC_CHECK_PROBE_DEFINE2(pipe_check_poll, "struct ucred *",
"struct pipepair *");
int
-mac_pipe_check_poll(struct ucred *cred, struct pipepair *pp)
+mac_pipe_check_poll_impl(struct ucred *cred, struct pipepair *pp)
{
int error;
diff --git a/sys/sys/pipe.h b/sys/sys/pipe.h
index 2f1568ab6637..8bdfae8b2308 100644
--- a/sys/sys/pipe.h
+++ b/sys/sys/pipe.h
@@ -95,7 +95,11 @@ struct pipemapping {
#define PIPE_LWANT 0x200 /* Process wants exclusive access to pointers/data. */
#define PIPE_DIRECTW 0x400 /* Pipe direct write active. */
#define PIPE_DIRECTOK 0x800 /* Direct mode ok. */
-#define PIPE_NAMED 0x1000 /* Is a named pipe. */
+
+/*
+ * Bits in pipe_type.
+ */
+#define PIPE_TYPE_NAMED 0x001 /* Is a named pipe. */
/*
* Per-pipe data structure.
@@ -111,7 +115,8 @@ struct pipe {
struct sigio *pipe_sigio; /* information for async I/O */
struct pipe *pipe_peer; /* link with other direction */
struct pipepair *pipe_pair; /* container structure pointer */
- u_int pipe_state; /* pipe status info */
+ u_short pipe_state; /* pipe status info */
+ u_short pipe_type; /* pipe type info */
int pipe_busy; /* busy flag, mostly to handle rundown sanely */
int pipe_present; /* still present? */
int pipe_wgen; /* writer generation for named pipe */