[Devel] [PATCH RHEL7 COMMIT] ve/net: netfilter: clear xt_table on net exit
Konstantin Khorenko
khorenko at virtuozzo.com
Mon Jul 6 13:15:02 PDT 2015
The commit is pushed to "branch-rh7-3.10.0-123.1.2-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-123.1.2.vz7.5.24
------>
commit d8b82fbb9f8a3a75f95a5d8652c32bf2226d905a
Author: Vladimir Davydov <vdavydov at parallels.com>
Date: Tue Jul 7 00:15:02 2015 +0400
ve/net: netfilter: clear xt_table on net exit
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 4a9c627..10c1822 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 be368e2..a881a7d 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 f701df6..182c11a 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 ae11980..74afd75 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 6319364..4bc73b9 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);
}
More information about the Devel
mailing list