]> git.dujemihanovic.xyz Git - linux.git/commitdiff
Bluetooth: msft: fix slab-use-after-free in msft_do_close()
authorSungwoo Kim <iam@sung-woo.kim>
Tue, 30 Apr 2024 16:20:51 +0000 (12:20 -0400)
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Fri, 3 May 2024 17:05:28 +0000 (13:05 -0400)
Tying the msft->data lifetime to hdev by freeing it in
hci_release_dev() to fix the following case:

[use]
msft_do_close()
  msft = hdev->msft_data;
  if (!msft)                      ...(1) <- passed.
    return;
  mutex_lock(&msft->filter_lock); ...(4) <- used after freed.

[free]
msft_unregister()
  msft = hdev->msft_data;
  hdev->msft_data = NULL;         ...(2)
  kfree(msft);                    ...(3) <- msft is freed.

==================================================================
BUG: KASAN: slab-use-after-free in __mutex_lock_common
kernel/locking/mutex.c:587 [inline]
BUG: KASAN: slab-use-after-free in __mutex_lock+0x8f/0xc30
kernel/locking/mutex.c:752
Read of size 8 at addr ffff888106cbbca8 by task kworker/u5:2/309

Fixes: bf6a4e30ffbd ("Bluetooth: disable advertisement filters during suspend")
Signed-off-by: Sungwoo Kim <iam@sung-woo.kim>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
net/bluetooth/hci_core.c
net/bluetooth/msft.c
net/bluetooth/msft.h

index a7028d38c1f5cc756aed90c3859638284996011f..bc5086423ab839d6ad451234dc3bece65a3096fa 100644 (file)
@@ -2768,8 +2768,6 @@ void hci_unregister_dev(struct hci_dev *hdev)
 
        hci_unregister_suspend_notifier(hdev);
 
-       msft_unregister(hdev);
-
        hci_dev_do_close(hdev);
 
        if (!test_bit(HCI_INIT, &hdev->flags) &&
@@ -2823,6 +2821,7 @@ void hci_release_dev(struct hci_dev *hdev)
        hci_discovery_filter_clear(hdev);
        hci_blocked_keys_clear(hdev);
        hci_codec_list_clear(&hdev->local_codecs);
+       msft_release(hdev);
        hci_dev_unlock(hdev);
 
        ida_destroy(&hdev->unset_handle_ida);
index 9612c5d1b13f6d2eed675d94d81c5e9b1483afa3..d039683d3bdd4128a0c911a12259cfb1f1abbbaf 100644 (file)
@@ -769,7 +769,7 @@ void msft_register(struct hci_dev *hdev)
        mutex_init(&msft->filter_lock);
 }
 
-void msft_unregister(struct hci_dev *hdev)
+void msft_release(struct hci_dev *hdev)
 {
        struct msft_data *msft = hdev->msft_data;
 
index 2a63205b377b70a79044b983d49f140fd3eb5578..fe538e9c91c0194db03c0dd32e664a4cd20d5d98 100644 (file)
@@ -14,7 +14,7 @@
 
 bool msft_monitor_supported(struct hci_dev *hdev);
 void msft_register(struct hci_dev *hdev);
-void msft_unregister(struct hci_dev *hdev);
+void msft_release(struct hci_dev *hdev);
 void msft_do_open(struct hci_dev *hdev);
 void msft_do_close(struct hci_dev *hdev);
 void msft_vendor_evt(struct hci_dev *hdev, void *data, struct sk_buff *skb);
@@ -35,7 +35,7 @@ static inline bool msft_monitor_supported(struct hci_dev *hdev)
 }
 
 static inline void msft_register(struct hci_dev *hdev) {}
-static inline void msft_unregister(struct hci_dev *hdev) {}
+static inline void msft_release(struct hci_dev *hdev) {}
 static inline void msft_do_open(struct hci_dev *hdev) {}
 static inline void msft_do_close(struct hci_dev *hdev) {}
 static inline void msft_vendor_evt(struct hci_dev *hdev, void *data,