diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index f8acb22feb0e..eb1a7c28ddfe 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -1636,12 +1636,14 @@ vn_poll(struct file *fp, int events, struct ucred *active_cred, vp = fp->f_vnode; #if defined(MAC) || defined(AUDIT) - vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); - AUDIT_ARG_VNODE1(vp); - error = mac_vnode_check_poll(active_cred, fp->f_cred, vp); - VOP_UNLOCK(vp); - if (error != 0) - return (error); + if (AUDITING_TD(td) || mac_vnode_check_poll_enabled()) { + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); + AUDIT_ARG_VNODE1(vp); + error = mac_vnode_check_poll(active_cred, fp->f_cred, vp); + VOP_UNLOCK(vp); + if (error != 0) + return (error); + } #endif error = VOP_POLL(vp, events, fp->f_cred, td); return (error); diff --git a/sys/security/mac/mac_framework.c b/sys/security/mac/mac_framework.c index 91f4701737fe..aea3789d572f 100644 --- a/sys/security/mac/mac_framework.c +++ b/sys/security/mac/mac_framework.c @@ -118,11 +118,18 @@ SYSCTL_UINT(_security_mac, OID_AUTO, version, CTLFLAG_RD, &mac_version, 0, ""); /* - * Flags for inlined checks. + * Flags for inlined checks. Note this would be best hotpatched at runtime. + * The following is a band-aid. + * + * Use FPFLAG for hooks running in commonly executed paths and FPFLAG_RARE + * for the rest. */ #define FPFLAG(f) \ bool __read_frequently mac_##f##_fp_flag +#define FPFLAG_RARE(f) \ +bool __read_mostly mac_##f##_fp_flag + FPFLAG(priv_check); FPFLAG(priv_grant); FPFLAG(vnode_check_lookup); @@ -131,8 +138,10 @@ FPFLAG(vnode_check_stat); FPFLAG(vnode_check_read); FPFLAG(vnode_check_write); FPFLAG(vnode_check_mmap); +FPFLAG_RARE(vnode_check_poll); #undef FPFLAG +#undef FPFLAG_RARE /* * Labels consist of a indexed set of "slots", which are allocated policies @@ -416,6 +425,8 @@ struct mac_policy_fastpath_elem mac_policy_fastpath_array[] = { .flag = &mac_vnode_check_write_fp_flag }, { .offset = FPO(vnode_check_mmap), .flag = &mac_vnode_check_mmap_fp_flag }, + { .offset = FPO(vnode_check_poll), + .flag = &mac_vnode_check_poll_fp_flag }, }; static void diff --git a/sys/security/mac/mac_framework.h b/sys/security/mac/mac_framework.h index 866ada8ee6e8..1ab82dd709d4 100644 --- a/sys/security/mac/mac_framework.h +++ b/sys/security/mac/mac_framework.h @@ -463,10 +463,14 @@ mac_vnode_check_open(struct ucred *cred, struct vnode *vp, int mac_vnode_check_mprotect(struct ucred *cred, struct vnode *vp, int prot); + +#define mac_vnode_check_poll_enabled() __predict_false(mac_vnode_check_poll_fp_flag) #ifdef MAC +extern bool mac_vnode_check_poll_fp_flag; int mac_vnode_check_poll(struct ucred *active_cred, struct ucred *file_cred, struct vnode *vp); #else +#define mac_vnode_check_poll_fp_flag 0 static inline int mac_vnode_check_poll(struct ucred *active_cred, struct ucred *file_cred, struct vnode *vp)