diff options
author | Stephen Smalley <sds@tycho.nsa.gov> | 2019-11-22 12:22:45 -0500 |
---|---|---|
committer | Paul Moore <paul@paul-moore.com> | 2019-12-09 18:37:47 -0500 |
commit | 0188d5c025ca8fe756ba3193bd7d150139af5a88 (patch) | |
tree | d0c0095e8765270013f691f0cf5df3626137e8f4 /security/selinux/include | |
parent | 1a37079c236d55fb31ebbf4b59945dab8ec8764c (diff) | |
download | linux-0188d5c025ca8fe756ba3193bd7d150139af5a88.tar.gz linux-0188d5c025ca8fe756ba3193bd7d150139af5a88.tar.bz2 linux-0188d5c025ca8fe756ba3193bd7d150139af5a88.zip |
selinux: fall back to ref-walk if audit is required
commit bda0be7ad994 ("security: make inode_follow_link RCU-walk aware")
passed down the rcu flag to the SELinux AVC, but failed to adjust the
test in slow_avc_audit() to also return -ECHILD on LSM_AUDIT_DATA_DENTRY.
Previously, we only returned -ECHILD if generating an audit record with
LSM_AUDIT_DATA_INODE since this was only relevant from inode_permission.
Move the handling of MAY_NOT_BLOCK to avc_audit() and its inlined
equivalent in selinux_inode_permission() immediately after we determine
that audit is required, and always fall back to ref-walk in this case.
Fixes: bda0be7ad994 ("security: make inode_follow_link RCU-walk aware")
Reported-by: Will Deacon <will@kernel.org>
Suggested-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: Paul Moore <paul@paul-moore.com>
Diffstat (limited to 'security/selinux/include')
-rw-r--r-- | security/selinux/include/avc.h | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/security/selinux/include/avc.h b/security/selinux/include/avc.h index 74ea50977c20..cf4cc3ef959b 100644 --- a/security/selinux/include/avc.h +++ b/security/selinux/include/avc.h @@ -100,8 +100,7 @@ static inline u32 avc_audit_required(u32 requested, int slow_avc_audit(struct selinux_state *state, u32 ssid, u32 tsid, u16 tclass, u32 requested, u32 audited, u32 denied, int result, - struct common_audit_data *a, - unsigned flags); + struct common_audit_data *a); /** * avc_audit - Audit the granting or denial of permissions. @@ -135,9 +134,12 @@ static inline int avc_audit(struct selinux_state *state, audited = avc_audit_required(requested, avd, result, 0, &denied); if (likely(!audited)) return 0; + /* fall back to ref-walk if we have to generate audit */ + if (flags & MAY_NOT_BLOCK) + return -ECHILD; return slow_avc_audit(state, ssid, tsid, tclass, requested, audited, denied, result, - a, flags); + a); } #define AVC_STRICT 1 /* Ignore permissive mode. */ |