From c327cddd184059d018b12d7ef818ba0961200079 Mon Sep 17 00:00:00 2001
From: Michael Knudsen <m.knudsen@samsung.com>
Date: Tue, 18 Feb 2014 09:48:08 +0100
Subject: [PATCH] Bluetooth: Stop BCSP/H5 timer before cleaning up

When stopping BCSP/H5, stop the retransmission timer before proceeding
to clean up packet queues.  The previous code had a race condition where
the timer could trigger after the packet lists and protocol structure
had been removed which led to dereferencing NULL or use-after-free bugs.

Signed-off-by: Michael Knudsen <m.knudsen@samsung.com>
Reported-by: Kirill Tkhai <ktkhai@parallels.com>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
 drivers/bluetooth/hci_bcsp.c | 4 +++-
 drivers/bluetooth/hci_h5.c   | 4 ++--
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c
index 0bc87f7abd958..eee2fb23b3bfe 100644
--- a/drivers/bluetooth/hci_bcsp.c
+++ b/drivers/bluetooth/hci_bcsp.c
@@ -715,6 +715,9 @@ static int bcsp_open(struct hci_uart *hu)
 static int bcsp_close(struct hci_uart *hu)
 {
 	struct bcsp_struct *bcsp = hu->priv;
+
+	del_timer_sync(&bcsp->tbcsp);
+
 	hu->priv = NULL;
 
 	BT_DBG("hu %p", hu);
@@ -722,7 +725,6 @@ static int bcsp_close(struct hci_uart *hu)
 	skb_queue_purge(&bcsp->unack);
 	skb_queue_purge(&bcsp->rel);
 	skb_queue_purge(&bcsp->unrel);
-	del_timer(&bcsp->tbcsp);
 
 	kfree(bcsp);
 	return 0;
diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c
index f6f4974505600..afd759eaa7044 100644
--- a/drivers/bluetooth/hci_h5.c
+++ b/drivers/bluetooth/hci_h5.c
@@ -206,12 +206,12 @@ static int h5_close(struct hci_uart *hu)
 {
 	struct h5 *h5 = hu->priv;
 
+	del_timer_sync(&h5->timer);
+
 	skb_queue_purge(&h5->unack);
 	skb_queue_purge(&h5->rel);
 	skb_queue_purge(&h5->unrel);
 
-	del_timer(&h5->timer);
-
 	kfree(h5);
 
 	return 0;
-- 
2.30.2