Linux kernel -stable discussions
 help / color / mirror / Atom feed
From: w15303746062  <w15303746062@163.com>
To: "Luiz Augusto von Dentz" <luiz.dentz@gmail.com>
Cc: pmenzel@molgen.mpg.de, marcel@holtmann.org,
	linux-bluetooth@vger.kernel.org, linux-serial@vger.kernel.org,
	linux-kernel@vger.kernel.org, greg@kroah.com,
	stable@vger.kernel.org,
	"Mingyu Wang" <25181214217@stu.xidian.edu.cn>
Subject: Re:Re: [PATCH v4] Bluetooth: hci_uart: fix UAF in hci_uart_tty_close()
Date: Sat, 16 May 2026 09:41:18 +0800 (CST)	[thread overview]
Message-ID: <485d0dd5.660.19e2e71ed1e.Coremail.w15303746062@163.com> (raw)
In-Reply-To: <CABBYNZ+r3gm37FW5WqE79bRp+x9UZsaCtyvfz_FdixqEucAxGw@mail.gmail.com>


Hi Luiz,

Thank you for checking it with Sashiko.


At 2026-05-16 00:08:05, "Luiz Augusto von Dentz" <luiz.dentz@gmail.com> wrote:
>Hi,
>
>On Fri, May 15, 2026 at 10:06 AM <w15303746062@163.com> wrote:
>>
>> From: Mingyu Wang <25181214217@stu.xidian.edu.cn>
>>
>> A Use-After-Free (UAF) vulnerability and a subsequent kernel panic were
>> observed in hci_uart_write_work() due to a race condition between the
>> initialization of the HCI UART line discipline and concurrent TTY hangup.
>>
>> This issue was triggered by our custom device emulation and fuzzing
>> framework (DevGen) on the v6.18 kernel. Due to the highly timing-dependent
>> nature of this race condition (requiring a precise interleaving of
>> TIOCVHANGUP and protocol setup), Syzkaller failed to extract a reliable
>> standalone C reproducer (reproducer is too unreliable: 0.00).
>>
>> The crash trace is as follows:
>>   ODEBUG: free active (active state 0) object: ffff88804024e870 object type: work_struct hint: hci_uart_write_work+0x0/0x940
>>   WARNING: CPU: 0 PID: 338273 at lib/debugobjects.c:612 debug_print_object+0x1a2/0x2b0
>>   ...
>>   Call Trace:
>>    <TASK>
>>    debug_check_no_obj_freed+0x3ec/0x520
>>    kfree+0x3f0/0x6c0
>>    hci_uart_tty_close+0x127/0x2a0
>>    tty_ldisc_close+0x113/0x1a0
>>    tty_ldisc_kill+0x8e/0x150
>>    tty_ldisc_hangup+0x3c1/0x730
>>    __tty_hangup.part.0+0x3fd/0x8a0
>>    tty_ioctl+0x120f/0x1690
>>    __x64_sys_ioctl+0x18f/0x210
>>    do_syscall_64+0xcb/0xfa0
>>    entry_SYSCALL_64_after_hwframe+0x77/0x7f
>>    </TASK>
>>
>> The issue arises because the workqueues (init_ready and write_work) are
>> only flushed/cancelled if the HCI_UART_PROTO_READY flag is set. However,
>> during the protocol initialization phase (HCI_UART_PROTO_INIT), the
>> underlying protocol may schedule work. If a hangup occurs before the setup
>> completes and the READY flag is set, hci_uart_tty_close() skips the
>> teardown of these workqueues and proceeds to free the `hu` struct. When
>> the scheduled work executes later, it blindly dereferences the freed `hu`
>> struct.
>>
>> Fix this by moving the workqueue teardown outside the HCI_UART_PROTO_READY
>> check. Furthermore, use disable_work_sync() instead of cancel_work_sync()
>> to unconditionally disable the works. This ensures that any pending works
>> are cancelled and no new submissions can occur before the hci_uart
>> structure is freed. Note that hu->init_ready and hu->write_work are
>> initialized in hci_uart_tty_open(), so it is always safe to call
>> disable_work_sync() on them in hci_uart_tty_close(), even if the protocol
>> was never fully attached.
>>
>> Fixes: 3b799254cf6f ("Bluetooth: hci_uart: Cancel init work before unregistering")
>> Cc: stable@vger.kernel.org
>> Signed-off-by: Mingyu Wang <25181214217@stu.xidian.edu.cn>
>> ---
>> Changes in v4:
>> - Adopted Luiz's suggestion to use disable_work_sync() instead of
>>   cancel_work_sync() to prevent new work submissions during teardown.
>>
>> Changes in v3:
>> - Added 'Cc: stable' tag as requested by the stable bot.
>>
>> Changes in v2:
>> - Added KASAN/ODEBUG crash trace.
>>
>>  drivers/bluetooth/hci_ldisc.c | 12 +++++++++---
>>  1 file changed, 9 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
>> index 275ea865bc29..333c1e1503e8 100644
>> --- a/drivers/bluetooth/hci_ldisc.c
>> +++ b/drivers/bluetooth/hci_ldisc.c
>> @@ -544,14 +544,20 @@ static void hci_uart_tty_close(struct tty_struct *tty)
>>         if (hdev)
>>                 hci_uart_close(hdev);
>>
>> +       /*
>> +        * Disable workqueues unconditionally before freeing the hu
>> +        * struct, as they might be active during the PROTO_INIT phase.
>> +        * Using disable_work_sync() instead of cancel_work_sync()
>> +        * ensures no new submissions can occur.
>> +        */
>> +       disable_work_sync(&hu->init_ready);
>> +       disable_work_sync(&hu->write_work);
>
>Looks like sashiko has a problem with these being after hci_uart_close:

I see the issue now. Placing `disable_work_sync()` after `hci_uart_close()`
could still leave a tiny window where the workqueues might race with the 
teardown of the `hdev` structure. 

The safest and most logical approach is to pull the `disable_work_sync()`
calls to the very top of `hci_uart_tty_close()`, before `hci_uart_close()` 
or any other teardown logic begins. This will completely choke off any 
asynchronous operations before we touch the connection state or hardware.

I will update the patch and send out v5 immediately.

>
>https://sashiko.dev/#/patchset/20260515140548.393865-1-w15303746062%40163.com
>
>>         if (test_bit(HCI_UART_PROTO_READY, &hu->flags)) {
>>                 percpu_down_write(&hu->proto_lock);
>>                 clear_bit(HCI_UART_PROTO_READY, &hu->flags);
>>                 percpu_up_write(&hu->proto_lock);
>>
>> -               cancel_work_sync(&hu->init_ready);
>> -               cancel_work_sync(&hu->write_work);
>> -
>>                 if (hdev) {
>>                         if (test_bit(HCI_UART_REGISTERED, &hu->flags))
>>                                 hci_unregister_dev(hdev);
>> --
>> 2.34.1
>>
>
>
>-- 
>Luiz Augusto von Dentz

Best regards,
Mingyu

  reply	other threads:[~2026-05-16  1:41 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <CABBYNZLjreYY_BczAQr2G6L=iJjBYKksFp53CairG-6V0Cb0EA@mail.gmail.com>
2026-05-15 14:05 ` [PATCH v4] Bluetooth: hci_uart: fix UAF in hci_uart_tty_close() w15303746062
2026-05-15 16:08   ` Luiz Augusto von Dentz
2026-05-16  1:41     ` w15303746062 [this message]
2026-05-16  2:22     ` [PATCH v5] " w15303746062
2026-05-16  5:30     ` [PATCH v6] Bluetooth: hci_uart: fix UAFs and race conditions in close and init paths w15303746062
2026-05-16  8:47     ` [PATCH v7] " w15303746062

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=485d0dd5.660.19e2e71ed1e.Coremail.w15303746062@163.com \
    --to=w15303746062@163.com \
    --cc=25181214217@stu.xidian.edu.cn \
    --cc=greg@kroah.com \
    --cc=linux-bluetooth@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-serial@vger.kernel.org \
    --cc=luiz.dentz@gmail.com \
    --cc=marcel@holtmann.org \
    --cc=pmenzel@molgen.mpg.de \
    --cc=stable@vger.kernel.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox