diff options
author | Stephen Smalley <sds@tycho.nsa.gov> | 2019-11-22 12:22:44 -0500 |
---|---|---|
committer | Paul Moore <paul@paul-moore.com> | 2019-12-09 18:28:56 -0500 |
commit | 1a37079c236d55fb31ebbf4b59945dab8ec8764c (patch) | |
tree | 7981c80629949905c03d4ca9618c6448e0983236 | |
parent | 59438b46471ae6cdfb761afc8c9beaf1e428a331 (diff) |
selinux: revert "stop passing MAY_NOT_BLOCK to the AVC upon follow_link"
This reverts commit e46e01eebbbc ("selinux: stop passing MAY_NOT_BLOCK
to the AVC upon follow_link"). The correct fix is to instead fall
back to ref-walk if audit is required irrespective of the specific
audit data type. This is done in the next commit.
Fixes: e46e01eebbbc ("selinux: stop passing MAY_NOT_BLOCK to the AVC upon follow_link")
Reported-by: Will Deacon <will@kernel.org>
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: Paul Moore <paul@paul-moore.com>
-rw-r--r-- | security/selinux/avc.c | 24 | ||||
-rw-r--r-- | security/selinux/hooks.c | 5 | ||||
-rw-r--r-- | security/selinux/include/avc.h | 5 |
3 files changed, 30 insertions, 4 deletions
diff --git a/security/selinux/avc.c b/security/selinux/avc.c index ecd3829996aa..74c43ebe34bb 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c @@ -862,8 +862,9 @@ static int avc_update_node(struct selinux_avc *avc, * permissive mode that only appear when in enforcing mode. * * See the corresponding handling in slow_avc_audit(), and the - * logic in selinux_inode_permission for the MAY_NOT_BLOCK flag, - * which is transliterated into AVC_NONBLOCKING. + * logic in selinux_inode_follow_link and selinux_inode_permission + * for the VFS MAY_NOT_BLOCK flag, which is transliterated into + * AVC_NONBLOCKING for avc_has_perm_noaudit(). */ if (flags & AVC_NONBLOCKING) return 0; @@ -1205,6 +1206,25 @@ int avc_has_perm(struct selinux_state *state, u32 ssid, u32 tsid, u16 tclass, return rc; } +int avc_has_perm_flags(struct selinux_state *state, + u32 ssid, u32 tsid, u16 tclass, u32 requested, + struct common_audit_data *auditdata, + int flags) +{ + struct av_decision avd; + int rc, rc2; + + rc = avc_has_perm_noaudit(state, ssid, tsid, tclass, requested, + (flags & MAY_NOT_BLOCK) ? AVC_NONBLOCKING : 0, + &avd); + + rc2 = avc_audit(state, ssid, tsid, tclass, requested, &avd, rc, + auditdata, flags); + if (rc2) + return rc2; + return rc; +} + u32 avc_policy_seqno(struct selinux_state *state) { return state->avc->avc_cache.latest_notif; diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 9e1c4780dc20..ed64cb4cd4c5 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -3004,8 +3004,9 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct inode *inode, if (IS_ERR(isec)) return PTR_ERR(isec); - return avc_has_perm(&selinux_state, - sid, isec->sid, isec->sclass, FILE__READ, &ad); + return avc_has_perm_flags(&selinux_state, + sid, isec->sid, isec->sclass, FILE__READ, &ad, + rcu ? MAY_NOT_BLOCK : 0); } static noinline int audit_inode_permission(struct inode *inode, diff --git a/security/selinux/include/avc.h b/security/selinux/include/avc.h index 7be0e1e90e8b..74ea50977c20 100644 --- a/security/selinux/include/avc.h +++ b/security/selinux/include/avc.h @@ -153,6 +153,11 @@ int avc_has_perm(struct selinux_state *state, u32 ssid, u32 tsid, u16 tclass, u32 requested, struct common_audit_data *auditdata); +int avc_has_perm_flags(struct selinux_state *state, + u32 ssid, u32 tsid, + u16 tclass, u32 requested, + struct common_audit_data *auditdata, + int flags); int avc_has_extended_perms(struct selinux_state *state, u32 ssid, u32 tsid, u16 tclass, u32 requested, |