[Debian] Re: lenny updates (netfilter)
Kir Kolyshkin
kir at openvz.org
Mon Mar 9 19:00:39 EDT 2009
Kir Kolyshkin wrote:
> I am currently checking all the ~80 patches that are not in openvz
> lenny kernel. Looks like most are really needed. Let me suggest some
> in a few emails I will send as a reply to this one.
Here is a set of netfilter patches, quite a few. Some are very critical
(read security-related) since they fix various container/host isolation
issues, others are to prevent kernel oopses...
http://git.openvz.org/?p=linux-2.6.26-openvz;a=commitdiff;h=8562975430153848dd817a050133b53adda96910
nf: fix use after free
Fix use after free error, found by internal testing. Not an ABI breaker.
Attached as 0010*
http://git.openvz.org/?p=linux-2.6.26-openvz;a=commitdiff;h=fa7ac0b2423dc741cd7016565545abb8e36c4af4
nf: fix call to kmem_cache_destroy from VEs
Found by internal testing. Not an ABI breaker.
Attached as 0011*
http://git.openvz.org/?p=linux-2.6.26-openvz;a=commitdiff;h=17b09e1de42db77743ea9ae3dfd3a910ac57ee71
conntrack: prevent double allocate/free of protos
Found by internal testing. Not an ABI breaker.
Attached as 0022*
http://git.openvz.org/?p=linux-2.6.26-openvz;a=commitdiff;h=7d3f10fc5d8e268f7572cfdd2287c049bce3af7c
conntrack: prevent call register_pernet_subsys() from VE context
Found by internal audit. Not an ABI breaker.
Attached as 0023*
http://git.openvz.org/?p=linux-2.6.26-openvz;a=commitdiff;h=482dd20be37f61b2f94e6b3f3de1c1b9b4f9e6f1
conntrack: prevent call nf_register_hooks() from VE context
Found by internal audit. Not an ABI breaker.
Attached as 0024*
http://git.openvz.org/?p=linux-2.6.26-openvz;a=commitdiff;h=5fff3eb60f78acaadcae8562de5d3e6504f4d4f9
conntrack: adjust context during freeing
Found by internal audit. Not an ABI breaker.
Attached as 0029*
http://git.openvz.org/?p=linux-2.6.26-openvz;a=commitdiff;h=3cb8bc3781889ade74c02840b2eb8ddafb6d39c5
netfilter: NAT: assign nf_nat_seq_adjust_hook from VE0 context only
Found by internal audit. Not an ABI breaker.
Attached as 0033*
http://git.openvz.org/?p=linux-2.6.26-openvz;a=commitdiff;h=490910232ebe61f65e5e5c03b7286f11291b6092
netfilter: call nf_register_hooks from VE0 context only
Found by internal audit. Not an ABI breaker.
Attached as 0034*
http://git.openvz.org/?p=linux-2.6.26-openvz;a=commitdiff;h=1acba8533b788e95c52f827d06d9629d672c80fc
netfilter: Fix NULL dereference in nf_nat_setup_info.
OpenVZ Bug #1051 (http://bugzilla.openvz.org/1051). Might be an ABI breaker.
Attached as 0047*
http://git.openvz.org/?p=linux-2.6.26-openvz;a=commitdiff;h=b405aed753ac48a46e66cccfd0a37006fd11feb8
netfilter: Add check to the nat hooks
OpenVZ Bug #1051 (http://bugzilla.openvz.org/1051). Might be an ABI breaker.
Attached as 0048*
http://git.openvz.org/?p=linux-2.6.26-openvz;a=commitdiff;h=b5e1f74cee5bc2c45bdca53a7218fb8de89215dd
netlink: Fix oops in netlink conntrack module
OpenVZ bug #788 (http://bugzilla.openvz.org/788)
Attached as 0053*
http://git.openvz.org/?p=linux-2.6.26-openvz;a=commitdiff;h=09686c184a2cb815cbd5af500fe468311887d746
Free skb->nf_bridge in veth_xmit() and venet_xmit()
OpenVZ bug #1146 (http://bugzilla.openvz.org/1146)
Attached as 0066*
http://git.openvz.org/?p=linux-2.6.26-openvz;a=commitdiff;h=
http://git.openvz.org/?p=linux-2.6.26-openvz;a=commitdiff;h=
http://git.openvz.org/?p=linux-2.6.26-openvz;a=commitdiff;h=
-------------- next part --------------
>From 8562975430153848dd817a050133b53adda96910 Mon Sep 17 00:00:00 2001
From: Vitaliy Gusev <vgusev at openvz.org>
Date: Wed, 27 Aug 2008 19:36:28 +0400
Subject: [PATCH] nf: fix use after free
Fix use after free error: move freeing ve_nf_conntrack_l4proto_generic
to nf_ct_proto_generic_sysctl_cleanup().
Signed-off-by: Vitaliy Gusev <vgusev at openvz.org>
Signed-off-by: Pavel Emelyanov <xemul at openvz.org>
---
net/netfilter/nf_conntrack_proto.c | 4 ----
net/netfilter/nf_conntrack_proto_generic.c | 2 ++
2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c
index 49fc01f..67c53a7 100644
--- a/net/netfilter/nf_conntrack_proto.c
+++ b/net/netfilter/nf_conntrack_proto.c
@@ -358,8 +358,4 @@ void nf_conntrack_proto_fini(void)
/* free l3proto protocol tables */
for (i = 0; i < PF_MAX; i++)
kfree(ve_nf_ct_protos[i]);
-#ifdef CONFIG_VE_IPTABLES
- if (!ve_is_super(get_exec_env()))
- kfree(ve_nf_conntrack_l4proto_generic);
-#endif
}
diff --git a/net/netfilter/nf_conntrack_proto_generic.c b/net/netfilter/nf_conntrack_proto_generic.c
index e65f9a7..24b0e29 100644
--- a/net/netfilter/nf_conntrack_proto_generic.c
+++ b/net/netfilter/nf_conntrack_proto_generic.c
@@ -163,6 +163,8 @@ void nf_ct_proto_generic_sysctl_cleanup(void)
kfree(ve_nf_conntrack_l4proto_generic->ctl_compat_table);
#endif
kfree(ve_nf_conntrack_l4proto_generic->ctl_table);
+
+ kfree(ve_nf_conntrack_l4proto_generic);
}
}
EXPORT_SYMBOL(nf_ct_proto_generic_sysctl_cleanup);
--
1.6.0.6
-------------- next part --------------
>From fa7ac0b2423dc741cd7016565545abb8e36c4af4 Mon Sep 17 00:00:00 2001
From: Vitaliy Gusev <vgusev at openvz.org>
Date: Wed, 27 Aug 2008 19:37:09 +0400
Subject: [PATCH] nf: fix call to kmem_cache_destroy from VEs
Free nf_conntrack_cachep only for VE0 as it is a global variable
for all VEs.
Signed-off-by: Vitaliy Gusev <vgusev at openvz.org>
Signed-off-by: Pavel Emelyanov <xemul at openvz.org>
---
net/netfilter/nf_conntrack_core.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index e811c0b..b4050b0 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -1041,7 +1041,8 @@ void nf_conntrack_cleanup(void)
rcu_assign_pointer(nf_ct_destroy, NULL);
- kmem_cache_destroy(nf_conntrack_cachep);
+ if (ve_is_super(ve))
+ kmem_cache_destroy(nf_conntrack_cachep);
skip_ct_cache:
nf_conntrack_helper_fini();
nf_conntrack_expect_fini();
--
1.6.0.6
-------------- next part --------------
>From 17b09e1de42db77743ea9ae3dfd3a910ac57ee71 Mon Sep 17 00:00:00 2001
From: Vitaliy Gusev <vgusev at openvz.org>
Date: Mon, 22 Sep 2008 13:53:27 +0400
Subject: [PATCH] conntrack: prevent double allocate/free of protos
Call nf_ct_proto_tcp_sysctl_xxx()/nf_ct_proto_tcp_sysctl_cleanup() from
nf_conntrack_init_ve()/nf_conntrack_cleanup_ve() to prevent to be called twice
from functions:
- init_nf_ct_l3proto_ipv4()
- init_nf_ct_l3proto_ipv6()
- fini_nf_ct_l3proto_ipv4()
- fini_nf_ct_l3proto_ipv6()
Signed-off-by: Vitaliy Gusev <vgusev at openvz.org>
Signed-off-by: Pavel Emelyanov <xemul at openvz.org>
---
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 12 ------------
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 12 ------------
net/netfilter/nf_conntrack_standalone.c | 13 +++++++++++++
3 files changed, 13 insertions(+), 24 deletions(-)
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index dca8da7..b4bb436 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -512,12 +512,6 @@ int init_nf_ct_l3proto_ipv4(void)
ret = nf_ct_proto_ipv4_sysctl_init();
if (ret < 0)
goto no_mem_ipv4;
- ret = nf_ct_proto_tcp_sysctl_init();
- if (ret < 0)
- goto no_mem_tcp;
- ret = nf_ct_proto_udp_sysctl_init();
- if (ret < 0)
- goto no_mem_udp;
ret = nf_ct_proto_icmp_sysctl_init();
if (ret < 0)
goto no_mem_icmp;
@@ -575,10 +569,6 @@ unreg_tcp:
cleanup_sys:
#ifdef CONFIG_VE_IPTABLES
no_mem_icmp:
- nf_ct_proto_udp_sysctl_cleanup();
-no_mem_udp:
- nf_ct_proto_tcp_sysctl_cleanup();
-no_mem_tcp:
nf_ct_proto_ipv4_sysctl_cleanup();
no_mem_ipv4:
nf_ct_proto_ipv4_fini();
@@ -606,8 +596,6 @@ void fini_nf_ct_l3proto_ipv4(void)
#ifdef CONFIG_VE_IPTABLES
nf_ct_proto_icmp_sysctl_cleanup();
- nf_ct_proto_udp_sysctl_cleanup();
- nf_ct_proto_tcp_sysctl_cleanup();
nf_ct_proto_ipv4_sysctl_cleanup();
nf_ct_proto_ipv4_fini();
if (!ve_is_super(get_exec_env()))
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index e6f8f7d..cbfe1a2 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -368,12 +368,6 @@ int init_nf_ct_l3proto_ipv6(void)
if (!ve_is_super(get_exec_env()))
__module_get(THIS_MODULE);
- ret = nf_ct_proto_tcp_sysctl_init();
- if (ret < 0)
- goto no_mem_tcp;
- ret = nf_ct_proto_udp_sysctl_init();
- if (ret < 0)
- goto no_mem_udp;
ret = nf_ct_proto_icmpv6_sysctl_init();
if (ret < 0)
goto no_mem_icmp;
@@ -430,10 +424,6 @@ cleanup_frag6:
cleanup_sys:
#ifdef CONFIG_VE_IPTABLES
no_mem_icmp:
- nf_ct_proto_udp_sysctl_cleanup();
-no_mem_udp:
- nf_ct_proto_tcp_sysctl_cleanup();
-no_mem_tcp:
if (!ve_is_super(get_exec_env()))
module_put(THIS_MODULE);
#endif /* CONFIG_VE_IPTABLES */
@@ -452,8 +442,6 @@ void fini_nf_ct_l3proto_ipv6(void)
#ifdef CONFIG_VE_IPTABLES
nf_ct_proto_icmpv6_sysctl_cleanup();
- nf_ct_proto_udp_sysctl_cleanup();
- nf_ct_proto_tcp_sysctl_cleanup();
if (!ve_is_super(get_exec_env()))
module_put(THIS_MODULE);
#endif /* CONFIG_VE_IPTABLES */
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
index c4d8ef2..0439df6 100644
--- a/net/netfilter/nf_conntrack_standalone.c
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -510,8 +510,19 @@ static int nf_conntrack_init_ve(void)
ret = nf_conntrack_standalone_init_sysctl();
if (ret < 0)
goto out_sysctl;
+ ret = nf_ct_proto_tcp_sysctl_init();
+ if (ret < 0)
+ goto out_tcp_sysctl;
+ ret = nf_ct_proto_udp_sysctl_init();
+ if (ret < 0)
+ goto out_udp_sysctl;
+
return 0;
+out_udp_sysctl:
+ nf_ct_proto_tcp_sysctl_cleanup();
+out_tcp_sysctl:
+ nf_conntrack_standalone_fini_sysctl();
out_sysctl:
nf_conntrack_standalone_fini_proc();
out_proc:
@@ -522,6 +533,8 @@ out:
static void nf_conntrack_cleanup_ve(void)
{
+ nf_ct_proto_udp_sysctl_cleanup();
+ nf_ct_proto_tcp_sysctl_cleanup();
nf_conntrack_standalone_fini_sysctl();
nf_conntrack_standalone_fini_proc();
nf_conntrack_cleanup();
--
1.6.0.6
-------------- next part --------------
>From 7d3f10fc5d8e268f7572cfdd2287c049bce3af7c Mon Sep 17 00:00:00 2001
From: Vitaliy Gusev <vgusev at openvz.org>
Date: Mon, 22 Sep 2008 14:04:45 +0400
Subject: [PATCH] conntrack: prevent call register_pernet_subsys() from VE context
nf_ct_frag6_init calls register_pernet_subsys. So move nf_ct_frag6_init to
nf_conntrack_l3proto_ipv6_init() to prevent call from VE context.
Signed-off-by: Vitaliy Gusev <vgusev at openvz.org>
Signed-off-by: Pavel Emelyanov <xemul at openvz.org>
---
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 24 +++++++++++++-----------
1 files changed, 13 insertions(+), 11 deletions(-)
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index cbfe1a2..b97914e 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -372,16 +372,10 @@ int init_nf_ct_l3proto_ipv6(void)
if (ret < 0)
goto no_mem_icmp;
#endif /* CONFIG_VE_IPTABLES */
- ret = nf_ct_frag6_init();
- if (ret < 0) {
- printk("nf_conntrack_ipv6: can't initialize frag6.\n");
- goto cleanup_sys;
- }
-
ret = nf_conntrack_l4proto_register(ve_nf_conntrack_l4proto_tcp6);
if (ret < 0) {
printk("nf_conntrack_ipv6: can't register tcp.\n");
- goto cleanup_frag6;
+ goto cleanup_sys;
}
ret = nf_conntrack_l4proto_register(ve_nf_conntrack_l4proto_udp6);
@@ -419,8 +413,6 @@ unreg_udp:
nf_conntrack_l4proto_unregister(ve_nf_conntrack_l4proto_udp6);
unreg_tcp:
nf_conntrack_l4proto_unregister(ve_nf_conntrack_l4proto_tcp6);
-cleanup_frag6:
- nf_ct_frag6_cleanup();
cleanup_sys:
#ifdef CONFIG_VE_IPTABLES
no_mem_icmp:
@@ -438,7 +430,6 @@ void fini_nf_ct_l3proto_ipv6(void)
nf_conntrack_l4proto_unregister(ve_nf_conntrack_l4proto_icmpv6);
nf_conntrack_l4proto_unregister(ve_nf_conntrack_l4proto_udp6);
nf_conntrack_l4proto_unregister(ve_nf_conntrack_l4proto_tcp6);
- nf_ct_frag6_cleanup();
#ifdef CONFIG_VE_IPTABLES
nf_ct_proto_icmpv6_sysctl_cleanup();
@@ -454,15 +445,25 @@ static int __init nf_conntrack_l3proto_ipv6_init(void)
need_conntrack();
+ ret = nf_ct_frag6_init();
+ if (ret < 0) {
+ printk("nf_conntrack_ipv6: can't initialize frag6.\n");
+ return ret;
+ }
+
ret = init_nf_ct_l3proto_ipv6();
if (ret < 0) {
printk(KERN_ERR "Unable to initialize netfilter protocols\n");
- return ret;
+ goto cleanup_frag6;
}
KSYMRESOLVE(init_nf_ct_l3proto_ipv6);
KSYMRESOLVE(fini_nf_ct_l3proto_ipv6);
KSYMMODRESOLVE(nf_conntrack_ipv6);
return 0;
+
+cleanup_frag6:
+ nf_ct_frag6_cleanup();
+ return ret;
}
static void __exit nf_conntrack_l3proto_ipv6_fini(void)
@@ -472,6 +473,7 @@ static void __exit nf_conntrack_l3proto_ipv6_fini(void)
KSYMUNRESOLVE(init_nf_ct_l3proto_ipv6);
KSYMUNRESOLVE(fini_nf_ct_l3proto_ipv6);
fini_nf_ct_l3proto_ipv6();
+ nf_ct_frag6_cleanup();
}
module_init(nf_conntrack_l3proto_ipv6_init);
--
1.6.0.6
-------------- next part --------------
>From 482dd20be37f61b2f94e6b3f3de1c1b9b4f9e6f1 Mon Sep 17 00:00:00 2001
From: Vitaliy Gusev <vgusev at openvz.org>
Date: Mon, 22 Sep 2008 14:05:54 +0400
Subject: [PATCH] conntrack: prevent call nf_register_hooks() from VE context
Move nf_register_hooks from init_nf_ct_l3proto_ipv6() to
nf_conntrack_l3proto_ipv6_init() to prevent call from VE
context.
Signed-off-by: Vitaliy Gusev <vgusev at openvz.org>
Signed-off-by: Pavel Emelyanov <xemul at openvz.org>
---
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 19 +++++++++----------
1 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index b97914e..71b15ab 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -396,17 +396,8 @@ int init_nf_ct_l3proto_ipv6(void)
goto unreg_icmpv6;
}
- ret = nf_register_hooks(ipv6_conntrack_ops,
- ARRAY_SIZE(ipv6_conntrack_ops));
- if (ret < 0) {
- printk("nf_conntrack_ipv6: can't register pre-routing defrag "
- "hook.\n");
- goto unreg_ipv6;
- }
return 0;
-unreg_ipv6:
- nf_conntrack_l3proto_unregister(ve_nf_conntrack_l3proto_ipv6);
unreg_icmpv6:
nf_conntrack_l4proto_unregister(ve_nf_conntrack_l4proto_icmpv6);
unreg_udp:
@@ -425,7 +416,6 @@ EXPORT_SYMBOL(init_nf_ct_l3proto_ipv6);
void fini_nf_ct_l3proto_ipv6(void)
{
- nf_unregister_hooks(ipv6_conntrack_ops, ARRAY_SIZE(ipv6_conntrack_ops));
nf_conntrack_l3proto_unregister(ve_nf_conntrack_l3proto_ipv6);
nf_conntrack_l4proto_unregister(ve_nf_conntrack_l4proto_icmpv6);
nf_conntrack_l4proto_unregister(ve_nf_conntrack_l4proto_udp6);
@@ -456,6 +446,14 @@ static int __init nf_conntrack_l3proto_ipv6_init(void)
printk(KERN_ERR "Unable to initialize netfilter protocols\n");
goto cleanup_frag6;
}
+
+ ret = nf_register_hooks(ipv6_conntrack_ops,
+ ARRAY_SIZE(ipv6_conntrack_ops));
+ if (ret < 0) {
+ printk(KERN_ERR "nf_conntrack_ipv6: can't register pre-routing "
+ "defrag hook.\n");
+ return ret;
+ }
KSYMRESOLVE(init_nf_ct_l3proto_ipv6);
KSYMRESOLVE(fini_nf_ct_l3proto_ipv6);
KSYMMODRESOLVE(nf_conntrack_ipv6);
@@ -472,6 +470,7 @@ static void __exit nf_conntrack_l3proto_ipv6_fini(void)
KSYMMODUNRESOLVE(nf_conntrack_ipv6);
KSYMUNRESOLVE(init_nf_ct_l3proto_ipv6);
KSYMUNRESOLVE(fini_nf_ct_l3proto_ipv6);
+ nf_unregister_hooks(ipv6_conntrack_ops, ARRAY_SIZE(ipv6_conntrack_ops));
fini_nf_ct_l3proto_ipv6();
nf_ct_frag6_cleanup();
}
--
1.6.0.6
-------------- next part --------------
>From 5fff3eb60f78acaadcae8562de5d3e6504f4d4f9 Mon Sep 17 00:00:00 2001
From: Vitaliy Gusev <vgusev at openvz.org>
Date: Fri, 26 Sep 2008 19:06:41 +0400
Subject: [PATCH] conntrack: adjust context during freeing
rcu callback are called from VE0 context, so we must specify
context when accessing to virtualized variables (ve_nf_conntrack_count)
Signed-off-by: Vitaliy Gusev <vgusev at openvz.org>
Signed-off-by: Pavel Emelyanov <xemul at openvz.org>
---
net/netfilter/nf_conntrack_core.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index b4050b0..b38699c 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -539,10 +539,16 @@ EXPORT_SYMBOL_GPL(nf_conntrack_alloc);
static void nf_conntrack_free_rcu(struct rcu_head *head)
{
struct nf_conn *ct = container_of(head, struct nf_conn, rcu);
+#ifdef CONFIG_VE_IPTABLES
+ struct ve_struct *ve = set_exec_env(ct->ct_owner_env);
+#endif
nf_ct_ext_free(ct);
kmem_cache_free(nf_conntrack_cachep, ct);
atomic_dec(&ve_nf_conntrack_count);
+#ifdef CONFIG_VE_IPTABLES
+ set_exec_env(ve);
+#endif
}
void nf_conntrack_free(struct nf_conn *ct)
--
1.6.0.6
-------------- next part --------------
>From 3cb8bc3781889ade74c02840b2eb8ddafb6d39c5 Mon Sep 17 00:00:00 2001
From: Vitaliy Gusev <vgusev at openvz.org>
Date: Wed, 1 Oct 2008 12:10:51 +0400
Subject: [PATCH] netfilter: NAT: assign nf_nat_seq_adjust_hook from VE0 context only
Signed-off-by: Vitaliy Gusev <vgusev at openvz.org>
Signed-off-by: Pavel Emelyanov <xemul at openvz.org>
---
net/ipv4/netfilter/nf_nat_core.c | 9 +++++----
1 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c
index f7f832b..ac9319d 100644
--- a/net/ipv4/netfilter/nf_nat_core.c
+++ b/net/ipv4/netfilter/nf_nat_core.c
@@ -645,12 +645,12 @@ int nf_nat_init(void)
if (ve_is_super(get_exec_env())) {
/* Initialize fake conntrack so that NAT will skip it */
nf_conntrack_untracked.status |= IPS_NAT_DONE_MASK;
+ BUG_ON(nf_nat_seq_adjust_hook != NULL);
+ rcu_assign_pointer(nf_nat_seq_adjust_hook, nf_nat_seq_adjust);
}
ve_nf_nat_l3proto = nf_ct_l3proto_find_get((u_int16_t)AF_INET);
- BUG_ON(nf_nat_seq_adjust_hook != NULL);
- rcu_assign_pointer(nf_nat_seq_adjust_hook, nf_nat_seq_adjust);
return 0;
#ifdef CONFIG_VE_IPTABLES
@@ -683,9 +683,10 @@ void nf_nat_cleanup(void)
#ifdef CONFIG_VE_IPTABLES
kfree(ve_nf_nat_protos);
#endif
- if (ve_is_super(get_exec_env()))
+ if (ve_is_super(get_exec_env())) {
nf_ct_extend_unregister(&nat_extend);
- rcu_assign_pointer(nf_nat_seq_adjust_hook, NULL);
+ rcu_assign_pointer(nf_nat_seq_adjust_hook, NULL);
+ }
synchronize_net();
}
--
1.6.0.6
-------------- next part --------------
>From 490910232ebe61f65e5e5c03b7286f11291b6092 Mon Sep 17 00:00:00 2001
From: Vitaliy Gusev <vgusev at openvz.org>
Date: Wed, 1 Oct 2008 12:12:36 +0400
Subject: [PATCH] netfilter: call nf_register_hooks from VE0 context only
Signed-off-by: Vitaliy Gusev <vgusev at openvz.org>
Signed-off-by: Pavel Emelyanov <xemul at openvz.org>
---
net/ipv4/netfilter/nf_nat_standalone.c | 14 +++++++++-----
1 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/net/ipv4/netfilter/nf_nat_standalone.c b/net/ipv4/netfilter/nf_nat_standalone.c
index 9aec464..72f45db 100644
--- a/net/ipv4/netfilter/nf_nat_standalone.c
+++ b/net/ipv4/netfilter/nf_nat_standalone.c
@@ -295,10 +295,13 @@ int init_nftable_nat(void)
printk("nf_nat_init: can't setup rules.\n");
goto out_modput;
}
- ret = nf_register_hooks(nf_nat_ops, ARRAY_SIZE(nf_nat_ops));
- if (ret < 0) {
- printk("nf_nat_init: can't register hooks.\n");
- goto cleanup_rule_init;
+
+ if (ve_is_super(get_exec_env())) {
+ ret = nf_register_hooks(nf_nat_ops, ARRAY_SIZE(nf_nat_ops));
+ if (ret < 0) {
+ printk("nf_nat_init: can't register hooks.\n");
+ goto cleanup_rule_init;
+ }
}
return 0;
@@ -312,7 +315,8 @@ out_modput:
void fini_nftable_nat(void)
{
- nf_unregister_hooks(nf_nat_ops, ARRAY_SIZE(nf_nat_ops));
+ if (ve_is_super(get_exec_env()))
+ nf_unregister_hooks(nf_nat_ops, ARRAY_SIZE(nf_nat_ops));
nf_nat_rule_cleanup();
if (!ve_is_super(get_exec_env()))
module_put(THIS_MODULE);
--
1.6.0.6
-------------- next part --------------
>From 1acba8533b788e95c52f827d06d9629d672c80fc Mon Sep 17 00:00:00 2001
From: Vitaliy Gusev <vgusev at openvz.org>
Date: Wed, 19 Nov 2008 20:50:25 +0300
Subject: [PATCH] netfilter: Fix NULL dereference in nf_nat_setup_info
If conntrack is allowed in VE but iptable_nat is not allowed and loaded
then Oops occurs:
BUG: unable to handle kernel NULL pointer dereference at 0000000000000008
IP: [<ffffffffa0123df6>] :nf_nat:nf_nat_setup_info+0x343/0x489
Oops: 0000 [1] SMP DEBUG_PAGEALLOC
CPU: 1
[<ffffffff8028c277>] ? poison_obj+0x27/0x32
[<ffffffffa012a084>] :iptable_nat:alloc_null_binding+0x44/0x46
[<ffffffffa012a1f7>] :iptable_nat:nf_nat_rule_find+0x62/0x6b
[<ffffffffa012a4e5>] :iptable_nat:nf_nat_fn+0x11d/0x149
[<ffffffffa012a551>] :iptable_nat:nf_nat_local_fn+0x40/0xbf
[<ffffffff80476ad5>] nf_iterate+0x43/0x80
[<ffffffff8047efa0>] ? dst_output+0x0/0xd
[<ffffffff80476de9>] nf_hook_slow+0x5e/0xc1
[<ffffffff8047efa0>] ? dst_output+0x0/0xd
[<ffffffff80480314>] __ip_local_out+0x9f/0xa1
[<ffffffff80480327>] ip_local_out+0x11/0x24
[<ffffffff80480600>] ip_push_pending_frames+0x2c6/0x345
[<ffffffff8049b668>] raw_sendmsg+0x6a9/0x739
[<ffffffff804a3750>] inet_sendmsg+0x46/0x53
[<ffffffff80455ffa>] sock_sendmsg+0xdf/0xf8
RIP [<ffffffffa0123df6>] :nf_nat:nf_nat_setup_info+0x343/0x489
So create/use iptable_nat to check was nat table initialized in VE or not.
Bug #1051
http://bugzilla.openvz.org/show_bug.cgi?id=1051
Signed-off-by: Vitaliy Gusev <vgusev at openvz.org>
Signed-off-by: Pavel Emelyanov <xemul at openvz.org>
---
include/linux/netfilter.h | 15 +++++++++++++++
include/linux/ve.h | 1 -
include/net/netns/ipv4.h | 1 +
net/ipv4/netfilter/nf_nat_rule.c | 25 +++++++++++--------------
4 files changed, 27 insertions(+), 15 deletions(-)
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index 8d41ea4..63c92ad 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -394,6 +394,21 @@ static inline struct net *nf_post_routing_net(const struct net_device *in,
#endif
}
+static inline struct net *nf_net(unsigned hook,
+ const struct net_device *in,
+ const struct net_device *out)
+{
+ switch (hook) {
+ case NF_INET_PRE_ROUTING:
+ case NF_INET_LOCAL_IN:
+ case NF_INET_FORWARD:
+ return dev_net(in);
+ case NF_INET_POST_ROUTING:
+ case NF_INET_LOCAL_OUT:
+ return dev_net(out);
+ }
+}
+
#ifdef CONFIG_VE_IPTABLES
#include <linux/vziptable_defs.h>
diff --git a/include/linux/ve.h b/include/linux/ve.h
index 2180c1f..f55f43e 100644
--- a/include/linux/ve.h
+++ b/include/linux/ve.h
@@ -56,7 +56,6 @@ struct ve_nf_conntrack {
struct hlist_head *_bysource;
struct nf_nat_protocol **_nf_nat_protos;
int _nf_nat_vmalloced;
- struct xt_table *_nf_nat_table;
struct nf_conntrack_l3proto *_nf_nat_l3proto;
atomic_t _nf_conntrack_count;
int _nf_conntrack_max;
diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
index d8588d5..31add33 100644
--- a/include/net/netns/ipv4.h
+++ b/include/net/netns/ipv4.h
@@ -34,6 +34,7 @@ struct netns_ipv4 {
struct netns_frags frags;
#ifdef CONFIG_NETFILTER
struct xt_table *iptable_filter;
+ struct xt_table *iptable_nat;
struct xt_table *iptable_mangle;
struct xt_table *iptable_raw;
struct xt_table *arptable_filter;
diff --git a/net/ipv4/netfilter/nf_nat_rule.c b/net/ipv4/netfilter/nf_nat_rule.c
index f301178..505c1cd 100644
--- a/net/ipv4/netfilter/nf_nat_rule.c
+++ b/net/ipv4/netfilter/nf_nat_rule.c
@@ -66,12 +66,6 @@ static struct xt_table __nat_table = {
.me = THIS_MODULE,
.af = AF_INET,
};
-#ifdef CONFIG_VE_IPTABLES
-#define nat_table \
- (get_exec_env()->_nf_conntrack->_nf_nat_table)
-#else
-static struct xt_table *nat_table;
-#endif
/* Source NAT */
static unsigned int ipt_snat_target(struct sk_buff *skb,
@@ -202,7 +196,8 @@ int nf_nat_rule_find(struct sk_buff *skb,
{
int ret;
- ret = ipt_do_table(skb, hooknum, in, out, nat_table);
+ ret = ipt_do_table(skb, hooknum, in, out,
+ nf_net(hooknum, in, out)->ipv4.iptable_nat);
if (ret == NF_ACCEPT) {
if (!nf_nat_initialized(ct, HOOK2MANIP(hooknum)))
@@ -237,10 +232,10 @@ int nf_nat_rule_init(void)
int ret;
struct net *net = get_exec_env()->ve_netns;
- nat_table = ipt_register_table(net, &__nat_table,
+ net->ipv4.iptable_nat = ipt_register_table(net, &__nat_table,
&nat_initial_table.repl);
- if (IS_ERR(nat_table))
- return PTR_ERR(nat_table);
+ if (IS_ERR(net->ipv4.iptable_nat))
+ return PTR_ERR(net->ipv4.iptable_nat);
ret = 0;
if (!ve_is_super(get_exec_env()))
@@ -260,20 +255,22 @@ done:
unregister_snat:
xt_unregister_target(&ipt_snat_reg);
unregister_table:
- ipt_unregister_table(nat_table);
- nat_table = NULL;
+ ipt_unregister_table(net->ipv4.iptable_nat);
+ net->ipv4.iptable_nat = NULL;
return ret;
}
void nf_nat_rule_cleanup(void)
{
+ struct net *net = get_exec_env()->ve_netns;
+
if (!ve_is_super(get_exec_env()))
goto skip;
xt_unregister_target(&ipt_dnat_reg);
xt_unregister_target(&ipt_snat_reg);
skip:
- ipt_unregister_table(nat_table);
- nat_table = NULL;
+ ipt_unregister_table(net->ipv4.iptable_nat);
+ net->ipv4.iptable_nat = NULL;
}
--
1.6.0.6
-------------- next part --------------
>From b405aed753ac48a46e66cccfd0a37006fd11feb8 Mon Sep 17 00:00:00 2001
From: Vitaliy Gusev <vgusev at openvz.org>
Date: Wed, 19 Nov 2008 20:39:51 +0300
Subject: [PATCH] netfilter: Add check to the nat hooks
Pass skb if VE wasn't granded to have nat table.
Related to bug #1051
http://bugzilla.openvz.org/show_bug.cgi?id=1051
Signed-off-by: Vitaliy Gusev <vgusev at openvz.org>
Signed-off-by: Pavel Emelyanov <xemul at openvz.org>
---
net/ipv4/netfilter/nf_nat_standalone.c | 24 +++++++++++++++++++++++-
1 files changed, 23 insertions(+), 1 deletions(-)
diff --git a/net/ipv4/netfilter/nf_nat_standalone.c b/net/ipv4/netfilter/nf_nat_standalone.c
index 72f45db..17d7527 100644
--- a/net/ipv4/netfilter/nf_nat_standalone.c
+++ b/net/ipv4/netfilter/nf_nat_standalone.c
@@ -157,6 +157,19 @@ nf_nat_fn(unsigned int hooknum,
}
static unsigned int
+nf_nat_local_in(unsigned int hooknum,
+ struct sk_buff *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+{
+ if (!dev_net(in)->ipv4.iptable_nat)
+ return NF_ACCEPT;
+
+ return nf_nat_fn(hooknum, skb, in, out, okfn);
+}
+
+static unsigned int
nf_nat_in(unsigned int hooknum,
struct sk_buff *skb,
const struct net_device *in,
@@ -166,6 +179,9 @@ nf_nat_in(unsigned int hooknum,
unsigned int ret;
__be32 daddr = ip_hdr(skb)->daddr;
+ if (!dev_net(in)->ipv4.iptable_nat)
+ return NF_ACCEPT;
+
ret = nf_nat_fn(hooknum, skb, in, out, okfn);
if (ret != NF_DROP && ret != NF_STOLEN &&
daddr != ip_hdr(skb)->daddr) {
@@ -188,6 +204,9 @@ nf_nat_out(unsigned int hooknum,
#endif
unsigned int ret;
+ if (!dev_net(out)->ipv4.iptable_nat)
+ return NF_ACCEPT;
+
/* root is playing with raw sockets. */
if (skb->len < sizeof(struct iphdr) ||
ip_hdrlen(skb) < sizeof(struct iphdr))
@@ -221,6 +240,9 @@ nf_nat_local_fn(unsigned int hooknum,
enum ip_conntrack_info ctinfo;
unsigned int ret;
+ if (!dev_net(out)->ipv4.iptable_nat)
+ return NF_ACCEPT;
+
/* root is playing with raw sockets. */
if (skb->len < sizeof(struct iphdr) ||
ip_hdrlen(skb) < sizeof(struct iphdr))
@@ -275,7 +297,7 @@ static struct nf_hook_ops nf_nat_ops[] __read_mostly = {
},
/* After packet filtering, change source */
{
- .hook = nf_nat_fn,
+ .hook = nf_nat_local_in,
.owner = THIS_MODULE,
.pf = PF_INET,
.hooknum = NF_INET_LOCAL_IN,
--
1.6.0.6
-------------- next part --------------
>From b5e1f74cee5bc2c45bdca53a7218fb8de89215dd Mon Sep 17 00:00:00 2001
From: Pavel Emelyanov <xemul at openvz.org>
Date: Fri, 28 Nov 2008 12:46:11 +0300
Subject: [PATCH] netlink: Fix oops in netlink conntrack module
If we load conntrack modules after ve start one pointer on ve_struct
is NULL and accessing it causes an oops.
This is handled in most of the places, but the netlink interface.
Fix this one as well.
http://bugzilla.openvz.org/show_bug.cgi?id=788
Signed-off-by: Pavel Emelyanov <xemul at openvz.org>
---
include/net/netfilter/nf_conntrack_l4proto.h | 3 +++
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 3 +++
net/netfilter/nf_conntrack_netlink.c | 18 ++++++++++++++++++
3 files changed, 24 insertions(+), 0 deletions(-)
diff --git a/include/net/netfilter/nf_conntrack_l4proto.h b/include/net/netfilter/nf_conntrack_l4proto.h
index 43ecaf7..43ca754 100644
--- a/include/net/netfilter/nf_conntrack_l4proto.h
+++ b/include/net/netfilter/nf_conntrack_l4proto.h
@@ -126,6 +126,9 @@ extern unsigned int nf_ct_log_invalid;
#ifdef CONFIG_VE_IPTABLES
#include <linux/sched.h>
#define ve_nf_ct4 (get_exec_env()->_nf_conntrack)
+#define ve_nf_ct_initialized() (get_exec_env()->_nf_conntrack != NULL)
+#else
+#define ve_nf_ct_initialized() 1
#endif
#if defined(CONFIG_VE_IPTABLES) && defined(CONFIG_SYSCTL)
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index b4bb436..c3c22dd 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -304,6 +304,9 @@ getorigdst(struct sock *sk, int optval, void __user *user, int *len)
const struct nf_conntrack_tuple_hash *h;
struct nf_conntrack_tuple tuple;
+ if (!ve_nf_ct_initialized())
+ return -ENOPROTOOPT;
+
memset(&tuple, 0, sizeof(tuple));
tuple.src.u3.ip = inet->rcv_saddr;
tuple.src.u.tcp.port = inet->sport;
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index e9bee13..f15c4ba 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -790,6 +790,9 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
u_int8_t u3 = nfmsg->nfgen_family;
int err = 0;
+ if (!ve_nf_ct_initialized())
+ return -ENOPROTOOPT;
+
if (cda[CTA_TUPLE_ORIG])
err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG, u3);
else if (cda[CTA_TUPLE_REPLY])
@@ -836,6 +839,9 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
u_int8_t u3 = nfmsg->nfgen_family;
int err = 0;
+ if (!ve_nf_ct_initialized())
+ return -ENOPROTOOPT;
+
if (nlh->nlmsg_flags & NLM_F_DUMP) {
#ifndef CONFIG_NF_CT_ACCT
if (NFNL_MSG_TYPE(nlh->nlmsg_type) == IPCTNL_MSG_CT_GET_CTRZERO)
@@ -1203,6 +1209,9 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
u_int8_t u3 = nfmsg->nfgen_family;
int err = 0;
+ if (!ve_nf_ct_initialized())
+ return -ENOPROTOOPT;
+
if (cda[CTA_TUPLE_ORIG]) {
err = ctnetlink_parse_tuple(cda, &otuple, CTA_TUPLE_ORIG, u3);
if (err < 0)
@@ -1527,6 +1536,9 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
u_int8_t u3 = nfmsg->nfgen_family;
int err = 0;
+ if (!ve_nf_ct_initialized())
+ return -ENOPROTOOPT;
+
if (nlh->nlmsg_flags & NLM_F_DUMP) {
return netlink_dump_start(ctnl, skb, nlh,
ctnetlink_exp_dump_table,
@@ -1588,6 +1600,9 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
unsigned int i;
int err;
+ if (!ve_nf_ct_initialized())
+ return -ENOPROTOOPT;
+
if (cda[CTA_EXPECT_TUPLE]) {
/* delete a single expect by tuple */
err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE, u3);
@@ -1726,6 +1741,9 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
u_int8_t u3 = nfmsg->nfgen_family;
int err = 0;
+ if (!ve_nf_ct_initialized())
+ return -ENOPROTOOPT;
+
if (!cda[CTA_EXPECT_TUPLE]
|| !cda[CTA_EXPECT_MASK]
|| !cda[CTA_EXPECT_MASTER])
--
1.6.0.6
-------------- next part --------------
>From 09686c184a2cb815cbd5af500fe468311887d746 Mon Sep 17 00:00:00 2001
From: Vitaliy Gusev <vgusev at openvz.org>
Date: Mon, 26 Jan 2009 15:48:02 +0300
Subject: [PATCH] Free skb->nf_bridge in veth_xmit() and venet_xmit()
We free skb->nfct in veth_xmit, but also have to free skb->nf_bridge.
Note: Why it works in 2.6.24-ovz but doesn't work in 2.6.26-ovz ?
1. It issue is only if BRIDGE_NETFILTER=y
2. nf_hook_register() has effect to all VEs in 2.6.26-ovz
(in 2.6.24-ovz doesn't).
Thus bridge hook ip_sabotage_in is not called for 2.6.24-ovz, but
is called for 2.6.26-ovz.
http://bugzilla.openvz.org/show_bug.cgi?id=1146
Signed-off-by: Vitaliy Gusev <vgusev at openvz.org>
Signed-off-by: Pavel Emelyanov <xemul at openvz.org>
---
drivers/net/venet_core.c | 5 +----
drivers/net/vzethdev.c | 5 +----
2 files changed, 2 insertions(+), 8 deletions(-)
diff --git a/drivers/net/venet_core.c b/drivers/net/venet_core.c
index 6b21630..8770255 100644
--- a/drivers/net/venet_core.c
+++ b/drivers/net/venet_core.c
@@ -272,10 +272,7 @@ static int venet_xmit(struct sk_buff *skb, struct net_device *dev)
dst_release(skb->dst);
skb->dst = NULL;
-#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
- nf_conntrack_put(skb->nfct);
- skb->nfct = NULL;
-#endif
+ nf_reset(skb);
length = skb->len;
netif_rx(skb);
diff --git a/drivers/net/vzethdev.c b/drivers/net/vzethdev.c
index 1414618..dd2b693 100644
--- a/drivers/net/vzethdev.c
+++ b/drivers/net/vzethdev.c
@@ -311,10 +311,7 @@ out:
dst_release(skb->dst);
skb->dst = NULL;
-#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
- nf_conntrack_put(skb->nfct);
- skb->nfct = NULL;
-#endif
+ nf_reset(skb);
length = skb->len;
netif_rx(skb);
--
1.6.0.6
More information about the Debian
mailing list