* [PATCH] Bluetooth: Reject controller operations while powering down
@ 2026-08-31 8:43 zhangchen200426
2026-08-31 12:45 ` bluez.test.bot
2026-08-31 15:54 ` [PATCH] " Luiz Augusto von Dentz
0 siblings, 2 replies; 5+ messages in thread
From: zhangchen200426 @ 2026-08-31 8:43 UTC (permalink / raw)
To: luiz.von.dentz, pav; +Cc: linux-bluetooth, Chen Zhang
From: Chen Zhang <zhangchen01@kylinos.cn>
When an adapter is powered off with devices still connected (e.g. a
Bluetooth keyboard or mouse), the shutdown sequence issues an HCI reset
which returns Command Complete while the controller firmware is still
rebooting. A concurrent command sent through a raw socket during this
window (e.g. periodic hciconfig queries triggered by the Bluetooth
status change) can leave the firmware in a stuck state where it stops
answering any HCI command. The subsequent power on then fails with
'Bluetooth: hci0: Opcode 0x0c03 failed: -110' and the adapter is lost
until reboot or re-enumeration.
Reject controller operations while HCI_POWERING_DOWN is set at the
public entry points in hci_core.c, which covers the ioctl (HCIDEVUP,
HCIDEVDOWN, HCIDEVRESET) and raw socket bind paths:
- hci_dev_open(): return -EBUSY
- hci_dev_close(): return -EBUSY
- hci_dev_reset(): return -EBUSY
In addition reject raw command transmission from an already bound
socket during the power down sequence in hci_sock_sendmsg()
(-ENETDOWN), and fail early in hci_sock_bind() (-EBUSY) to avoid
toggling HCI_USER_CHANNEL while powering down.
Signed-off-by: Chen Zhang <zhangchen01@kylinos.cn>
---
net/bluetooth/hci_core.c | 28 ++++++++++++++++++++++++++++
net/bluetooth/hci_sock.c | 4 +++-
2 files changed, 31 insertions(+), 1 deletion(-)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index d1e78ae7728e..a0533f260471 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -445,6 +445,16 @@ int hci_dev_open(__u16 dev)
if (!hdev)
return -ENODEV;
+ /* Reject opening the controller while it is being powered down:
+ * the firmware is rebooting after the shutdown reset and any
+ * concurrent command sent during this window can leave it in a
+ * stuck state where it stops answering HCI commands.
+ */
+ if (hci_dev_test_flag(hdev, HCI_POWERING_DOWN)) {
+ err = -EBUSY;
+ goto done;
+ }
+
/* Devices that are marked as unconfigured can only be powered
* up as user channel. Trying to bring them up as normal devices
* will result into a failure. Only user channel operation is
@@ -515,6 +525,14 @@ int hci_dev_close(__u16 dev)
if (!hdev)
return -ENODEV;
+ /* Reject closing the controller while the power off sequence
+ * is already in progress (see hci_dev_open for details).
+ */
+ if (hci_dev_test_flag(hdev, HCI_POWERING_DOWN)) {
+ err = -EBUSY;
+ goto done;
+ }
+
if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
err = -EBUSY;
goto done;
@@ -556,6 +574,16 @@ int hci_dev_reset(__u16 dev)
if (!hdev)
return -ENODEV;
+ /* Reject resetting the controller while the power off sequence
+ * is in progress: the shutdown routine already issues its own
+ * HCI reset and a concurrent one would hit the firmware while
+ * it is rebooting (see hci_dev_open for details).
+ */
+ if (hci_dev_test_flag(hdev, HCI_POWERING_DOWN)) {
+ err = -EBUSY;
+ goto done;
+ }
+
if (!test_bit(HCI_UP, &hdev->flags)) {
err = -ENETDOWN;
goto done;
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 070ca388f9ac..897596614939 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -1296,6 +1296,7 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr_unsized *addr,
if (test_bit(HCI_INIT, &hdev->flags) ||
hci_dev_test_flag(hdev, HCI_SETUP) ||
hci_dev_test_flag(hdev, HCI_CONFIG) ||
+ hci_dev_test_flag(hdev, HCI_POWERING_DOWN) ||
(!hci_dev_test_flag(hdev, HCI_AUTO_OFF) &&
test_bit(HCI_UP, &hdev->flags))) {
err = -EBUSY;
@@ -1850,7 +1851,8 @@ static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg,
goto drop;
}
- if (!test_bit(HCI_UP, &hdev->flags)) {
+ if (!test_bit(HCI_UP, &hdev->flags) ||
+ hci_dev_test_flag(hdev, HCI_POWERING_DOWN)) {
err = -ENETDOWN;
goto drop;
}
--
2.25.1
^ permalink raw reply related [flat|nested] 5+ messages in thread* RE: Bluetooth: Reject controller operations while powering down
2026-08-31 8:43 [PATCH] Bluetooth: Reject controller operations while powering down zhangchen200426
@ 2026-08-31 12:45 ` bluez.test.bot
2026-08-31 15:54 ` [PATCH] " Luiz Augusto von Dentz
1 sibling, 0 replies; 5+ messages in thread
From: bluez.test.bot @ 2026-08-31 12:45 UTC (permalink / raw)
To: linux-bluetooth, zhangchen200426
[-- Attachment #1: Type: text/plain, Size: 2390 bytes --]
This is automated email and please do not reply to this email!
Dear submitter,
Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1154312
---Test result---
Test Summary:
CheckPatch PASS 0.80 seconds
VerifyFixes PASS 0.09 seconds
VerifySignedoff PASS 0.09 seconds
GitLint PASS 0.25 seconds
SubjectPrefix PASS 0.09 seconds
BuildKernel PASS 27.35 seconds
CheckAllWarning PASS 29.76 seconds
CheckSparse PASS 28.43 seconds
BuildKernel32 PASS 25.98 seconds
CheckKernelLLVM SKIP 0.00 seconds
TestRunnerSetup PASS 471.29 seconds
TestRunner_l2cap-tester PASS 67.65 seconds
TestRunner_iso-tester PASS 110.72 seconds
TestRunner_bnep-tester PASS 19.25 seconds
TestRunner_mgmt-tester FAIL 236.77 seconds
TestRunner_rfcomm-tester PASS 26.49 seconds
TestRunner_sco-tester PASS 32.93 seconds
TestRunner_ioctl-tester PASS 27.16 seconds
TestRunner_mesh-tester FAIL 27.28 seconds
TestRunner_smp-tester PASS 23.79 seconds
TestRunner_userchan-tester PASS 20.44 seconds
TestRunner_6lowpan-tester PASS 23.18 seconds
IncrementalBuild PASS 23.60 seconds
Details
##############################
Test: CheckKernelLLVM - SKIP
Desc: Build kernel with LLVM + context analysis
Output:
Clang not found
##############################
Test: TestRunner_mgmt-tester - FAIL
Desc: Run mgmt-tester with test-runner
Output:
Total: 501, Passed: 496 (99.0%), Failed: 1, Not Run: 4
Failed Test Cases
Read Exp Feature - Success Failed 0.266 seconds
##############################
Test: TestRunner_mesh-tester - FAIL
Desc: Run mesh-tester with test-runner
Output:
Total: 10, Passed: 8 (80.0%), Failed: 2, Not Run: 0
Failed Test Cases
Mesh - Send cancel - 1 Timed out 2.768 seconds
Mesh - Send cancel - 2 Timed out 1.975 seconds
https://github.com/bluez/bluetooth-next/pull/671
---
Regards,
Linux Bluetooth
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] Bluetooth: Reject controller operations while powering down
2026-08-31 8:43 [PATCH] Bluetooth: Reject controller operations while powering down zhangchen200426
2026-08-31 12:45 ` bluez.test.bot
@ 2026-08-31 15:54 ` Luiz Augusto von Dentz
2026-09-01 2:00 ` [PATCH v2] Bluetooth: hci_sock: Reject raw " zhangchen200426
1 sibling, 1 reply; 5+ messages in thread
From: Luiz Augusto von Dentz @ 2026-08-31 15:54 UTC (permalink / raw)
To: zhangchen200426; +Cc: luiz.von.dentz, pav, linux-bluetooth, Chen Zhang
Hi,
On Mon, Aug 31, 2026 at 4:57 AM <zhangchen200426@163.com> wrote:
>
> From: Chen Zhang <zhangchen01@kylinos.cn>
>
> When an adapter is powered off with devices still connected (e.g. a
> Bluetooth keyboard or mouse), the shutdown sequence issues an HCI reset
> which returns Command Complete while the controller firmware is still
> rebooting. A concurrent command sent through a raw socket during this
> window (e.g. periodic hciconfig queries triggered by the Bluetooth
> status change) can leave the firmware in a stuck state where it stops
> answering any HCI command. The subsequent power on then fails with
> 'Bluetooth: hci0: Opcode 0x0c03 failed: -110' and the adapter is lost
> until reboot or re-enumeration.
>
> Reject controller operations while HCI_POWERING_DOWN is set at the
> public entry points in hci_core.c, which covers the ioctl (HCIDEVUP,
> HCIDEVDOWN, HCIDEVRESET) and raw socket bind paths:
> - hci_dev_open(): return -EBUSY
> - hci_dev_close(): return -EBUSY
> - hci_dev_reset(): return -EBUSY
>
> In addition reject raw command transmission from an already bound
> socket during the power down sequence in hci_sock_sendmsg()
> (-ENETDOWN), and fail early in hci_sock_bind() (-EBUSY) to avoid
> toggling HCI_USER_CHANNEL while powering down.
>
> Signed-off-by: Chen Zhang <zhangchen01@kylinos.cn>
> ---
> net/bluetooth/hci_core.c | 28 ++++++++++++++++++++++++++++
> net/bluetooth/hci_sock.c | 4 +++-
> 2 files changed, 31 insertions(+), 1 deletion(-)
>
> diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
> index d1e78ae7728e..a0533f260471 100644
> --- a/net/bluetooth/hci_core.c
> +++ b/net/bluetooth/hci_core.c
> @@ -445,6 +445,16 @@ int hci_dev_open(__u16 dev)
> if (!hdev)
> return -ENODEV;
>
> + /* Reject opening the controller while it is being powered down:
> + * the firmware is rebooting after the shutdown reset and any
> + * concurrent command sent during this window can leave it in a
> + * stuck state where it stops answering HCI commands.
> + */
> + if (hci_dev_test_flag(hdev, HCI_POWERING_DOWN)) {
> + err = -EBUSY;
> + goto done;
> + }
> +
> /* Devices that are marked as unconfigured can only be powered
> * up as user channel. Trying to bring them up as normal devices
> * will result into a failure. Only user channel operation is
> @@ -515,6 +525,14 @@ int hci_dev_close(__u16 dev)
> if (!hdev)
> return -ENODEV;
>
> + /* Reject closing the controller while the power off sequence
> + * is already in progress (see hci_dev_open for details).
> + */
> + if (hci_dev_test_flag(hdev, HCI_POWERING_DOWN)) {
> + err = -EBUSY;
> + goto done;
> + }
> +
> if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
> err = -EBUSY;
> goto done;
> @@ -556,6 +574,16 @@ int hci_dev_reset(__u16 dev)
> if (!hdev)
> return -ENODEV;
>
> + /* Reject resetting the controller while the power off sequence
> + * is in progress: the shutdown routine already issues its own
> + * HCI reset and a concurrent one would hit the firmware while
> + * it is rebooting (see hci_dev_open for details).
> + */
> + if (hci_dev_test_flag(hdev, HCI_POWERING_DOWN)) {
> + err = -EBUSY;
> + goto done;
> + }
> +
> if (!test_bit(HCI_UP, &hdev->flags)) {
> err = -ENETDOWN;
> goto done;
> diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
> index 070ca388f9ac..897596614939 100644
> --- a/net/bluetooth/hci_sock.c
> +++ b/net/bluetooth/hci_sock.c
> @@ -1296,6 +1296,7 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr_unsized *addr,
> if (test_bit(HCI_INIT, &hdev->flags) ||
> hci_dev_test_flag(hdev, HCI_SETUP) ||
> hci_dev_test_flag(hdev, HCI_CONFIG) ||
> + hci_dev_test_flag(hdev, HCI_POWERING_DOWN) ||
> (!hci_dev_test_flag(hdev, HCI_AUTO_OFF) &&
> test_bit(HCI_UP, &hdev->flags))) {
> err = -EBUSY;
> @@ -1850,7 +1851,8 @@ static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg,
> goto drop;
> }
>
> - if (!test_bit(HCI_UP, &hdev->flags)) {
> + if (!test_bit(HCI_UP, &hdev->flags) ||
> + hci_dev_test_flag(hdev, HCI_POWERING_DOWN)) {
> err = -ENETDOWN;
> goto drop;
> }
> --
> 2.25.1
Sashiko found quite a few problems:
https://sashiko.dev/#/patchset/20260831084329.3141802-1-zhangchen200426%40163.com
The fact that a lock already serializes these operations probably
means we should either check HCI_POWERING_DOWN or we do it after the
lock, but if after the lock acquisition the HCI_POWERING_DOWN it
probably means someone is powering the controller down without
properly locking it meaning this would be more of a workaround.
--
Luiz Augusto von Dentz
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH v2] Bluetooth: hci_sock: Reject raw operations while powering down
2026-08-31 15:54 ` [PATCH] " Luiz Augusto von Dentz
@ 2026-09-01 2:00 ` zhangchen200426
2026-09-01 7:27 ` [v2] " bluez.test.bot
0 siblings, 1 reply; 5+ messages in thread
From: zhangchen200426 @ 2026-09-01 2:00 UTC (permalink / raw)
To: luiz.dentz
Cc: linux-bluetooth, luiz.von.dentz, pav, zhangchen01,
zhangchen200426
From: Chen Zhang <zhangchen01@kylinos.cn>
When an adapter is powered off with devices still connected, the
shutdown sequence issues an HCI reset which returns Command Complete
while the controller firmware is still rebooting. A command sent
concurrently through a raw socket during this window (e.g. hciconfig
queries triggered by the Bluetooth status change) can leave the
firmware in a stuck state where it stops answering any HCI command.
The subsequent power on then fails with 'Opcode 0x0c03 failed: -110'
and the adapter is lost until reboot or re-enumeration.
Unlike the ioctl paths (HCIDEVUP/HCIDEVDOWN/HCIDEVRESET) which are
already serialized by hci_req_sync_lock against the power off
sequence, raw socket command transmission goes directly to the
transport through hdev->send() without taking the lock, so it has to
be rejected explicitly:
- hci_sock_sendmsg(): reject with -ENETDOWN while HCI_POWERING_DOWN
is set, extending the existing HCI_UP check
- hci_sock_bind(): fail early with -EBUSY while HCI_POWERING_DOWN is
set, avoiding HCI_USER_CHANNEL to be toggled (and the controller
to be opened as user channel) right after power off
Changes in v2:
- Drop the HCI_POWERING_DOWN checks in hci_dev_open()/hci_dev_close()/
hci_dev_reset() (hci_core.c): those paths are already serialized by
hci_req_sync_lock against the power off sequence, checking the flag
outside the lock is redundant (as pointed out in review).
Signed-off-by: Chen Zhang <zhangchen01@kylinos.cn>
---
net/bluetooth/hci_sock.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 070ca388f9ac..897596614939 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -1296,6 +1296,7 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr_unsized *addr,
if (test_bit(HCI_INIT, &hdev->flags) ||
hci_dev_test_flag(hdev, HCI_SETUP) ||
hci_dev_test_flag(hdev, HCI_CONFIG) ||
+ hci_dev_test_flag(hdev, HCI_POWERING_DOWN) ||
(!hci_dev_test_flag(hdev, HCI_AUTO_OFF) &&
test_bit(HCI_UP, &hdev->flags))) {
err = -EBUSY;
@@ -1850,7 +1851,8 @@ static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg,
goto drop;
}
- if (!test_bit(HCI_UP, &hdev->flags)) {
+ if (!test_bit(HCI_UP, &hdev->flags) ||
+ hci_dev_test_flag(hdev, HCI_POWERING_DOWN)) {
err = -ENETDOWN;
goto drop;
}
--
2.25.1
^ permalink raw reply related [flat|nested] 5+ messages in thread* RE: [v2] Bluetooth: hci_sock: Reject raw operations while powering down
2026-09-01 2:00 ` [PATCH v2] Bluetooth: hci_sock: Reject raw " zhangchen200426
@ 2026-09-01 7:27 ` bluez.test.bot
0 siblings, 0 replies; 5+ messages in thread
From: bluez.test.bot @ 2026-09-01 7:27 UTC (permalink / raw)
To: linux-bluetooth, zhangchen200426
[-- Attachment #1: Type: text/plain, Size: 2390 bytes --]
This is automated email and please do not reply to this email!
Dear submitter,
Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1154959
---Test result---
Test Summary:
CheckPatch PASS 0.74 seconds
VerifyFixes PASS 0.14 seconds
VerifySignedoff PASS 0.14 seconds
GitLint PASS 0.63 seconds
SubjectPrefix PASS 0.13 seconds
BuildKernel PASS 27.28 seconds
CheckAllWarning PASS 30.17 seconds
CheckSparse PASS 28.98 seconds
BuildKernel32 PASS 26.49 seconds
CheckKernelLLVM SKIP 0.00 seconds
TestRunnerSetup PASS 505.16 seconds
TestRunner_l2cap-tester PASS 67.03 seconds
TestRunner_iso-tester PASS 100.00 seconds
TestRunner_bnep-tester PASS 19.22 seconds
TestRunner_mgmt-tester FAIL 218.35 seconds
TestRunner_rfcomm-tester PASS 26.08 seconds
TestRunner_sco-tester PASS 31.77 seconds
TestRunner_ioctl-tester PASS 27.17 seconds
TestRunner_mesh-tester FAIL 26.19 seconds
TestRunner_smp-tester PASS 23.48 seconds
TestRunner_userchan-tester PASS 20.25 seconds
TestRunner_6lowpan-tester PASS 23.50 seconds
IncrementalBuild PASS 25.58 seconds
Details
##############################
Test: CheckKernelLLVM - SKIP
Desc: Build kernel with LLVM + context analysis
Output:
Clang not found
##############################
Test: TestRunner_mgmt-tester - FAIL
Desc: Run mgmt-tester with test-runner
Output:
Total: 501, Passed: 496 (99.0%), Failed: 1, Not Run: 4
Failed Test Cases
Read Exp Feature - Success Failed 0.240 seconds
##############################
Test: TestRunner_mesh-tester - FAIL
Desc: Run mesh-tester with test-runner
Output:
Total: 10, Passed: 8 (80.0%), Failed: 2, Not Run: 0
Failed Test Cases
Mesh - Send cancel - 1 Timed out 2.524 seconds
Mesh - Send cancel - 2 Timed out 1.988 seconds
https://github.com/bluez/bluetooth-next/pull/677
---
Regards,
Linux Bluetooth
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-09-01 7:27 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-31 8:43 [PATCH] Bluetooth: Reject controller operations while powering down zhangchen200426
2026-08-31 12:45 ` bluez.test.bot
2026-08-31 15:54 ` [PATCH] " Luiz Augusto von Dentz
2026-09-01 2:00 ` [PATCH v2] Bluetooth: hci_sock: Reject raw " zhangchen200426
2026-09-01 7:27 ` [v2] " bluez.test.bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox