aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn
diff options
context:
space:
mode:
authorKarsten Keil <keil@b1-systems.de>2009-06-09 08:38:39 -0400
committerKarsten Keil <keil@b1-systems.de>2009-06-11 13:05:18 -0400
commit8164491dd628ffcac5d61267f747997689ee256c (patch)
tree146094cf95bb3a57708cb1f302c6cf5580c5a4ba /drivers/isdn
parent395df11f5fa7fe852be28ccec8aaa15634386ad1 (diff)
mISDN: Do not disable IRQ in ph_data_ind()
This fix triggering the WARN_ON_ONCE(in_irq() || irqs_disabled()); in local_bh_enable(). Here is no need to grab this lock, this was wrong at all and may cause a deadlock and access to freed memory, since on a TEI remove the current listelement can be deleted under us. So this is clearly a case for list_for_each_entry_safe. Signed-off-by: Karsten Keil <keil@b1-systems.de>
Diffstat (limited to 'drivers/isdn')
-rw-r--r--drivers/isdn/mISDN/tei.c7
1 files changed, 2 insertions, 5 deletions
diff --git a/drivers/isdn/mISDN/tei.c b/drivers/isdn/mISDN/tei.c
index bfcdd97df95d..e04bad6c5baf 100644
--- a/drivers/isdn/mISDN/tei.c
+++ b/drivers/isdn/mISDN/tei.c
@@ -862,8 +862,7 @@ static int
862ph_data_ind(struct manager *mgr, struct sk_buff *skb) 862ph_data_ind(struct manager *mgr, struct sk_buff *skb)
863{ 863{
864 int ret = -EINVAL; 864 int ret = -EINVAL;
865 struct layer2 *l2; 865 struct layer2 *l2, *nl2;
866 u_long flags;
867 u_char mt; 866 u_char mt;
868 867
869 if (skb->len < 8) { 868 if (skb->len < 8) {
@@ -908,11 +907,9 @@ ph_data_ind(struct manager *mgr, struct sk_buff *skb)
908 new_tei_req(mgr, &skb->data[4]); 907 new_tei_req(mgr, &skb->data[4]);
909 goto done; 908 goto done;
910 } 909 }
911 read_lock_irqsave(&mgr->lock, flags); 910 list_for_each_entry_safe(l2, nl2, &mgr->layer2, list) {
912 list_for_each_entry(l2, &mgr->layer2, list) {
913 tei_ph_data_ind(l2->tm, mt, &skb->data[4], skb->len - 4); 911 tei_ph_data_ind(l2->tm, mt, &skb->data[4], skb->len - 4);
914 } 912 }
915 read_unlock_irqrestore(&mgr->lock, flags);
916done: 913done:
917 return ret; 914 return ret;
918} 915}