Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e46e01ee authored by Stephen Smalley's avatar Stephen Smalley Committed by Paul Moore
Browse files

selinux: stop passing MAY_NOT_BLOCK to the AVC upon follow_link



commit bda0be7a ("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: default avatarStephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
parent 3a28cff3
Loading
Loading
Loading
Loading
+2 −22
Original line number Diff line number Diff line
@@ -867,9 +867,8 @@ 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_follow_link and selinux_inode_permission
	 * for the VFS MAY_NOT_BLOCK flag, which is transliterated into
	 * AVC_NONBLOCKING for avc_has_perm_noaudit().
	 * logic in selinux_inode_permission for the MAY_NOT_BLOCK flag,
	 * which is transliterated into AVC_NONBLOCKING.
	 */
	if (flags & AVC_NONBLOCKING)
		return 0;
@@ -1209,25 +1208,6 @@ 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;
+2 −3
Original line number Diff line number Diff line
@@ -2925,9 +2925,8 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct inode *inode,
	if (IS_ERR(isec))
		return PTR_ERR(isec);

	return avc_has_perm_flags(&selinux_state,
				  sid, isec->sid, isec->sclass, FILE__READ, &ad,
				  rcu ? MAY_NOT_BLOCK : 0);
	return avc_has_perm(&selinux_state,
			    sid, isec->sid, isec->sclass, FILE__READ, &ad);
}

static noinline int audit_inode_permission(struct inode *inode,
+0 −5
Original line number Diff line number Diff line
@@ -153,11 +153,6 @@ 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,