[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20201110084908.219088-1-tientzu@chromium.org>
Date: Tue, 10 Nov 2020 16:49:08 +0800
From: Claire Chang <tientzu@...omium.org>
To: johannes@...solutions.net, davem@...emloft.net, kuba@...nel.org,
hdegoede@...hat.com, marcel@...tmann.org
Cc: linux-wireless@...r.kernel.org, netdev@...r.kernel.org,
linux-kernel@...r.kernel.org, Claire Chang <tientzu@...omium.org>
Subject: [PATCH] rfkill: Fix use-after-free in rfkill_resume()
If a device is getting removed or reprobed during resume, use-after-free
might happen. For example, h5_btrtl_resume()[drivers/bluetooth/hci_h5.c]
schedules a work queue for device reprobing. During the reprobing, if
rfkill_set_block() in rfkill_resume() is called after the corresponding
*_unregister() and kfree() are called, there will be an use-after-free
in hci_rfkill_set_block()[net/bluetooth/hci_core.c].
BUG: KASAN: use-after-free in hci_rfkill_set_block+0x58/0xc0 [bluetooth]
...
Call trace:
dump_backtrace+0x0/0x154
show_stack+0x20/0x2c
dump_stack+0xbc/0x12c
print_address_description+0x88/0x4b0
__kasan_report+0x144/0x168
kasan_report+0x10/0x18
check_memory_region+0x19c/0x1ac
__kasan_check_write+0x18/0x24
hci_rfkill_set_block+0x58/0xc0 [bluetooth]
rfkill_set_block+0x9c/0x120
rfkill_resume+0x34/0x70
dpm_run_callback+0xf0/0x1f4
device_resume+0x210/0x22c
Fix this by checking rfkill->registered in rfkill_resume().
Since device_del() in rfkill_unregister() requires device_lock() and the
whole rfkill_resume() is also protected by the same lock in
device_resume()[drivers/base/power/main.c], we can make sure either the
rfkill->registered is false before rfkill_resume() starts or the rfkill
device won't be unregistered before rfkill_resume() returns.
Fixes: 8589086f4efd ("Bluetooth: hci_h5: Turn off RTL8723BS on suspend, reprobe on resume")
Signed-off-by: Claire Chang <tientzu@...omium.org>
---
net/rfkill/core.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/net/rfkill/core.c b/net/rfkill/core.c
index 971c73c7d34c..97101c55763d 100644
--- a/net/rfkill/core.c
+++ b/net/rfkill/core.c
@@ -876,6 +876,9 @@ static int rfkill_resume(struct device *dev)
rfkill->suspended = false;
+ if (!rfkill->registered)
+ return 0;
+
if (!rfkill->persistent) {
cur = !!(rfkill->state & RFKILL_BLOCK_SW);
rfkill_set_block(rfkill, cur);
--
2.29.2.222.g5d2a92d10f8-goog
Powered by blists - more mailing lists