aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Paris <eparis@redhat.com>2009-02-12 14:50:11 -0500
committerJames Morris <jmorris@namei.org>2009-02-13 17:22:34 -0500
commita5dda683328f99c781f92c66cc52ffc0639bef58 (patch)
tree2432f51e505fd9242f7081d5bf4e21ff322b73d6
parent4cb912f1d1447077160ace9ce3b3a10696dd74e5 (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>
-rw-r--r--security/selinux/avc.c9
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 */
751static int avc_update_node(u32 event, u32 perms, u32 ssid, u32 tsid, u16 tclass) 752static 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 }