diff options
author | Eric Paris <eparis@redhat.com> | 2009-02-12 14:50:11 -0500 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2009-02-13 17:22:34 -0500 |
commit | a5dda683328f99c781f92c66cc52ffc0639bef58 (patch) | |
tree | 2432f51e505fd9242f7081d5bf4e21ff322b73d6 /security/selinux/avc.c | |
parent | 4cb912f1d1447077160ace9ce3b3a10696dd74e5 (diff) |
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: Eric Paris <eparis@redhat.com>
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/selinux/avc.c')
-rw-r--r-- | security/selinux/avc.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/security/selinux/avc.c b/security/selinux/avc.c index eb41f43e2772..0d00f4874f32 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c | |||
@@ -742,13 +742,15 @@ static inline int avc_sidcmp(u32 x, u32 y) | |||
742 | * @event : Updating event | 742 | * @event : Updating event |
743 | * @perms : Permission mask bits | 743 | * @perms : Permission mask bits |
744 | * @ssid,@tsid,@tclass : identifier of an AVC entry | 744 | * @ssid,@tsid,@tclass : identifier of an AVC entry |
745 | * @seqno : sequence number when decision was made | ||
745 | * | 746 | * |
746 | * if a valid AVC entry doesn't exist,this function returns -ENOENT. | 747 | * if a valid AVC entry doesn't exist,this function returns -ENOENT. |
747 | * if kmalloc() called internal returns NULL, this function returns -ENOMEM. | 748 | * if kmalloc() called internal returns NULL, this function returns -ENOMEM. |
748 | * otherwise, this function update the AVC entry. The original AVC-entry object | 749 | * otherwise, this function update the AVC entry. The original AVC-entry object |
749 | * will release later by RCU. | 750 | * will release later by RCU. |
750 | */ | 751 | */ |
751 | static int avc_update_node(u32 event, u32 perms, u32 ssid, u32 tsid, u16 tclass) | 752 | static int avc_update_node(u32 event, u32 perms, u32 ssid, u32 tsid, u16 tclass, |
753 | u32 seqno) | ||
752 | { | 754 | { |
753 | int hvalue, rc = 0; | 755 | int hvalue, rc = 0; |
754 | unsigned long flag; | 756 | unsigned long flag; |
@@ -767,7 +769,8 @@ static int avc_update_node(u32 event, u32 perms, u32 ssid, u32 tsid, u16 tclass) | |||
767 | list_for_each_entry(pos, &avc_cache.slots[hvalue], list) { | 769 | list_for_each_entry(pos, &avc_cache.slots[hvalue], list) { |
768 | if (ssid == pos->ae.ssid && | 770 | if (ssid == pos->ae.ssid && |
769 | tsid == pos->ae.tsid && | 771 | tsid == pos->ae.tsid && |
770 | tclass == pos->ae.tclass){ | 772 | tclass == pos->ae.tclass && |
773 | seqno == pos->ae.avd.seqno){ | ||
771 | orig = pos; | 774 | orig = pos; |
772 | break; | 775 | break; |
773 | } | 776 | } |
@@ -908,7 +911,7 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid, | |||
908 | rc = -EACCES; | 911 | rc = -EACCES; |
909 | else if (!selinux_enforcing || security_permissive_sid(ssid)) | 912 | else if (!selinux_enforcing || security_permissive_sid(ssid)) |
910 | avc_update_node(AVC_CALLBACK_GRANT, requested, ssid, | 913 | avc_update_node(AVC_CALLBACK_GRANT, requested, ssid, |
911 | tsid, tclass); | 914 | tsid, tclass, p_ae->avd.seqno); |
912 | else | 915 | else |
913 | rc = -EACCES; | 916 | rc = -EACCES; |
914 | } | 917 | } |