selinux: stop passing MAY_NOT_BLOCK to the AVC upon follow_link

commit bda0be7ad9 ("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>
This commit is contained in:
Stephen Smalley 2018-12-12 10:10:56 -05:00 committed by Paul Moore
parent 3a28cff3bd
commit e46e01eebb
3 changed files with 4 additions and 30 deletions

View File

@ -867,9 +867,8 @@ static int avc_update_node(struct selinux_avc *avc,
* permissive mode that only appear when in enforcing mode. * permissive mode that only appear when in enforcing mode.
* *
* See the corresponding handling in slow_avc_audit(), and the * See the corresponding handling in slow_avc_audit(), and the
* logic in selinux_inode_follow_link and selinux_inode_permission * logic in selinux_inode_permission for the MAY_NOT_BLOCK flag,
* for the VFS MAY_NOT_BLOCK flag, which is transliterated into * which is transliterated into AVC_NONBLOCKING.
* AVC_NONBLOCKING for avc_has_perm_noaudit().
*/ */
if (flags & AVC_NONBLOCKING) if (flags & AVC_NONBLOCKING)
return 0; return 0;
@ -1209,25 +1208,6 @@ int avc_has_perm(struct selinux_state *state, u32 ssid, u32 tsid, u16 tclass,
return rc; 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) u32 avc_policy_seqno(struct selinux_state *state)
{ {
return state->avc->avc_cache.latest_notif; return state->avc->avc_cache.latest_notif;

View File

@ -2925,9 +2925,8 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct inode *inode,
if (IS_ERR(isec)) if (IS_ERR(isec))
return PTR_ERR(isec); return PTR_ERR(isec);
return avc_has_perm_flags(&selinux_state, return avc_has_perm(&selinux_state,
sid, isec->sid, isec->sclass, FILE__READ, &ad, sid, isec->sid, isec->sclass, FILE__READ, &ad);
rcu ? MAY_NOT_BLOCK : 0);
} }
static noinline int audit_inode_permission(struct inode *inode, static noinline int audit_inode_permission(struct inode *inode,

View File

@ -153,11 +153,6 @@ int avc_has_perm(struct selinux_state *state,
u32 ssid, u32 tsid, u32 ssid, u32 tsid,
u16 tclass, u32 requested, u16 tclass, u32 requested,
struct common_audit_data *auditdata); 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, int avc_has_extended_perms(struct selinux_state *state,
u32 ssid, u32 tsid, u16 tclass, u32 requested, u32 ssid, u32 tsid, u16 tclass, u32 requested,