wil6210: fix race condition of disconnect while BACK event
authorDedy Lansky <qca_dlansky@qca.qualcomm.com>
Wed, 10 Sep 2014 13:34:40 +0000 (16:34 +0300)
committerJohn W. Linville <linville@tuxdriver.com>
Thu, 11 Sep 2014 19:27:37 +0000 (15:27 -0400)
This race condition was causing double free of tid_ampdu_rx structures

Signed-off-by: Dedy Lansky <qca_dlansky@qca.qualcomm.com>
Signed-off-by: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/ath/wil6210/wmi.c

index 97909f0b3ef86dc7b3e149e5c64568240a8a798b..c71657bb8ce14676d3e75a63c2edef7c8331e43b 100644 (file)
@@ -597,16 +597,18 @@ static void wmi_evt_ba_status(struct wil6210_priv *wil, int id, void *d,
                return;
        }
 
+       mutex_lock(&wil->mutex);
+
        cid = wil->vring2cid_tid[evt->ringid][0];
        if (cid >= WIL6210_MAX_CID) {
                wil_err(wil, "invalid CID %d for vring %d\n", cid, evt->ringid);
-               return;
+               goto out;
        }
 
        sta = &wil->sta[cid];
        if (sta->status == wil_sta_unused) {
                wil_err(wil, "CID %d unused\n", cid);
-               return;
+               goto out;
        }
 
        wil_dbg_wmi(wil, "BACK for CID %d %pM\n", cid, sta->addr);
@@ -618,6 +620,9 @@ static void wmi_evt_ba_status(struct wil6210_priv *wil, int id, void *d,
                        sta->tid_rx[i] = wil_tid_ampdu_rx_alloc(wil,
                                                evt->agg_wsize, 0);
        }
+
+out:
+       mutex_unlock(&wil->mutex);
 }
 
 static const struct {