diff options
author | Patrick McHardy <kaber@trash.net> | 2006-08-21 18:31:08 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-08-22 17:33:56 -0400 |
commit | e0b7cde9975e17a61b4511c7822803dfb7210011 (patch) | |
tree | df2f6669f5016fb3e9c8d089b0c6c850b6bc8a3e /net/ipv4 | |
parent | 2d8f613160ed303f5fe310f21bba334a4b074fa5 (diff) |
[NETFILTER]: arp_tables: fix table locking in arpt_do_table
table->private might change because of ruleset changes, don't use it
without holding the lock.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/netfilter/arp_tables.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index df4854cf598b..8d1d7a6e72a5 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c | |||
@@ -236,7 +236,7 @@ unsigned int arpt_do_table(struct sk_buff **pskb, | |||
236 | struct arpt_entry *e, *back; | 236 | struct arpt_entry *e, *back; |
237 | const char *indev, *outdev; | 237 | const char *indev, *outdev; |
238 | void *table_base; | 238 | void *table_base; |
239 | struct xt_table_info *private = table->private; | 239 | struct xt_table_info *private; |
240 | 240 | ||
241 | /* ARP header, plus 2 device addresses, plus 2 IP addresses. */ | 241 | /* ARP header, plus 2 device addresses, plus 2 IP addresses. */ |
242 | if (!pskb_may_pull((*pskb), (sizeof(struct arphdr) + | 242 | if (!pskb_may_pull((*pskb), (sizeof(struct arphdr) + |
@@ -248,6 +248,7 @@ unsigned int arpt_do_table(struct sk_buff **pskb, | |||
248 | outdev = out ? out->name : nulldevname; | 248 | outdev = out ? out->name : nulldevname; |
249 | 249 | ||
250 | read_lock_bh(&table->lock); | 250 | read_lock_bh(&table->lock); |
251 | private = table->private; | ||
251 | table_base = (void *)private->entries[smp_processor_id()]; | 252 | table_base = (void *)private->entries[smp_processor_id()]; |
252 | e = get_entry(table_base, private->hook_entry[hook]); | 253 | e = get_entry(table_base, private->hook_entry[hook]); |
253 | back = get_entry(table_base, private->underflow[hook]); | 254 | back = get_entry(table_base, private->underflow[hook]); |