All of lore.kernel.org
 help / color / mirror / Atom feed
From: syzbot <syzbot+feb0dc579bbe30a13190@syzkaller.appspotmail.com>
To: linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com
Subject: Re: [syzbot] Re: [PATCH v4 1/2] Bluetooth: MGMT: Fix UAF on mgmt_remove_adv_monitor_complete
Date: Tue, 03 Jun 2025 13:30:57 -0700	[thread overview]
Message-ID: <683f5b81.a00a0220.d4325.0001.GAE@google.com> (raw)
In-Reply-To: <68241bb2.a70a0220.3e9d8.0005.GAE@google.com>

For archival purposes, forwarding an incoming command email to
linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com.

***

Subject: Re: [PATCH v4 1/2] Bluetooth: MGMT: Fix UAF on mgmt_remove_adv_monitor_complete
Author: luiz.dentz@gmail.com

#syz test

On Tue, Jun 3, 2025 at 4:29 PM Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
>
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>
> This reworks MGMT_OP_REMOVE_ADV_MONITOR to not use mgmt_pending_add to
> avoid crashes like bellow:
>
> ==================================================================
> BUG: KASAN: slab-use-after-free in mgmt_remove_adv_monitor_complete+0xe5/0x540 net/bluetooth/mgmt.c:5406
> Read of size 8 at addr ffff88801c53f318 by task kworker/u5:5/5341
>
> CPU: 0 UID: 0 PID: 5341 Comm: kworker/u5:5 Not tainted 6.15.0-syzkaller-10402-g4cb6c8af8591 #0 PREEMPT(full)
> Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014
> Workqueue: hci0 hci_cmd_sync_work
> Call Trace:
>  <TASK>
>  dump_stack_lvl+0x189/0x250 lib/dump_stack.c:120
>  print_address_description mm/kasan/report.c:408 [inline]
>  print_report+0xd2/0x2b0 mm/kasan/report.c:521
>  kasan_report+0x118/0x150 mm/kasan/report.c:634
>  mgmt_remove_adv_monitor_complete+0xe5/0x540 net/bluetooth/mgmt.c:5406
>  hci_cmd_sync_work+0x261/0x3a0 net/bluetooth/hci_sync.c:334
>  process_one_work kernel/workqueue.c:3238 [inline]
>  process_scheduled_works+0xade/0x17b0 kernel/workqueue.c:3321
>  worker_thread+0x8a0/0xda0 kernel/workqueue.c:3402
>  kthread+0x711/0x8a0 kernel/kthread.c:464
>  ret_from_fork+0x3fc/0x770 arch/x86/kernel/process.c:148
>  ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
>  </TASK>
>
> Allocated by task 5987:
>  kasan_save_stack mm/kasan/common.c:47 [inline]
>  kasan_save_track+0x3e/0x80 mm/kasan/common.c:68
>  poison_kmalloc_redzone mm/kasan/common.c:377 [inline]
>  __kasan_kmalloc+0x93/0xb0 mm/kasan/common.c:394
>  kasan_kmalloc include/linux/kasan.h:260 [inline]
>  __kmalloc_cache_noprof+0x230/0x3d0 mm/slub.c:4358
>  kmalloc_noprof include/linux/slab.h:905 [inline]
>  kzalloc_noprof include/linux/slab.h:1039 [inline]
>  mgmt_pending_new+0x65/0x240 net/bluetooth/mgmt_util.c:252
>  mgmt_pending_add+0x34/0x120 net/bluetooth/mgmt_util.c:279
>  remove_adv_monitor+0x103/0x1b0 net/bluetooth/mgmt.c:5454
>  hci_mgmt_cmd+0x9c9/0xef0 net/bluetooth/hci_sock.c:1719
>  hci_sock_sendmsg+0x6ca/0xef0 net/bluetooth/hci_sock.c:1839
>  sock_sendmsg_nosec net/socket.c:712 [inline]
>  __sock_sendmsg+0x219/0x270 net/socket.c:727
>  sock_write_iter+0x258/0x330 net/socket.c:1131
>  new_sync_write fs/read_write.c:593 [inline]
>  vfs_write+0x548/0xa90 fs/read_write.c:686
>  ksys_write+0x145/0x250 fs/read_write.c:738
>  do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
>  do_syscall_64+0xfa/0x3b0 arch/x86/entry/syscall_64.c:94
>  entry_SYSCALL_64_after_hwframe+0x77/0x7f
>
> Freed by task 5989:
>  kasan_save_stack mm/kasan/common.c:47 [inline]
>  kasan_save_track+0x3e/0x80 mm/kasan/common.c:68
>  kasan_save_free_info+0x46/0x50 mm/kasan/generic.c:576
>  poison_slab_object mm/kasan/common.c:247 [inline]
>  __kasan_slab_free+0x62/0x70 mm/kasan/common.c:264
>  kasan_slab_free include/linux/kasan.h:233 [inline]
>  slab_free_hook mm/slub.c:2380 [inline]
>  slab_free mm/slub.c:4642 [inline]
>  kfree+0x18e/0x440 mm/slub.c:4841
>  mgmt_pending_foreach+0xc9/0x120 net/bluetooth/mgmt_util.c:242
>  mgmt_index_removed+0x10d/0x2f0 net/bluetooth/mgmt.c:9366
>  hci_sock_bind+0xbe9/0x1000 net/bluetooth/hci_sock.c:1314
>  __sys_bind_socket net/socket.c:1810 [inline]
>  __sys_bind+0x2c3/0x3e0 net/socket.c:1841
>  __do_sys_bind net/socket.c:1846 [inline]
>  __se_sys_bind net/socket.c:1844 [inline]
>  __x64_sys_bind+0x7a/0x90 net/socket.c:1844
>  do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
>  do_syscall_64+0xfa/0x3b0 arch/x86/entry/syscall_64.c:94
>  entry_SYSCALL_64_after_hwframe+0x77/0x7f
>
> Fixes: 66bd095ab5d4 ("Bluetooth: advmon offload MSFT remove monitor")
> Closes: https://syzkaller.appspot.com/bug?extid=feb0dc579bbe30a13190
> Reported-by: syzbot+feb0dc579bbe30a13190@syzkaller.appspotmail.com
> Tested-by: syzbot+feb0dc579bbe30a13190@syzkaller.appspotmail.com
> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
> ---
>  include/net/bluetooth/hci_core.h |  1 -
>  net/bluetooth/hci_core.c         |  4 +---
>  net/bluetooth/mgmt.c             | 37 ++++++++++----------------------
>  3 files changed, 12 insertions(+), 30 deletions(-)
>
> diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
> index 2b261e74e2c4..93fcb659f0d4 100644
> --- a/include/net/bluetooth/hci_core.h
> +++ b/include/net/bluetooth/hci_core.h
> @@ -2400,7 +2400,6 @@ void mgmt_advertising_added(struct sock *sk, struct hci_dev *hdev,
>                             u8 instance);
>  void mgmt_advertising_removed(struct sock *sk, struct hci_dev *hdev,
>                               u8 instance);
> -void mgmt_adv_monitor_removed(struct hci_dev *hdev, u16 handle);
>  int mgmt_phy_configuration_changed(struct hci_dev *hdev, struct sock *skip);
>  void mgmt_adv_monitor_device_lost(struct hci_dev *hdev, u16 handle,
>                                   bdaddr_t *bdaddr, u8 addr_type);
> diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
> index 04845ff3ad57..aeda2e4557d5 100644
> --- a/net/bluetooth/hci_core.c
> +++ b/net/bluetooth/hci_core.c
> @@ -1877,10 +1877,8 @@ void hci_free_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor)
>         if (monitor->handle)
>                 idr_remove(&hdev->adv_monitors_idr, monitor->handle);
>
> -       if (monitor->state != ADV_MONITOR_STATE_NOT_REGISTERED) {
> +       if (monitor->state != ADV_MONITOR_STATE_NOT_REGISTERED)
>                 hdev->adv_monitors_cnt--;
> -               mgmt_adv_monitor_removed(hdev, monitor->handle);
> -       }
>
>         kfree(monitor);
>  }
> diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
> index 14a9462fced5..feaeec2423ae 100644
> --- a/net/bluetooth/mgmt.c
> +++ b/net/bluetooth/mgmt.c
> @@ -5108,24 +5108,14 @@ static void mgmt_adv_monitor_added(struct sock *sk, struct hci_dev *hdev,
>         mgmt_event(MGMT_EV_ADV_MONITOR_ADDED, hdev, &ev, sizeof(ev), sk);
>  }
>
> -void mgmt_adv_monitor_removed(struct hci_dev *hdev, u16 handle)
> +static void mgmt_adv_monitor_removed(struct sock *sk, struct hci_dev *hdev,
> +                                    u16 handle)
>  {
>         struct mgmt_ev_adv_monitor_removed ev;
> -       struct mgmt_pending_cmd *cmd;
> -       struct sock *sk_skip = NULL;
> -       struct mgmt_cp_remove_adv_monitor *cp;
> -
> -       cmd = pending_find(MGMT_OP_REMOVE_ADV_MONITOR, hdev);
> -       if (cmd) {
> -               cp = cmd->param;
> -
> -               if (cp->monitor_handle)
> -                       sk_skip = cmd->sk;
> -       }
>
>         ev.monitor_handle = cpu_to_le16(handle);
>
> -       mgmt_event(MGMT_EV_ADV_MONITOR_REMOVED, hdev, &ev, sizeof(ev), sk_skip);
> +       mgmt_event(MGMT_EV_ADV_MONITOR_REMOVED, hdev, &ev, sizeof(ev), sk);
>  }
>
>  static int read_adv_mon_features(struct sock *sk, struct hci_dev *hdev,
> @@ -5227,8 +5217,7 @@ static int __add_adv_patterns_monitor(struct sock *sk, struct hci_dev *hdev,
>
>         if (pending_find(MGMT_OP_SET_LE, hdev) ||
>             pending_find(MGMT_OP_ADD_ADV_PATTERNS_MONITOR, hdev) ||
> -           pending_find(MGMT_OP_ADD_ADV_PATTERNS_MONITOR_RSSI, hdev) ||
> -           pending_find(MGMT_OP_REMOVE_ADV_MONITOR, hdev)) {
> +           pending_find(MGMT_OP_ADD_ADV_PATTERNS_MONITOR_RSSI, hdev)) {
>                 status = MGMT_STATUS_BUSY;
>                 goto unlock;
>         }
> @@ -5398,8 +5387,7 @@ static void mgmt_remove_adv_monitor_complete(struct hci_dev *hdev,
>         struct mgmt_pending_cmd *cmd = data;
>         struct mgmt_cp_remove_adv_monitor *cp;
>
> -       if (status == -ECANCELED ||
> -           cmd != pending_find(MGMT_OP_REMOVE_ADV_MONITOR, hdev))
> +       if (status == -ECANCELED)
>                 return;
>
>         hci_dev_lock(hdev);
> @@ -5408,12 +5396,14 @@ static void mgmt_remove_adv_monitor_complete(struct hci_dev *hdev,
>
>         rp.monitor_handle = cp->monitor_handle;
>
> -       if (!status)
> +       if (!status) {
> +               mgmt_adv_monitor_removed(cmd->sk, hdev, cp->monitor_handle);
>                 hci_update_passive_scan(hdev);
> +       }
>
>         mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode,
>                           mgmt_status(status), &rp, sizeof(rp));
> -       mgmt_pending_remove(cmd);
> +       mgmt_pending_free(cmd);
>
>         hci_dev_unlock(hdev);
>         bt_dev_dbg(hdev, "remove monitor %d complete, status %d",
> @@ -5423,10 +5413,6 @@ static void mgmt_remove_adv_monitor_complete(struct hci_dev *hdev,
>  static int mgmt_remove_adv_monitor_sync(struct hci_dev *hdev, void *data)
>  {
>         struct mgmt_pending_cmd *cmd = data;
> -
> -       if (cmd != pending_find(MGMT_OP_REMOVE_ADV_MONITOR, hdev))
> -               return -ECANCELED;
> -
>         struct mgmt_cp_remove_adv_monitor *cp = cmd->param;
>         u16 handle = __le16_to_cpu(cp->monitor_handle);
>
> @@ -5445,14 +5431,13 @@ static int remove_adv_monitor(struct sock *sk, struct hci_dev *hdev,
>         hci_dev_lock(hdev);
>
>         if (pending_find(MGMT_OP_SET_LE, hdev) ||
> -           pending_find(MGMT_OP_REMOVE_ADV_MONITOR, hdev) ||
>             pending_find(MGMT_OP_ADD_ADV_PATTERNS_MONITOR, hdev) ||
>             pending_find(MGMT_OP_ADD_ADV_PATTERNS_MONITOR_RSSI, hdev)) {
>                 status = MGMT_STATUS_BUSY;
>                 goto unlock;
>         }
>
> -       cmd = mgmt_pending_add(sk, MGMT_OP_REMOVE_ADV_MONITOR, hdev, data, len);
> +       cmd = mgmt_pending_new(sk, MGMT_OP_REMOVE_ADV_MONITOR, hdev, data, len);
>         if (!cmd) {
>                 status = MGMT_STATUS_NO_RESOURCES;
>                 goto unlock;
> @@ -5462,7 +5447,7 @@ static int remove_adv_monitor(struct sock *sk, struct hci_dev *hdev,
>                                   mgmt_remove_adv_monitor_complete);
>
>         if (err) {
> -               mgmt_pending_remove(cmd);
> +               mgmt_pending_free(cmd);
>
>                 if (err == -ENOMEM)
>                         status = MGMT_STATUS_NO_RESOURCES;
> --
> 2.49.0
>


-- 
Luiz Augusto von Dentz

      parent reply	other threads:[~2025-06-03 20:30 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-05-14  4:27 [syzbot] [bluetooth?] KASAN: slab-use-after-free Read in mgmt_remove_adv_monitor_complete (3) syzbot
2025-05-14  7:10 ` [syzbot] #syz test: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 9f35e33144ae5377d6a8de86dd3bd4d995c6ac65 syzbot
2025-05-20 13:30 ` [syzbot] #syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git a5806cd506af5a7c19bcd596e4708b5c464bfd21 syzbot
2025-05-23  8:20 ` [syzbot] #syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 94305e83eccb3120c921cd3a015cd74731140bac syzbot
2025-05-23  8:20 ` syzbot
2025-05-28 19:03 ` [syzbot] Re: [PATCH v1] Bluetooth: MGMT: Use RCU-protected in mgmt_pending list syzbot
2025-06-02 18:00 ` [syzbot] Re: [PATCH v3] Bluetooth: MGMT: Protect mgmt_pending list with its own lock syzbot
2025-06-03 20:30 ` syzbot [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=683f5b81.a00a0220.d4325.0001.GAE@google.com \
    --to=syzbot+feb0dc579bbe30a13190@syzkaller.appspotmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=syzkaller-bugs@googlegroups.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.