aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Woodhouse <David.Woodhouse@intel.com>2012-11-27 19:46:45 -0500
committerDavid Woodhouse <David.Woodhouse@intel.com>2012-12-01 19:05:16 -0500
commitd71ffeb12378243babb2227acfed0c8d263e237e (patch)
tree06c451e078f5e11a6ce8135ef0c4539ca6e0e82c
parent0e56d99a5b557c760394d6941d7d1fc8d279eff3 (diff)
br2684: fix module_put() race
The br2684 code used module_put() during unassignment from vcc with hope that we have BKL. This assumption is no longer true. Now owner field in atmvcc is used to move this module_put() to vcc_destroy_socket(). Signed-off-by: David Woodhouse <David.Woodhouse@intel.com> Acked-by: Krzysztof Mazur <krzysiek@podlesie.net>
-rw-r--r--net/atm/br2684.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/net/atm/br2684.c b/net/atm/br2684.c
index 4de3ae7bc3e2..6dc383c90262 100644
--- a/net/atm/br2684.c
+++ b/net/atm/br2684.c
@@ -69,6 +69,7 @@ struct br2684_vcc {
69 void (*old_push)(struct atm_vcc *vcc, struct sk_buff *skb); 69 void (*old_push)(struct atm_vcc *vcc, struct sk_buff *skb);
70 void (*old_pop)(struct atm_vcc *vcc, struct sk_buff *skb); 70 void (*old_pop)(struct atm_vcc *vcc, struct sk_buff *skb);
71 void (*old_release_cb)(struct atm_vcc *vcc); 71 void (*old_release_cb)(struct atm_vcc *vcc);
72 struct module *old_owner;
72 enum br2684_encaps encaps; 73 enum br2684_encaps encaps;
73 struct list_head brvccs; 74 struct list_head brvccs;
74#ifdef CONFIG_ATM_BR2684_IPFILTER 75#ifdef CONFIG_ATM_BR2684_IPFILTER
@@ -414,8 +415,8 @@ static void br2684_close_vcc(struct br2684_vcc *brvcc)
414 brvcc->atmvcc->user_back = NULL; /* what about vcc->recvq ??? */ 415 brvcc->atmvcc->user_back = NULL; /* what about vcc->recvq ??? */
415 brvcc->atmvcc->release_cb = brvcc->old_release_cb; 416 brvcc->atmvcc->release_cb = brvcc->old_release_cb;
416 brvcc->old_push(brvcc->atmvcc, NULL); /* pass on the bad news */ 417 brvcc->old_push(brvcc->atmvcc, NULL); /* pass on the bad news */
418 module_put(brvcc->old_owner);
417 kfree(brvcc); 419 kfree(brvcc);
418 module_put(THIS_MODULE);
419} 420}
420 421
421/* when AAL5 PDU comes in: */ 422/* when AAL5 PDU comes in: */
@@ -590,10 +591,12 @@ static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg)
590 brvcc->old_push = atmvcc->push; 591 brvcc->old_push = atmvcc->push;
591 brvcc->old_pop = atmvcc->pop; 592 brvcc->old_pop = atmvcc->pop;
592 brvcc->old_release_cb = atmvcc->release_cb; 593 brvcc->old_release_cb = atmvcc->release_cb;
594 brvcc->old_owner = atmvcc->owner;
593 barrier(); 595 barrier();
594 atmvcc->push = br2684_push; 596 atmvcc->push = br2684_push;
595 atmvcc->pop = br2684_pop; 597 atmvcc->pop = br2684_pop;
596 atmvcc->release_cb = br2684_release_cb; 598 atmvcc->release_cb = br2684_release_cb;
599 atmvcc->owner = THIS_MODULE;
597 600
598 /* initialize netdev carrier state */ 601 /* initialize netdev carrier state */
599 if (atmvcc->dev->signal == ATM_PHY_SIG_LOST) 602 if (atmvcc->dev->signal == ATM_PHY_SIG_LOST)