Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selinux: stop passing MAY_NOT_BLOCK to the AVC upon follow_link

commit bda0be7ad9948 ("security: make inode_follow_link RCU-walk aware")
switched selinux_inode_follow_link() to use avc_has_perm_flags() and
pass down the MAY_NOT_BLOCK flag if called during RCU walk. However,
the only test of MAY_NOT_BLOCK occurs during slow_avc_audit()
and only if passing an inode as audit data (LSM_AUDIT_DATA_INODE). Since
selinux_inode_follow_link() passes a dentry directly, passing MAY_NOT_BLOCK
here serves no purpose. Switch selinux_inode_follow_link() to use
avc_has_perm() and drop avc_has_perm_flags() since there are no other
users.

Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: Paul Moore <paul@paul-moore.com>

authored by

Stephen Smalley and committed by
Paul Moore
e46e01ee 3a28cff3

+4 -30
+2 -22
security/selinux/avc.c
··· 867 867 * permissive mode that only appear when in enforcing mode. 868 868 * 869 869 * See the corresponding handling in slow_avc_audit(), and the 870 - * logic in selinux_inode_follow_link and selinux_inode_permission 871 - * for the VFS MAY_NOT_BLOCK flag, which is transliterated into 872 - * AVC_NONBLOCKING for avc_has_perm_noaudit(). 870 + * logic in selinux_inode_permission for the MAY_NOT_BLOCK flag, 871 + * which is transliterated into AVC_NONBLOCKING. 873 872 */ 874 873 if (flags & AVC_NONBLOCKING) 875 874 return 0; ··· 1203 1204 1204 1205 rc2 = avc_audit(state, ssid, tsid, tclass, requested, &avd, rc, 1205 1206 auditdata, 0); 1206 - if (rc2) 1207 - return rc2; 1208 - return rc; 1209 - } 1210 - 1211 - int avc_has_perm_flags(struct selinux_state *state, 1212 - u32 ssid, u32 tsid, u16 tclass, u32 requested, 1213 - struct common_audit_data *auditdata, 1214 - int flags) 1215 - { 1216 - struct av_decision avd; 1217 - int rc, rc2; 1218 - 1219 - rc = avc_has_perm_noaudit(state, ssid, tsid, tclass, requested, 1220 - (flags & MAY_NOT_BLOCK) ? AVC_NONBLOCKING : 0, 1221 - &avd); 1222 - 1223 - rc2 = avc_audit(state, ssid, tsid, tclass, requested, &avd, rc, 1224 - auditdata, flags); 1225 1207 if (rc2) 1226 1208 return rc2; 1227 1209 return rc;
+2 -3
security/selinux/hooks.c
··· 2925 2925 if (IS_ERR(isec)) 2926 2926 return PTR_ERR(isec); 2927 2927 2928 - return avc_has_perm_flags(&selinux_state, 2929 - sid, isec->sid, isec->sclass, FILE__READ, &ad, 2930 - rcu ? MAY_NOT_BLOCK : 0); 2928 + return avc_has_perm(&selinux_state, 2929 + sid, isec->sid, isec->sclass, FILE__READ, &ad); 2931 2930 } 2932 2931 2933 2932 static noinline int audit_inode_permission(struct inode *inode,
-5
security/selinux/include/avc.h
··· 153 153 u32 ssid, u32 tsid, 154 154 u16 tclass, u32 requested, 155 155 struct common_audit_data *auditdata); 156 - int avc_has_perm_flags(struct selinux_state *state, 157 - u32 ssid, u32 tsid, 158 - u16 tclass, u32 requested, 159 - struct common_audit_data *auditdata, 160 - int flags); 161 156 162 157 int avc_has_extended_perms(struct selinux_state *state, 163 158 u32 ssid, u32 tsid, u16 tclass, u32 requested,