Linux bluetooth development
 help / color / mirror / Atom feed
* [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