diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/sys_pipe.c | 33 | ||||
-rw-r--r-- | sys/security/mac/mac_framework.c | 6 | ||||
-rw-r--r-- | sys/security/mac/mac_framework.h | 25 | ||||
-rw-r--r-- | sys/security/mac/mac_pipe.c | 2 | ||||
-rw-r--r-- | sys/sys/pipe.h | 9 |
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 */ |