Showing error 927

User: Jiri Slaby
Error type: Leaving function in locked state
Error type description: Some lock is not unlocked on all paths of a function, so it is leaked
File location: net/core/net_namespace.c
Line in file: 347
Project: Linux Kernel
Project version: 2.6.28
Confirmation: Removed in f875bae065334907796da12523f9df85c89f5712
Tools: Stanse (1.2)
Entered: 2012-03-02 21:35:17 UTC


Source:

  1#include <linux/workqueue.h>
  2#include <linux/rtnetlink.h>
  3#include <linux/cache.h>
  4#include <linux/slab.h>
  5#include <linux/list.h>
  6#include <linux/delay.h>
  7#include <linux/sched.h>
  8#include <linux/idr.h>
  9#include <net/net_namespace.h>
 10#include <net/netns/generic.h>
 11
 12/*
 13 *        Our network namespace constructor/destructor lists
 14 */
 15
 16static LIST_HEAD(pernet_list);
 17static struct list_head *first_device = &pernet_list;
 18static DEFINE_MUTEX(net_mutex);
 19
 20LIST_HEAD(net_namespace_list);
 21EXPORT_SYMBOL_GPL(net_namespace_list);
 22
 23struct net init_net;
 24EXPORT_SYMBOL(init_net);
 25
 26#define INITIAL_NET_GEN_PTRS        13 /* +1 for len +2 for rcu_head */
 27
 28/*
 29 * setup_net runs the initializers for the network namespace object.
 30 */
 31static __net_init int setup_net(struct net *net)
 32{
 33        /* Must be called with net_mutex held */
 34        struct pernet_operations *ops;
 35        int error;
 36        struct net_generic *ng;
 37
 38        atomic_set(&net->count, 1);
 39#ifdef NETNS_REFCNT_DEBUG
 40        atomic_set(&net->use_count, 0);
 41#endif
 42
 43        error = -ENOMEM;
 44        ng = kzalloc(sizeof(struct net_generic) +
 45                        INITIAL_NET_GEN_PTRS * sizeof(void *), GFP_KERNEL);
 46        if (ng == NULL)
 47                goto out;
 48
 49        ng->len = INITIAL_NET_GEN_PTRS;
 50        INIT_RCU_HEAD(&ng->rcu);
 51        rcu_assign_pointer(net->gen, ng);
 52
 53        error = 0;
 54        list_for_each_entry(ops, &pernet_list, list) {
 55                if (ops->init) {
 56                        error = ops->init(net);
 57                        if (error < 0)
 58                                goto out_undo;
 59                }
 60        }
 61out:
 62        return error;
 63
 64out_undo:
 65        /* Walk through the list backwards calling the exit functions
 66         * for the pernet modules whose init functions did not fail.
 67         */
 68        list_for_each_entry_continue_reverse(ops, &pernet_list, list) {
 69                if (ops->exit)
 70                        ops->exit(net);
 71        }
 72
 73        rcu_barrier();
 74        kfree(ng);
 75        goto out;
 76}
 77
 78#ifdef CONFIG_NET_NS
 79static struct kmem_cache *net_cachep;
 80static struct workqueue_struct *netns_wq;
 81
 82static struct net *net_alloc(void)
 83{
 84        return kmem_cache_zalloc(net_cachep, GFP_KERNEL);
 85}
 86
 87static void net_free(struct net *net)
 88{
 89        if (!net)
 90                return;
 91
 92#ifdef NETNS_REFCNT_DEBUG
 93        if (unlikely(atomic_read(&net->use_count) != 0)) {
 94                printk(KERN_EMERG "network namespace not free! Usage: %d\n",
 95                        atomic_read(&net->use_count));
 96                return;
 97        }
 98#endif
 99        kfree(net->gen);
100        kmem_cache_free(net_cachep, net);
101}
102
103struct net *copy_net_ns(unsigned long flags, struct net *old_net)
104{
105        struct net *new_net = NULL;
106        int err;
107
108        get_net(old_net);
109
110        if (!(flags & CLONE_NEWNET))
111                return old_net;
112
113        err = -ENOMEM;
114        new_net = net_alloc();
115        if (!new_net)
116                goto out;
117
118        mutex_lock(&net_mutex);
119        err = setup_net(new_net);
120        if (err)
121                goto out_unlock;
122
123        rtnl_lock();
124        list_add_tail(&new_net->list, &net_namespace_list);
125        rtnl_unlock();
126
127
128out_unlock:
129        mutex_unlock(&net_mutex);
130out:
131        put_net(old_net);
132        if (err) {
133                net_free(new_net);
134                new_net = ERR_PTR(err);
135        }
136        return new_net;
137}
138
139static void cleanup_net(struct work_struct *work)
140{
141        struct pernet_operations *ops;
142        struct net *net;
143
144        /* Be very certain incoming network packets will not find us */
145        rcu_barrier();
146
147        net = container_of(work, struct net, work);
148
149        mutex_lock(&net_mutex);
150
151        /* Don't let anyone else find us. */
152        rtnl_lock();
153        list_del(&net->list);
154        rtnl_unlock();
155
156        /* Run all of the network namespace exit methods */
157        list_for_each_entry_reverse(ops, &pernet_list, list) {
158                if (ops->exit)
159                        ops->exit(net);
160        }
161
162        mutex_unlock(&net_mutex);
163
164        /* Ensure there are no outstanding rcu callbacks using this
165         * network namespace.
166         */
167        rcu_barrier();
168
169        /* Finally it is safe to free my network namespace structure */
170        net_free(net);
171}
172
173void __put_net(struct net *net)
174{
175        /* Cleanup the network namespace in process context */
176        INIT_WORK(&net->work, cleanup_net);
177        queue_work(netns_wq, &net->work);
178}
179EXPORT_SYMBOL_GPL(__put_net);
180
181#else
182struct net *copy_net_ns(unsigned long flags, struct net *old_net)
183{
184        if (flags & CLONE_NEWNET)
185                return ERR_PTR(-EINVAL);
186        return old_net;
187}
188#endif
189
190static int __init net_ns_init(void)
191{
192        int err;
193
194        printk(KERN_INFO "net_namespace: %zd bytes\n", sizeof(struct net));
195#ifdef CONFIG_NET_NS
196        net_cachep = kmem_cache_create("net_namespace", sizeof(struct net),
197                                        SMP_CACHE_BYTES,
198                                        SLAB_PANIC, NULL);
199
200        /* Create workqueue for cleanup */
201        netns_wq = create_singlethread_workqueue("netns");
202        if (!netns_wq)
203                panic("Could not create netns workq");
204#endif
205
206        mutex_lock(&net_mutex);
207        err = setup_net(&init_net);
208
209        rtnl_lock();
210        list_add_tail(&init_net.list, &net_namespace_list);
211        rtnl_unlock();
212
213        mutex_unlock(&net_mutex);
214        if (err)
215                panic("Could not setup the initial network namespace");
216
217        return 0;
218}
219
220pure_initcall(net_ns_init);
221
222#ifdef CONFIG_NET_NS
223static int register_pernet_operations(struct list_head *list,
224                                      struct pernet_operations *ops)
225{
226        struct net *net, *undo_net;
227        int error;
228
229        list_add_tail(&ops->list, list);
230        if (ops->init) {
231                for_each_net(net) {
232                        error = ops->init(net);
233                        if (error)
234                                goto out_undo;
235                }
236        }
237        return 0;
238
239out_undo:
240        /* If I have an error cleanup all namespaces I initialized */
241        list_del(&ops->list);
242        if (ops->exit) {
243                for_each_net(undo_net) {
244                        if (undo_net == net)
245                                goto undone;
246                        ops->exit(undo_net);
247                }
248        }
249undone:
250        return error;
251}
252
253static void unregister_pernet_operations(struct pernet_operations *ops)
254{
255        struct net *net;
256
257        list_del(&ops->list);
258        if (ops->exit)
259                for_each_net(net)
260                        ops->exit(net);
261}
262
263#else
264
265static int register_pernet_operations(struct list_head *list,
266                                      struct pernet_operations *ops)
267{
268        if (ops->init == NULL)
269                return 0;
270        return ops->init(&init_net);
271}
272
273static void unregister_pernet_operations(struct pernet_operations *ops)
274{
275        if (ops->exit)
276                ops->exit(&init_net);
277}
278#endif
279
280static DEFINE_IDA(net_generic_ids);
281
282/**
283 *      register_pernet_subsys - register a network namespace subsystem
284 *        @ops:  pernet operations structure for the subsystem
285 *
286 *        Register a subsystem which has init and exit functions
287 *        that are called when network namespaces are created and
288 *        destroyed respectively.
289 *
290 *        When registered all network namespace init functions are
291 *        called for every existing network namespace.  Allowing kernel
292 *        modules to have a race free view of the set of network namespaces.
293 *
294 *        When a new network namespace is created all of the init
295 *        methods are called in the order in which they were registered.
296 *
297 *        When a network namespace is destroyed all of the exit methods
298 *        are called in the reverse of the order with which they were
299 *        registered.
300 */
301int register_pernet_subsys(struct pernet_operations *ops)
302{
303        int error;
304        mutex_lock(&net_mutex);
305        error =  register_pernet_operations(first_device, ops);
306        mutex_unlock(&net_mutex);
307        return error;
308}
309EXPORT_SYMBOL_GPL(register_pernet_subsys);
310
311/**
312 *      unregister_pernet_subsys - unregister a network namespace subsystem
313 *        @ops: pernet operations structure to manipulate
314 *
315 *        Remove the pernet operations structure from the list to be
316 *        used when network namespaces are created or destroyed.  In
317 *        addition run the exit method for all existing network
318 *        namespaces.
319 */
320void unregister_pernet_subsys(struct pernet_operations *module)
321{
322        mutex_lock(&net_mutex);
323        unregister_pernet_operations(module);
324        mutex_unlock(&net_mutex);
325}
326EXPORT_SYMBOL_GPL(unregister_pernet_subsys);
327
328int register_pernet_gen_subsys(int *id, struct pernet_operations *ops)
329{
330        int rv;
331
332        mutex_lock(&net_mutex);
333again:
334        rv = ida_get_new_above(&net_generic_ids, 1, id);
335        if (rv < 0) {
336                if (rv == -EAGAIN) {
337                        ida_pre_get(&net_generic_ids, GFP_KERNEL);
338                        goto again;
339                }
340                goto out;
341        }
342        rv = register_pernet_operations(first_device, ops);
343        if (rv < 0)
344                ida_remove(&net_generic_ids, *id);
345        mutex_unlock(&net_mutex);
346out:
347        return rv;
348}
349EXPORT_SYMBOL_GPL(register_pernet_gen_subsys);
350
351void unregister_pernet_gen_subsys(int id, struct pernet_operations *ops)
352{
353        mutex_lock(&net_mutex);
354        unregister_pernet_operations(ops);
355        ida_remove(&net_generic_ids, id);
356        mutex_unlock(&net_mutex);
357}
358EXPORT_SYMBOL_GPL(unregister_pernet_gen_subsys);
359
360/**
361 *      register_pernet_device - register a network namespace device
362 *        @ops:  pernet operations structure for the subsystem
363 *
364 *        Register a device which has init and exit functions
365 *        that are called when network namespaces are created and
366 *        destroyed respectively.
367 *
368 *        When registered all network namespace init functions are
369 *        called for every existing network namespace.  Allowing kernel
370 *        modules to have a race free view of the set of network namespaces.
371 *
372 *        When a new network namespace is created all of the init
373 *        methods are called in the order in which they were registered.
374 *
375 *        When a network namespace is destroyed all of the exit methods
376 *        are called in the reverse of the order with which they were
377 *        registered.
378 */
379int register_pernet_device(struct pernet_operations *ops)
380{
381        int error;
382        mutex_lock(&net_mutex);
383        error = register_pernet_operations(&pernet_list, ops);
384        if (!error && (first_device == &pernet_list))
385                first_device = &ops->list;
386        mutex_unlock(&net_mutex);
387        return error;
388}
389EXPORT_SYMBOL_GPL(register_pernet_device);
390
391int register_pernet_gen_device(int *id, struct pernet_operations *ops)
392{
393        int error;
394        mutex_lock(&net_mutex);
395again:
396        error = ida_get_new_above(&net_generic_ids, 1, id);
397        if (error) {
398                if (error == -EAGAIN) {
399                        ida_pre_get(&net_generic_ids, GFP_KERNEL);
400                        goto again;
401                }
402                goto out;
403        }
404        error = register_pernet_operations(&pernet_list, ops);
405        if (error)
406                ida_remove(&net_generic_ids, *id);
407        else if (first_device == &pernet_list)
408                first_device = &ops->list;
409out:
410        mutex_unlock(&net_mutex);
411        return error;
412}
413EXPORT_SYMBOL_GPL(register_pernet_gen_device);
414
415/**
416 *      unregister_pernet_device - unregister a network namespace netdevice
417 *        @ops: pernet operations structure to manipulate
418 *
419 *        Remove the pernet operations structure from the list to be
420 *        used when network namespaces are created or destroyed.  In
421 *        addition run the exit method for all existing network
422 *        namespaces.
423 */
424void unregister_pernet_device(struct pernet_operations *ops)
425{
426        mutex_lock(&net_mutex);
427        if (&ops->list == first_device)
428                first_device = first_device->next;
429        unregister_pernet_operations(ops);
430        mutex_unlock(&net_mutex);
431}
432EXPORT_SYMBOL_GPL(unregister_pernet_device);
433
434void unregister_pernet_gen_device(int id, struct pernet_operations *ops)
435{
436        mutex_lock(&net_mutex);
437        if (&ops->list == first_device)
438                first_device = first_device->next;
439        unregister_pernet_operations(ops);
440        ida_remove(&net_generic_ids, id);
441        mutex_unlock(&net_mutex);
442}
443EXPORT_SYMBOL_GPL(unregister_pernet_gen_device);
444
445static void net_generic_release(struct rcu_head *rcu)
446{
447        struct net_generic *ng;
448
449        ng = container_of(rcu, struct net_generic, rcu);
450        kfree(ng);
451}
452
453int net_assign_generic(struct net *net, int id, void *data)
454{
455        struct net_generic *ng, *old_ng;
456
457        BUG_ON(!mutex_is_locked(&net_mutex));
458        BUG_ON(id == 0);
459
460        ng = old_ng = net->gen;
461        if (old_ng->len >= id)
462                goto assign;
463
464        ng = kzalloc(sizeof(struct net_generic) +
465                        id * sizeof(void *), GFP_KERNEL);
466        if (ng == NULL)
467                return -ENOMEM;
468
469        /*
470         * Some synchronisation notes:
471         *
472         * The net_generic explores the net->gen array inside rcu
473         * read section. Besides once set the net->gen->ptr[x]
474         * pointer never changes (see rules in netns/generic.h).
475         *
476         * That said, we simply duplicate this array and schedule
477         * the old copy for kfree after a grace period.
478         */
479
480        ng->len = id;
481        INIT_RCU_HEAD(&ng->rcu);
482        memcpy(&ng->ptr, &old_ng->ptr, old_ng->len);
483
484        rcu_assign_pointer(net->gen, ng);
485        call_rcu(&old_ng->rcu, net_generic_release);
486assign:
487        ng->ptr[id - 1] = data;
488        return 0;
489}
490EXPORT_SYMBOL_GPL(net_assign_generic);