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

Commit a5dda683 authored by Eric Paris's avatar Eric Paris Committed by James Morris
Browse files

SELinux: check seqno when updating an avc_node



The avc update node callbacks do not check the seqno of the caller with the
seqno of the node found.  It is possible that a policy change could happen
(although almost impossibly unlikely) in which a permissive or
permissive_domain decision is not valid for the entry found.  Simply pass
and check that the seqno of the caller and the seqno of the node found
match.

Signed-off-by: default avatarEric Paris <eparis@redhat.com>
Acked-by: default avatarStephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: default avatarJames Morris <jmorris@namei.org>
parent 4cb912f1
Loading
Loading
Loading
Loading
+6 −3
Original line number Original line Diff line number Diff line
@@ -742,13 +742,15 @@ static inline int avc_sidcmp(u32 x, u32 y)
 * @event : Updating event
 * @event : Updating event
 * @perms : Permission mask bits
 * @perms : Permission mask bits
 * @ssid,@tsid,@tclass : identifier of an AVC entry
 * @ssid,@tsid,@tclass : identifier of an AVC entry
 * @seqno : sequence number when decision was made
 *
 *
 * if a valid AVC entry doesn't exist,this function returns -ENOENT.
 * if a valid AVC entry doesn't exist,this function returns -ENOENT.
 * if kmalloc() called internal returns NULL, this function returns -ENOMEM.
 * if kmalloc() called internal returns NULL, this function returns -ENOMEM.
 * otherwise, this function update the AVC entry. The original AVC-entry object
 * otherwise, this function update the AVC entry. The original AVC-entry object
 * will release later by RCU.
 * will release later by RCU.
 */
 */
static int avc_update_node(u32 event, u32 perms, u32 ssid, u32 tsid, u16 tclass)
static int avc_update_node(u32 event, u32 perms, u32 ssid, u32 tsid, u16 tclass,
			   u32 seqno)
{
{
	int hvalue, rc = 0;
	int hvalue, rc = 0;
	unsigned long flag;
	unsigned long flag;
@@ -767,7 +769,8 @@ static int avc_update_node(u32 event, u32 perms, u32 ssid, u32 tsid, u16 tclass)
	list_for_each_entry(pos, &avc_cache.slots[hvalue], list) {
	list_for_each_entry(pos, &avc_cache.slots[hvalue], list) {
		if (ssid == pos->ae.ssid &&
		if (ssid == pos->ae.ssid &&
		    tsid == pos->ae.tsid &&
		    tsid == pos->ae.tsid &&
		    tclass == pos->ae.tclass){
		    tclass == pos->ae.tclass &&
		    seqno == pos->ae.avd.seqno){
			orig = pos;
			orig = pos;
			break;
			break;
		}
		}
@@ -908,7 +911,7 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid,
			rc = -EACCES;
			rc = -EACCES;
		else if (!selinux_enforcing || security_permissive_sid(ssid))
		else if (!selinux_enforcing || security_permissive_sid(ssid))
			avc_update_node(AVC_CALLBACK_GRANT, requested, ssid,
			avc_update_node(AVC_CALLBACK_GRANT, requested, ssid,
					tsid, tclass);
					tsid, tclass, p_ae->avd.seqno);
		else
		else
			rc = -EACCES;
			rc = -EACCES;
	}
	}