diff options
author | Sungwoo Kim <iam@sung-woo.kim> | 2024-04-30 12:20:51 -0400 |
---|---|---|
committer | Luiz Augusto von Dentz <luiz.von.dentz@intel.com> | 2024-05-03 13:05:28 -0400 |
commit | 10f9f426ac6e752c8d87bf4346930ba347aaabac (patch) | |
tree | 8b5614014538497085d6e8b4d8eb1bb31dd28085 /net/bluetooth | |
parent | 4d7b41c0e43995b0e992b9f8903109275744b658 (diff) |
Bluetooth: msft: fix slab-use-after-free in msft_do_close()
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>
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/hci_core.c | 3 | ||||
-rw-r--r-- | net/bluetooth/msft.c | 2 | ||||
-rw-r--r-- | net/bluetooth/msft.h | 4 |
3 files changed, 4 insertions, 5 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index a7028d38c1f5..bc5086423ab8 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -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); diff --git a/net/bluetooth/msft.c b/net/bluetooth/msft.c index 9612c5d1b13f..d039683d3bdd 100644 --- a/net/bluetooth/msft.c +++ b/net/bluetooth/msft.c @@ -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; diff --git a/net/bluetooth/msft.h b/net/bluetooth/msft.h index 2a63205b377b..fe538e9c91c0 100644 --- a/net/bluetooth/msft.h +++ b/net/bluetooth/msft.h @@ -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, |