SELinux fixups needed for preemptable RCU from -rt
PATCH 1/1 SELinux fixups needed for preemptable RCU from -rt
Hello!
The attached patch needs to move from -rt to mainline given preemptable RCU. This patch fixes SELinux code that implicitly assumes that disabling preemption prevents an RCU grace period from completing, an assumption that is valid for Classic RCU, but not necessarily for preemptable RCU. Explicit rcu_read_lock() calls are thus added.
---
security/selinux/avc.c | 9 +++++++++ security/selinux/netif.c | 2 ++ 2 files changed, 11 insertions(+)
security/selinux/avc.c +9 -0
@@ -312,6 +312,7 @@ static inline int avc_reclaim_node(void)if (!spin_trylock_irqsave (&avc_cache.slots_lock[hvalue], flags))continue ; +rcu_read_lock ();list_for_each_entry (node, &avc_cache.slots[hvalue], list) {if (atomic_dec_and_test (&node->ae.used)) {/* Recently Unused */
@@ -319,11 +320,13 @@ static inline int avc_reclaim_node(void)avc_cache_stats_incr (reclaims); ecx++;if (ecx >=AVC_CACHE_RECLAIM ) { +rcu_read_unlock ();spin_unlock_irqrestore (&avc_cache.slots_lock[hvalue], flags); goto out; } } } +rcu_read_unlock ();spin_unlock_irqrestore (&avc_cache.slots_lock[hvalue], flags); } out:
@@ -807,8 +810,14 @@ int avc_ss_reset(u32 seqno)for (i =0 ; i <AVC_CACHE_SLOTS ; i++) {spin_lock_irqsave (&avc_cache.slots_lock[i], flag); +/* +* On -rt the outer spinlock does not prevent RCU +* from being performed: +*/ +rcu_read_lock ();list_for_each_entry (node, &avc_cache.slots[i], list)avc_node_delete (node); +rcu_read_unlock ();spin_unlock_irqrestore (&avc_cache.slots_lock[i], flag); }
security/selinux/netif.c +2 -0
@@ -210,6 +210,7 @@ static void sel_netif_flush(void) {int idx; +rcu_read_lock ();spin_lock_bh (&sel_netif_lock);for (idx =0 ; idx <SEL_NETIF_HASH_SIZE ; idx++) {struct sel_netif *netif;
@@ -218,6 +219,7 @@ static void sel_netif_flush(void)sel_netif_destroy (netif); }spin_unlock_bh (&sel_netif_lock); +rcu_read_unlock (); } static int sel_netif_avc_callback(u32 event, u32 ssid, u32 tsid,
security/selinux/avc.c int avc_ss_reset(u32 seqno) · line 815
Quoted 7 lines · Paul E. McKenney
security/selinux/avc.c +3
-0@@ -807,8 +810,14 @@ int avc_ss_reset(u32 seqno)for (i =0 ; i <AVC_CACHE_SLOTS ; i++) {spin_lock_irqsave (&avc_cache.slots_lock[i], flag); +/* +* On -rt the outer spinlock does not prevent RCU +* from being performed:
I would suggest to change this comment to "With preemptible RCU" from "On -rt".
-- Steve
security/selinux/avc.c int avc_ss_reset(u32 seqno) · line 823
Quoted 8 lines
security/selinux/avc.c +3
-0+*/ +rcu_read_lock ();list_for_each_entry (node, &avc_cache.slots[i], list)avc_node_delete (node); +rcu_read_unlock ();spin_unlock_irqrestore (&avc_cache.slots_lock[i], flag); }
5A
Quoted 4 lines · Steven Rostedt
Quoted 2 lines · Paul E. McKenney
(quoted diff) +0
-0@@ -807,8 +810,14 @@ int avc_ss_reset(u32 seqno)
Quoted 8 lines
Review int avc_ss_reset(u32 seqno) · line 815
Quoted 5 lines
(quoted diff) +3
-0for (i = 0; i < AVC_CACHE_SLOTS; i++) { spin_lock_irqsave(&avc_cache.slots_lock[i], flag); + /* + * On -rt the outer spinlock does not prevent RCU + * from being performed:I would suggest to change this comment to "With preemptible RCU" from "On -rt".
Good point... How about the following?
Quoted 9 lines
-- Steve
Review int avc_ss_reset(u32 seqno) · line 822
Quoted 7 lines
(quoted diff) +3
-0+ */ + rcu_read_lock(); list_for_each_entry(node, &avc_cache.slots[i], list) avc_node_delete(node); + rcu_read_unlock(); spin_unlock_irqrestore(&avc_cache.slots_lock[i], flag); }
--- security/selinux/avc.c | 9 +++++++++ security/selinux/netif.c | 2 ++ 2 files changed, 11 insertions(+)
security/selinux/avc.c +9 -0
@@ -312,6 +312,7 @@ static inline int avc_reclaim_node(void)if (!spin_trylock_irqsave (&avc_cache.slots_lock[hvalue], flags))continue ; +rcu_read_lock ();list_for_each_entry (node, &avc_cache.slots[hvalue], list) {if (atomic_dec_and_test (&node->ae.used)) {/* Recently Unused */
@@ -319,11 +320,13 @@ static inline int avc_reclaim_node(void)avc_cache_stats_incr (reclaims); ecx++;if (ecx >=AVC_CACHE_RECLAIM ) { +rcu_read_unlock ();spin_unlock_irqrestore (&avc_cache.slots_lock[hvalue], flags); goto out; } } } +rcu_read_unlock ();spin_unlock_irqrestore (&avc_cache.slots_lock[hvalue], flags); } out:
@@ -807,8 +810,14 @@ int avc_ss_reset(u32 seqno)for (i =0 ; i <AVC_CACHE_SLOTS ; i++) {spin_lock_irqsave (&avc_cache.slots_lock[i], flag); +/* +* With preemptable RCU, the outer spinlock does not +* prevent RCU grace periods from ending. +*/ +rcu_read_lock ();list_for_each_entry (node, &avc_cache.slots[i], list)avc_node_delete (node); +rcu_read_unlock ();spin_unlock_irqrestore (&avc_cache.slots_lock[i], flag); }
security/selinux/netif.c +2 -0
@@ -210,6 +210,7 @@ static void sel_netif_flush(void) {int idx; +rcu_read_lock ();spin_lock_bh (&sel_netif_lock);for (idx =0 ; idx <SEL_NETIF_HASH_SIZE ; idx++) {struct sel_netif *netif;
@@ -218,6 +219,7 @@ static void sel_netif_flush(void)sel_netif_destroy (netif); }spin_unlock_bh (&sel_netif_lock); +rcu_read_unlock (); } static int sel_netif_avc_callback(u32 event, u32 ssid, u32 tsid,
Steven Rostedt
Acked-byQuoted 14 lines · Paul E. McKenney
Quoted 4 lines · Steven Rostedt
Quoted 2 lines · Paul E. McKenney
(quoted diff) +0
-0@@ -807,8 +810,14 @@ int avc_ss_reset(u32 seqno)Quoted 8 lines
security/selinux/avc.c int avc_ss_reset(u32 seqno)
Quoted 5 lines
security/selinux/avc.c +3
-0for (i =0 ; i <AVC_CACHE_SLOTS ; i++) {spin_lock_irqsave (&avc_cache.slots_lock[i], flag); +/* +* On -rt the outer spinlock does not prevent RCU +* from being performed: I would suggest to change this comment to "With preemptible RCU" from "On -rt".
Quoted 1 line
Good point... How about the following?
-- Steve
James Morris
AppliedThanks, applied to
git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/selinux-2.6.git#for-linus
Quoted 73 lines
Signed-off-by Paul E. McKenney <[email protected]> (comment change)--- security/selinux/avc.c | 9 +++++++++ security/selinux/netif.c | 2 ++ 2 files changed, 11 insertions(+)Index:
linux-2.6.24.4-rt4/security/selinux/avc.c
===================================================================security/selinux/avc.c +9
-0@@ -312,6 +312,7 @@ static inline int avc_reclaim_node(void)if (!spin_trylock_irqsave (&avc_cache.slots_lock[hvalue], flags))continue ; +rcu_read_lock ();list_for_each_entry (node, &avc_cache.slots[hvalue], list) {if (atomic_dec_and_test (&node->ae.used)) {/* Recently Unused */ @@ -319,11 +320,13 @@ static inline int avc_reclaim_node(void)avc_cache_stats_incr (reclaims); ecx++;if (ecx >=AVC_CACHE_RECLAIM ) { +rcu_read_unlock ();spin_unlock_irqrestore (&avc_cache.slots_lock[hvalue], flags); goto out; } } } +rcu_read_unlock ();spin_unlock_irqrestore (&avc_cache.slots_lock[hvalue], flags); } out:@@ -807,8 +810,14 @@ int avc_ss_reset(u32 seqno)for (i =0 ; i <AVC_CACHE_SLOTS ; i++) {spin_lock_irqsave (&avc_cache.slots_lock[i], flag); +/* +* With preemptable RCU, the outer spinlock does not +* prevent RCU grace periods from ending. +*/ +rcu_read_lock ();list_for_each_entry (node, &avc_cache.slots[i], list)avc_node_delete (node); +rcu_read_unlock ();spin_unlock_irqrestore (&avc_cache.slots_lock[i], flag); }Index:
linux-2.6.24.4-rt4/security/selinux/netif.c
===================================================================security/selinux/netif.c +2
-1@@ -210,6 +210,7 @@ static void sel_netif_flush(void) {int idx; +rcu_read_lock ();spin_lock_bh (&sel_netif_lock);for (idx =0 ; idx <SEL_NETIF_HASH_SIZE ; idx++) {struct sel_netif *netif;@@ -218,6 +219,7 @@ static void sel_netif_flush(void)sel_netif_destroy (netif); }spin_unlock_bh (&sel_netif_lock); +rcu_read_unlock (); } static int sel_netif_avc_callback(u32 event, u32 ssid, u32 tsid, --To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Signature · 2 lines
James Morris <[email protected]>