aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJulian Anastasov <ja@ssi.bg>2012-04-16 00:43:15 -0400
committerLuis Henriques <luis.henriques@canonical.com>2012-05-01 06:00:23 -0400
commit7a44ec092d399db125c10c2f18b0f90157840819 (patch)
tree197bf5d2c00b14c990bcc12197096866e000ecce /net
parent81a5e5595a996d6e304e342411f34adb95213d2e (diff)
netns: do not leak net_generic data on failed init
BugLink: http://bugs.launchpad.net/bugs/990544 [ Upstream commit b922934d017f1cc831b017913ed7d1a56c558b43 ] ops_init should free the net_generic data on init failure and __register_pernet_operations should not call ops_free when NET_NS is not enabled. Signed-off-by: Julian Anastasov <ja@ssi.bg> Reviewed-by: "Eric W. Biederman" <ebiederm@xmission.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
Diffstat (limited to 'net')
-rw-r--r--net/core/net_namespace.c33
1 files changed, 18 insertions, 15 deletions
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index 0b0211d7fc3..2772ed11bec 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -82,21 +82,29 @@ assign:
82 82
83static int ops_init(const struct pernet_operations *ops, struct net *net) 83static int ops_init(const struct pernet_operations *ops, struct net *net)
84{ 84{
85 int err; 85 int err = -ENOMEM;
86 void *data = NULL;
87
86 if (ops->id && ops->size) { 88 if (ops->id && ops->size) {
87 void *data = kzalloc(ops->size, GFP_KERNEL); 89 data = kzalloc(ops->size, GFP_KERNEL);
88 if (!data) 90 if (!data)
89 return -ENOMEM; 91 goto out;
90 92
91 err = net_assign_generic(net, *ops->id, data); 93 err = net_assign_generic(net, *ops->id, data);
92 if (err) { 94 if (err)
93 kfree(data); 95 goto cleanup;
94 return err;
95 }
96 } 96 }
97 err = 0;
97 if (ops->init) 98 if (ops->init)
98 return ops->init(net); 99 err = ops->init(net);
99 return 0; 100 if (!err)
101 return 0;
102
103cleanup:
104 kfree(data);
105
106out:
107 return err;
100} 108}
101 109
102static void ops_free(const struct pernet_operations *ops, struct net *net) 110static void ops_free(const struct pernet_operations *ops, struct net *net)
@@ -446,12 +454,7 @@ static void __unregister_pernet_operations(struct pernet_operations *ops)
446static int __register_pernet_operations(struct list_head *list, 454static int __register_pernet_operations(struct list_head *list,
447 struct pernet_operations *ops) 455 struct pernet_operations *ops)
448{ 456{
449 int err = 0; 457 return ops_init(ops, &init_net);
450 err = ops_init(ops, &init_net);
451 if (err)
452 ops_free(ops, &init_net);
453 return err;
454
455} 458}
456 459
457static void __unregister_pernet_operations(struct pernet_operations *ops) 460static void __unregister_pernet_operations(struct pernet_operations *ops)