[Devel] [PATCH rh7] net: netfilter: clear xt_table on net exit

Vladimir Davydov vdavydov at parallels.com
Fri Jul 3 04:16:54 PDT 2015


We use net->ipv[46].{ip,ip6,nat_}table* as a mark if the corresponding
netfilter is enabled for the network namespace - see ipt_do_table ->
ve_xt_table_forbidden. Therefore we must clear it on module removal,
when {ipt,ip6t}_unregister_table is called, otherwise if a module gets
reinserted with a feature disabled, we will still call ipt_do_table for
it, which will result in a panic, because the table was freed:

  BUG: unable to handle kernel NULL pointer dereference at 0000000000000050
  IP: [<ffffffffa032bfae>] ipt_do_table+0xee/0x6f5 [ip_tables]
  PGD 0
  Oops: 0000 [#1] SMP
  CPU: 0 PID: 0 Comm: swapper/0 ve: 0 Tainted: G          I --------------   3.10.0-123.1.2.vz7.5.24 #1 5.24
  Hardware name: System Manufacturer System Product Name/KFSN4-DRE, BIOS 1008 09/03/2008
  task: ffffffff818bb620 ti: ffffffff818a8000 task.ti: ffffffff818a8000
  RIP: 0010:[<ffffffffa032bfae>]  [<ffffffffa032bfae>] ipt_do_table+0xee/0x6f5 [ip_tables]
  RSP: 0018:ffff88007dc03880  EFLAGS: 00010206
  RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000
  RDX: 0000000000000000 RSI: ffff88007bc60000 RDI: ffff88007c157800
  RBP: ffff88007dc03998 R08: ffff8800df1d9a80 R09: ffff88007bc60000
  R10: 0000000000000002 R11: ffff88007c518208 R12: ffff88003691dad0
  R13: ffff8800df1d9a80 R14: ffff88007bc60000 R15: ffff88007c157800
  FS:  00007f5e6e4a28c0(0000) GS:ffff88007dc00000(0000) knlGS:00000000f762b6c0
  CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
  CR2: 0000000000000050 CR3: 0000000036d27000 CR4: 00000000000007f0
  DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
  DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
  Stack:
   ffffffff8109a84f ffff88007dc03920 ffffffff81578056 0000000000000046
   ffff88007cff3e68 ffff88007dc183d8 ffff88007dc183c0 0000000000000000
   0000000000000003 0000000000000246 ffff88007dc039f8 ffffffffa032c1f7
  Call Trace:
   <IRQ>
   [<ffffffff8109a84f>] ? try_to_wake_up+0x20f/0x360
   [<ffffffff81578056>] ? ip6_pol_route.isra.46+0x336/0x480
   [<ffffffffa032c1f7>] ? ipt_do_table+0x337/0x6f5 [ip_tables]
   [<ffffffffa03771d7>] nf_nat_ipv4_fn+0x1d7/0x320 [iptable_nat]
   [<ffffffff814fc030>] ? inet_del_offload+0x40/0x40
   [<ffffffffa037753e>] nf_nat_ipv4_in+0x2e/0x90 [iptable_nat]
   [<ffffffff814fc030>] ? inet_del_offload+0x40/0x40
   [<ffffffff814f2fda>] nf_iterate+0xaa/0xc0
   [<ffffffff814fc030>] ? inet_del_offload+0x40/0x40
   [<ffffffff814f3074>] nf_hook_slow+0x84/0x140
   [<ffffffff814fc030>] ? inet_del_offload+0x40/0x40
   [<ffffffff814fcaa4>] ip_rcv+0x344/0x380
   [<ffffffff814c2606>] __netif_receive_skb_core+0x676/0x870
   [<ffffffff814c2818>] __netif_receive_skb+0x18/0x60
   [<ffffffff814c28a0>] netif_receive_skb+0x40/0xd0
   [<ffffffffa0013747>] br_handle_frame_finish+0x247/0x400 [bridge]
   [<ffffffffa0013a75>] br_handle_frame+0x175/0x260 [bridge]
   [<ffffffff814c2212>] __netif_receive_skb_core+0x282/0x870
   [<ffffffff81019fc9>] ? read_tsc+0x9/0x20
   [<ffffffff814c2818>] __netif_receive_skb+0x18/0x60
   [<ffffffff814c28a0>] netif_receive_skb+0x40/0xd0
   [<ffffffff814c32f8>] napi_gro_receive+0x58/0x80
   [<ffffffffa00aab43>] tg3_poll_work+0x943/0xf70 [tg3]
   [<ffffffffa00aef49>] tg3_poll+0x79/0x3a0 [tg3]
   [<ffffffff814c2c6a>] net_rx_action+0x15a/0x250
   [<ffffffff81067777>] __do_softirq+0x117/0x2c0
   [<ffffffff815dd9dc>] call_softirq+0x1c/0x30
   [<ffffffff81014ca5>] do_softirq+0x65/0xa0
   [<ffffffff81067b25>] irq_exit+0x115/0x120
   [<ffffffff815de158>] do_IRQ+0x58/0xf0
   [<ffffffff815d352d>] common_interrupt+0x6d/0x6d
   <EOI>

https://jira.sw.ru/browse/PSBM-34657

Signed-off-by: Vladimir Davydov <vdavydov at parallels.com>
---
 net/ipv4/netfilter/iptable_filter.c  | 1 +
 net/ipv4/netfilter/iptable_mangle.c  | 1 +
 net/ipv4/netfilter/iptable_nat.c     | 1 +
 net/ipv6/netfilter/ip6table_filter.c | 1 +
 net/ipv6/netfilter/ip6table_mangle.c | 1 +
 5 files changed, 5 insertions(+)

diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c
index 4a9c627d05c9..10c18225c645 100644
--- a/net/ipv4/netfilter/iptable_filter.c
+++ b/net/ipv4/netfilter/iptable_filter.c
@@ -86,6 +86,7 @@ static void __net_exit iptable_filter_net_exit(struct net *net)
 		return;
 
 	ipt_unregister_table(net, net->ipv4.iptable_filter);
+	net->ipv4.iptable_filter = NULL;
 
 	net_ipt_module_clear(net, VE_IP_FILTER);
 }
diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c
index be368e23f590..a881a7db2630 100644
--- a/net/ipv4/netfilter/iptable_mangle.c
+++ b/net/ipv4/netfilter/iptable_mangle.c
@@ -123,6 +123,7 @@ static void __net_exit iptable_mangle_net_exit(struct net *net)
 		return;
 
 	ipt_unregister_table(net, net->ipv4.iptable_mangle);
+	net->ipv4.iptable_mangle = NULL;
 
 	net_ipt_module_clear(net, VE_IP_MANGLE);
 }
diff --git a/net/ipv4/netfilter/iptable_nat.c b/net/ipv4/netfilter/iptable_nat.c
index f701df6dad50..182c11a1d560 100644
--- a/net/ipv4/netfilter/iptable_nat.c
+++ b/net/ipv4/netfilter/iptable_nat.c
@@ -308,6 +308,7 @@ static void __net_exit iptable_nat_net_exit(struct net *net)
 		return;
 
 	ipt_unregister_table(net, net->ipv4.nat_table);
+	net->ipv4.nat_table = NULL;
 
 	net_ipt_module_clear(net, VE_IP_IPTABLE_NAT);
 }
diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c
index ae1198073c48..74afd759d91a 100644
--- a/net/ipv6/netfilter/ip6table_filter.c
+++ b/net/ipv6/netfilter/ip6table_filter.c
@@ -78,6 +78,7 @@ static void __net_exit ip6table_filter_net_exit(struct net *net)
 		return;
 
 	ip6t_unregister_table(net, net->ipv6.ip6table_filter);
+	net->ipv6.ip6table_filter = NULL;
 
 	net_ipt_module_clear(net, VE_IP_FILTER6);
 }
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
index 631936490897..4bc73b9410ec 100644
--- a/net/ipv6/netfilter/ip6table_mangle.c
+++ b/net/ipv6/netfilter/ip6table_mangle.c
@@ -117,6 +117,7 @@ static void __net_exit ip6table_mangle_net_exit(struct net *net)
 		return;
 
 	ip6t_unregister_table(net, net->ipv6.ip6table_mangle);
+	net->ipv6.ip6table_mangle = NULL;
 
 	net_ipt_module_clear(net, VE_IP_MANGLE6);
 }
-- 
2.1.4




More information about the Devel mailing list