CHROMIUM: bluetooth: fix use-after-free error
This patch fixed a use-after-free error. The statement
to print the opcode of current command should be executed
before the skb is freed.
BUG=chromium:782910
TEST=Verify with the following steps.
Step 1: Build a KASAN kernel for a chromebook, say eve,
without this patch.
(cr) $ USE="kasan" FEATURES="noclean" cros_workon_make --board=eve
--install chromeos-kernel-4_4
Use bluetoothctl to start discovery with "scan on" and then "scan off"
after a few seconds.
We would see the following use-after-free error.
ERR kernel: [ 524.812008] BUG: KASAN: use-after-free in hci_reset_dev
Step 2: Build a KASAN kernel for a chromebook, say eve,
with this patch.
(cr) $ USE="kasan" FEATURES="noclean" cros_workon_make --board=eve
--install chromeos-kernel-4_4
Use bluetoothctl to start discovery with "scan on" and then "scan off"
after a few seconds.
Verify that there is no more use-after-free error in dmesg.
Change-Id: I37c06f00cf31375bac0e3176c31ad131fa53667b
Signed-off-by: Joseph Hwang <josephsih@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/827042
Commit-Ready: Shyh-In Hwang <josephsih@chromium.org>
Tested-by: Shyh-In Hwang <josephsih@chromium.org>
Reviewed-by: Miao-chen Chou <mcchou@chromium.org>
(cherry picked from commit efecc2e9c0dd197948cb9714a2beb3312fe783e0)
(cherry picked from commit 759ad18fe788b842e19637a1b53b88999ec07210)
Reviewed-on: https://chromium-review.googlesource.com/841503
Commit-Queue: Miao-chen Chou <mcchou@chromium.org>
Tested-by: Miao-chen Chou <mcchou@chromium.org>
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 3fae80c..a7e73a7 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -4267,12 +4267,13 @@
*/
if ((cur_enabled == desired_enabled && !cur_changing) ||
(cur_enabled != desired_enabled && cur_changing)) {
- skb_orphan(skb);
- kfree_skb(skb);
-
BT_INFO(" COND LE cmd (0x%04x) is already %d (chg %d),"
" skip transition to %d", hci_skb_opcode(skb),
cur_enabled, cur_changing, desired_enabled);
+
+ skb_orphan(skb);
+ kfree_skb(skb);
+
/* See if there are more commands to do in cmd_q. */
atomic_set(&hdev->cmd_cnt, 1);
if (!skb_queue_empty(&hdev->cmd_q)) {