netfilter: use rcu_read_bh() in ipt_do_table()
Eric Dumazet [Thu, 2 Apr 2009 07:53:49 +0000 (00:53 -0700)]
Commit 784544739a25c30637397ace5489eeb6e15d7d49
(netfilter: iptables: lock free counters) forgot to disable BH
in arpt_do_table(), ipt_do_table() and  ip6t_do_table()

Use rcu_read_lock_bh() instead of rcu_read_lock() cures the problem.

Reported-and-bisected-by: Roman Mindalev <r000n@r000n.net>
Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>
Acked-by: Patrick McHardy <kaber@trash.net>
Acked-by: Stephen Hemminger <shemminger@vyatta.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

net/ipv4/netfilter/arp_tables.c
net/ipv4/netfilter/ip_tables.c
net/ipv6/netfilter/ip6_tables.c

index 35c5f6a..5ba533d 100644 (file)
@@ -253,7 +253,7 @@ unsigned int arpt_do_table(struct sk_buff *skb,
        indev = in ? in->name : nulldevname;
        outdev = out ? out->name : nulldevname;
 
-       rcu_read_lock();
+       rcu_read_lock_bh();
        private = rcu_dereference(table->private);
        table_base = rcu_dereference(private->entries[smp_processor_id()]);
 
@@ -329,7 +329,7 @@ unsigned int arpt_do_table(struct sk_buff *skb,
                }
        } while (!hotdrop);
 
-       rcu_read_unlock();
+       rcu_read_unlock_bh();
 
        if (hotdrop)
                return NF_DROP;
index 82ee7c9..810c0b6 100644 (file)
@@ -339,7 +339,7 @@ ipt_do_table(struct sk_buff *skb,
 
        IP_NF_ASSERT(table->valid_hooks & (1 << hook));
 
-       rcu_read_lock();
+       rcu_read_lock_bh();
        private = rcu_dereference(table->private);
        table_base = rcu_dereference(private->entries[smp_processor_id()]);
 
@@ -437,7 +437,7 @@ ipt_do_table(struct sk_buff *skb,
                }
        } while (!hotdrop);
 
-       rcu_read_unlock();
+       rcu_read_unlock_bh();
 
 #ifdef DEBUG_ALLOW_ALL
        return NF_ACCEPT;
index e89cfa3..dfed176 100644 (file)
@@ -365,7 +365,7 @@ ip6t_do_table(struct sk_buff *skb,
 
        IP_NF_ASSERT(table->valid_hooks & (1 << hook));
 
-       rcu_read_lock();
+       rcu_read_lock_bh();
        private = rcu_dereference(table->private);
        table_base = rcu_dereference(private->entries[smp_processor_id()]);
 
@@ -466,7 +466,7 @@ ip6t_do_table(struct sk_buff *skb,
 #ifdef CONFIG_NETFILTER_DEBUG
        ((struct ip6t_entry *)table_base)->comefrom = NETFILTER_LINK_POISON;
 #endif
-       rcu_read_unlock();
+       rcu_read_unlock_bh();
 
 #ifdef DEBUG_ALLOW_ALL
        return NF_ACCEPT;