summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-04-23 00:15:48 +0200
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-23 00:15:48 +0200
commite199ceee15c8f8652cc3bb97651bdf246ba23c5f (patch)
tree1d6540d2f0724af08e117324326322e9c882260b
parentMerge branch 'i2c-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6 (diff)
parentSELinux fixups needed for preemptable RCU from -rt (diff)
downloadlinux-e199ceee15c8f8652cc3bb97651bdf246ba23c5f.tar.xz
linux-e199ceee15c8f8652cc3bb97651bdf246ba23c5f.zip
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/selinux-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/selinux-2.6: SELinux fixups needed for preemptable RCU from -rt SELinux: no BUG_ON(!ss_initialized) in selinux_clone_mnt_opts
-rw-r--r--security/selinux/avc.c9
-rw-r--r--security/selinux/hooks.c15
-rw-r--r--security/selinux/netif.c2
3 files changed, 23 insertions, 3 deletions
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index 1d69f6649bff..95a8ef4a5073 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -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:
@@ -821,8 +824,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);
}
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 1bf2543ea942..33af321f647b 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -755,9 +755,18 @@ static void selinux_sb_clone_mnt_opts(const struct super_block *oldsb,
int set_context = (oldsbsec->flags & CONTEXT_MNT);
int set_rootcontext = (oldsbsec->flags & ROOTCONTEXT_MNT);
- /* we can't error, we can't save the info, this shouldn't get called
- * this early in the boot process. */
- BUG_ON(!ss_initialized);
+ /*
+ * if the parent was able to be mounted it clearly had no special lsm
+ * mount options. thus we can safely put this sb on the list and deal
+ * with it later
+ */
+ if (!ss_initialized) {
+ spin_lock(&sb_security_lock);
+ if (list_empty(&newsbsec->list))
+ list_add(&newsbsec->list, &superblock_security_head);
+ spin_unlock(&sb_security_lock);
+ return;
+ }
/* how can we clone if the old one wasn't set up?? */
BUG_ON(!oldsbsec->initialized);
diff --git a/security/selinux/netif.c b/security/selinux/netif.c
index c658b84c3196..b4e14bc0bf32 100644
--- a/security/selinux/netif.c
+++ b/security/selinux/netif.c
@@ -239,11 +239,13 @@ static void sel_netif_kill(int ifindex)
{
struct sel_netif *netif;
+ rcu_read_lock();
spin_lock_bh(&sel_netif_lock);
netif = sel_netif_find(ifindex);
if (netif)
sel_netif_destroy(netif);
spin_unlock_bh(&sel_netif_lock);
+ rcu_read_unlock();
}
/**