Linux bluetooth development
 help / color / mirror / Atom feed
* Re: [PATCH BlueZ v1 1/2] monitor: Add features bits defined in 6.2
From: patchwork-bot+bluetooth @ 2026-05-06 13:30 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <20260504211303.1081876-1-luiz.dentz@gmail.com>

Hello:

This series was applied to bluetooth/bluez.git (master)
by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>:

On Mon,  4 May 2026 17:13:01 -0400 you wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
> 
> This adds features bits defined as per core spec 6.2:
> https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-62/out/en/low-energy-controller/link-layer-specification.html#UUID-56ada5ed-4ae3-acee-198f-27ead57d86f1
> ---
>  monitor/packet.c | 7 +++++++
>  1 file changed, 7 insertions(+)

Here is the summary with links:
  - [BlueZ,v1,1/2] monitor: Add features bits defined in 6.2
    https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=fda84f7004fa
  - [BlueZ,v1,2/2] monitor: Add decoding for Short Connection Interval feature
    https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=79cfd07224ff

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply

* Re: [PATCH BlueZ v1] hciemu: Fix crash if hciemu_client_new return NULL
From: patchwork-bot+bluetooth @ 2026-05-06 13:30 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <20260505201548.1328953-1-luiz.dentz@gmail.com>

Hello:

This patch was applied to bluetooth/bluez.git (master)
by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>:

On Tue,  5 May 2026 16:15:48 -0400 you wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
> 
> The following crahs can be observed if hciemu_client_new fails:
> 
>  Invalid read of size 8
>    at 0x12DA79: queue_get_entries (queue.c:356)
>    by 0x118434: hciemu_get_client (hciemu.c:277)
>    by 0x1184A3: hciemu_client_get_host (hciemu.c:301)
>    by 0x11536B: setup_powered_common (l2cap-tester.c:1452)
>    by 0x11568E: setup_powered_client (l2cap-tester.c:1491)
>    by 0x1324C6: setup_callback (tester.c:500)
>    by 0x48A304D: g_main_context_dispatch (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
>    by 0x48A33FF: ??? (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
>    by 0x48A36F2: g_main_loop_run (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
>    by 0x133868: mainloop_run (mainloop-glib.c:65)
>    by 0x133C9F: mainloop_run_with_signal (mainloop-notify.c:196)
>    by 0x13325F: tester_run (tester.c:1085)
>   Address 0x4c1e388 is 8 bytes inside a block of size 32 free'd
>    at 0x483CA3F: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
>    by 0x1187BF: hciemu_new_num (hciemu.c:437)
> 
> [...]

Here is the summary with links:
  - [BlueZ,v1] hciemu: Fix crash if hciemu_client_new return NULL
    https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=6aa7f5b4e022

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply

* RE: [v4] Bluetooth: serialize accept_q access
From: bluez.test.bot @ 2026-05-06 13:56 UTC (permalink / raw)
  To: linux-bluetooth, n05ec
In-Reply-To: <20260506114338.2873496-1-n05ec@lzu.edu.cn>

[-- Attachment #1: Type: text/plain, Size: 15960 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=1090423

---Test result---

Test Summary:
CheckPatch                    FAIL      1.02 seconds
GitLint                       FAIL      0.36 seconds
SubjectPrefix                 PASS      2.06 seconds
BuildKernel                   PASS      27.34 seconds
CheckAllWarning               PASS      30.36 seconds
CheckSparse                   PASS      30.05 seconds
BuildKernel32                 PASS      26.21 seconds
TestRunnerSetup               PASS      579.19 seconds
TestRunner_l2cap-tester       FAIL      19.18 seconds
TestRunner_iso-tester         PASS      311.73 seconds
TestRunner_bnep-tester        FAIL      18.56 seconds
TestRunner_mgmt-tester        FAIL      23.55 seconds
TestRunner_rfcomm-tester      PASS      41.44 seconds
TestRunner_sco-tester         PASS      80.71 seconds
TestRunner_ioctl-tester       FAIL      50.29 seconds
TestRunner_mesh-tester        PASS      39.76 seconds
TestRunner_smp-tester         PASS      18.82 seconds
TestRunner_userchan-tester    PASS      20.32 seconds
TestRunner_6lowpan-tester     PASS      35.31 seconds
IncrementalBuild              PASS      25.46 seconds

Details
##############################
Test: CheckPatch - FAIL
Desc: Run checkpatch.pl script
Output:
[v4] Bluetooth: serialize accept_q access
WARNING: Reported-by: should be immediately followed by Closes: with a URL to the report
#91: 
Reported-by: Jann Horn <jannh@google.com>
Reported-by: Yuan Tan <yuantan098@gmail.com>

WARNING: Reported-by: should be immediately followed by Closes: with a URL to the report
#92: 
Reported-by: Yuan Tan <yuantan098@gmail.com>
Reported-by: Yifan Wu <yifanwucs@gmail.com>

WARNING: Reported-by: should be immediately followed by Closes: with a URL to the report
#93: 
Reported-by: Yifan Wu <yifanwucs@gmail.com>
Reported-by: Juefei Pu <tomapufckgml@gmail.com>

WARNING: Reported-by: should be immediately followed by Closes: with a URL to the report
#94: 
Reported-by: Juefei Pu <tomapufckgml@gmail.com>
Reported-by: Xin Liu <bird@lzu.edu.cn>

WARNING: Reported-by: should be immediately followed by Closes: with a URL to the report
#95: 
Reported-by: Xin Liu <bird@lzu.edu.cn>
Signed-off-by: Jiexun Wang <wangjiexun2025@gmail.com>

total: 0 errors, 5 warnings, 0 checks, 170 lines checked

NOTE: For some of the reported defects, checkpatch may be able to
      mechanically convert to the typical style using --fix or --fix-inplace.

/github/workspace/src/patch/14557166.patch has style problems, please review.

NOTE: Ignored message types: UNKNOWN_COMMIT_ID

NOTE: If any of the errors are false positives, please report
      them to the maintainer, see CHECKPATCH in MAINTAINERS.


##############################
Test: GitLint - FAIL
Desc: Run gitlint
Output:
[v4] Bluetooth: serialize accept_q access

WARNING: I3 - ignore-body-lines: gitlint will be switching from using Python regex 'match' (match beginning) to 'search' (match anywhere) semantics. Please review your ignore-body-lines.regex option accordingly. To remove this warning, set general.regex-style-search=True. More details: https://jorisroovers.github.io/gitlint/configuration/#regex-style-search
28: B1 Line exceeds max length (119>80): "  https://patchwork.kernel.org/project/bluetooth/patch/20260504-bluetooth-accept-uaf-fix-v1-1-1ca63c0efadd@google.com/,"
31: B1 Line exceeds max length (81>80): "- v3 Link: https://lore.kernel.org/all/20260404162324.2789862-1-n05ec@lzu.edu.cn/"
37: B1 Line exceeds max length (120>80): "- v2 Link: https://lore.kernel.org/all/06a6b4549acba207847ce532dedbf1c95ab22d13.1774925231.git.wangjiexun2025@gmail.com/"
##############################
Test: TestRunner_l2cap-tester - FAIL
Desc: Run l2cap-tester with test-runner
Output:
Crash detected:
==34==    by 0x13325F: tester_run (tester.c:1085)
==34==    by 0x1142AD: main (l2cap-tester.c:3295)
==34==  Address 0x50 is not stack'd, malloc'd or (recently) free'd
==34== 
==34== 
==34== Process terminating with default action of signal 11 (SIGSEGV)
==34==  Access not within mapped region at address 0x50
==34==    at 0x12BE24: bthost_set_cmd_complete_cb (bthost.c:3487)
==34==    by 0x11596D: setup_powered_client_callback (l2cap-tester.c:1317)
==34==    by 0x12E5B0: request_complete (mgmt.c:320)
==34==    by 0x12F045: can_read_data (mgmt.c:408)
==34==    by 0x131AB8: watch_callback (io-glib.c:173)
==34==    by 0x48A304D: g_main_context_dispatch (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==34==    by 0x48A33FF: ??? (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==34==    by 0x48A36F2: g_main_loop_run (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==34==    by 0x133868: mainloop_run (mainloop-glib.c:65)
==34==    by 0x133C9F: mainloop_run_with_signal (mainloop-notify.c:196)
==34==    by 0x13325F: tester_run (tester.c:1085)
==34==    by 0x1142AD: main (l2cap-tester.c:3295)
==34==  If you believe this happened as a result of a stack
==34==  overflow in your program's main thread (unlikely but
==34==  possible), you can try to increase the size of the
==34==  main thread stack using the --main-stacksize= flag.
==34==  The main thread stack size used in this run was 8388608.
==34== 
Valgrind errors:
==34==    by 0x11596D: setup_powered_client_callback (l2cap-tester.c:1317)
==34==    by 0x12E5B0: request_complete (mgmt.c:320)
==34==    by 0x12F045: can_read_data (mgmt.c:408)
==34==    by 0x131AB8: watch_callback (io-glib.c:173)
==34==    by 0x48A304D: g_main_context_dispatch (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==34==    by 0x48A33FF: ??? (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==34==    by 0x48A36F2: g_main_loop_run (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==34==    by 0x133868: mainloop_run (mainloop-glib.c:65)
==34==    by 0x133C9F: mainloop_run_with_signal (mainloop-notify.c:196)
==34==    by 0x13325F: tester_run (tester.c:1085)
==34==    by 0x1142AD: main (l2cap-tester.c:3295)
==34==  If you believe this happened as a result of a stack
==34==  overflow in your program's main thread (unlikely but
==34==  possible), you can try to increase the size of the
==34==  main thread stack using the --main-stacksize= flag.
==34==  The main thread stack size used in this run was 8388608.
==34== 
==34== HEAP SUMMARY:
==34==     in use at exit: 66,134 bytes in 464 blocks
==34==   total heap usage: 632 allocs, 168 frees, 80,436 bytes allocated
==34== 
==34== LEAK SUMMARY:
==34==    definitely lost: 0 bytes in 0 blocks
==34==    indirectly lost: 0 bytes in 0 blocks
==34==      possibly lost: 0 bytes in 0 blocks
==34==    still reachable: 66,134 bytes in 464 blocks
==34==         suppressed: 0 bytes in 0 blocks
==34== Rerun with --leak-check=full to see details of leaked memory
==34== 
==34== For lists of detected and suppressed errors, rerun with: -s
==34== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)
Crash detected:
==34==         suppressed: 0 bytes in 0 blocks
==34== Rerun with --leak-check=full to see details of leaked memory
==34== 
==34== For lists of detected and suppressed errors, rerun with: -s
==34== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)
Segmentation fault
Process 33 exited with status 139
reboot: Restarting system
reboot: machine restart
No test result found
##############################
Test: TestRunner_bnep-tester - FAIL
Desc: Run bnep-tester with test-runner
Output:
Crash detected:
==33==    by 0x12C99F: tester_run (tester.c:1085)
==33==    by 0x111CB3: main (bnep-tester.c:298)
==33==  Address 0x50 is not stack'd, malloc'd or (recently) free'd
==33== 
==33== 
==33== Process terminating with default action of signal 11 (SIGSEGV)
==33==  Access not within mapped region at address 0x50
==33==    at 0x125C44: bthost_set_cmd_complete_cb (bthost.c:3487)
==33==    by 0x111F42: setup_powered_client_callback (bnep-tester.c:244)
==33==    by 0x127F00: request_complete (mgmt.c:320)
==33==    by 0x1288B5: can_read_data (mgmt.c:408)
==33==    by 0x12B328: watch_callback (io-glib.c:173)
==33==    by 0x48A304D: g_main_context_dispatch (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==33==    by 0x48A33FF: ??? (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==33==    by 0x48A36F2: g_main_loop_run (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==33==    by 0x12CFA8: mainloop_run (mainloop-glib.c:65)
==33==    by 0x12D3DF: mainloop_run_with_signal (mainloop-notify.c:196)
==33==    by 0x12C99F: tester_run (tester.c:1085)
==33==    by 0x111CB3: main (bnep-tester.c:298)
==33==  If you believe this happened as a result of a stack
==33==  overflow in your program's main thread (unlikely but
==33==  possible), you can try to increase the size of the
==33==  main thread stack using the --main-stacksize= flag.
==33==  The main thread stack size used in this run was 8388608.
==33== 
Valgrind errors:
==33==    by 0x111F42: setup_powered_client_callback (bnep-tester.c:244)
==33==    by 0x127F00: request_complete (mgmt.c:320)
==33==    by 0x1288B5: can_read_data (mgmt.c:408)
==33==    by 0x12B328: watch_callback (io-glib.c:173)
==33==    by 0x48A304D: g_main_context_dispatch (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==33==    by 0x48A33FF: ??? (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==33==    by 0x48A36F2: g_main_loop_run (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==33==    by 0x12CFA8: mainloop_run (mainloop-glib.c:65)
==33==    by 0x12D3DF: mainloop_run_with_signal (mainloop-notify.c:196)
==33==    by 0x12C99F: tester_run (tester.c:1085)
==33==    by 0x111CB3: main (bnep-tester.c:298)
==33==  If you believe this happened as a result of a stack
==33==  overflow in your program's main thread (unlikely but
==33==  possible), you can try to increase the size of the
==33==  main thread stack using the --main-stacksize= flag.
==33==  The main thread stack size used in this run was 8388608.
==33== 
==33== HEAP SUMMARY:
==33==     in use at exit: 25,333 bytes in 82 blocks
==33==   total heap usage: 237 allocs, 155 frees, 39,167 bytes allocated
==33== 
==33== LEAK SUMMARY:
==33==    definitely lost: 0 bytes in 0 blocks
==33==    indirectly lost: 0 bytes in 0 blocks
==33==      possibly lost: 0 bytes in 0 blocks
==33==    still reachable: 25,333 bytes in 82 blocks
==33==         suppressed: 0 bytes in 0 blocks
==33== Rerun with --leak-check=full to see details of leaked memory
==33== 
==33== For lists of detected and suppressed errors, rerun with: -s
==33== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Crash detected:
==33==         suppressed: 0 bytes in 0 blocks
==33== Rerun with --leak-check=full to see details of leaked memory
==33== 
==33== For lists of detected and suppressed errors, rerun with: -s
==33== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Segmentation fault
Process 32 exited with status 139
reboot: Restarting system
reboot: machine restart
No test result found
##############################
Test: TestRunner_mgmt-tester - FAIL
Desc: Run mgmt-tester with test-runner
Output:
Crash detected:
==34==    by 0x14F1DF: tester_run (tester.c:1085)
==34==    by 0x12B999: main (mgmt-tester.c:15134)
==34==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==34== 
==34== 
==34== Process terminating with default action of signal 11 (SIGSEGV)
==34==  Access not within mapped region at address 0x0
==34==    at 0x145134: bthost_notify_ready (bthost.c:1190)
==34==    by 0x12FA10: read_info_callback (mgmt-tester.c:223)
==34==    by 0x14A420: request_complete (mgmt.c:320)
==34==    by 0x14AFD5: can_read_data (mgmt.c:408)
==34==    by 0x14DA48: watch_callback (io-glib.c:173)
==34==    by 0x48A304D: g_main_context_dispatch (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==34==    by 0x48A33FF: ??? (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==34==    by 0x48A36F2: g_main_loop_run (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==34==    by 0x14F7E8: mainloop_run (mainloop-glib.c:65)
==34==    by 0x14FC1F: mainloop_run_with_signal (mainloop-notify.c:196)
==34==    by 0x14F1DF: tester_run (tester.c:1085)
==34==    by 0x12B999: main (mgmt-tester.c:15134)
==34==  If you believe this happened as a result of a stack
==34==  overflow in your program's main thread (unlikely but
==34==  possible), you can try to increase the size of the
==34==  main thread stack using the --main-stacksize= flag.
==34==  The main thread stack size used in this run was 8388608.
==34== 
Valgrind errors:
==34==    by 0x12FA10: read_info_callback (mgmt-tester.c:223)
==34==    by 0x14A420: request_complete (mgmt.c:320)
==34==    by 0x14AFD5: can_read_data (mgmt.c:408)
==34==    by 0x14DA48: watch_callback (io-glib.c:173)
==34==    by 0x48A304D: g_main_context_dispatch (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==34==    by 0x48A33FF: ??? (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==34==    by 0x48A36F2: g_main_loop_run (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==34==    by 0x14F7E8: mainloop_run (mainloop-glib.c:65)
==34==    by 0x14FC1F: mainloop_run_with_signal (mainloop-notify.c:196)
==34==    by 0x14F1DF: tester_run (tester.c:1085)
==34==    by 0x12B999: main (mgmt-tester.c:15134)
==34==  If you believe this happened as a result of a stack
==34==  overflow in your program's main thread (unlikely but
==34==  possible), you can try to increase the size of the
==34==  main thread stack using the --main-stacksize= flag.
==34==  The main thread stack size used in this run was 8388608.
==34== 
==34== HEAP SUMMARY:
==34==     in use at exit: 182,331 bytes in 2,112 blocks
==34==   total heap usage: 2,379 allocs, 267 frees, 204,063 bytes allocated
==34== 
==34== LEAK SUMMARY:
==34==    definitely lost: 0 bytes in 0 blocks
==34==    indirectly lost: 0 bytes in 0 blocks
==34==      possibly lost: 0 bytes in 0 blocks
==34==    still reachable: 182,331 bytes in 2,112 blocks
==34==         suppressed: 0 bytes in 0 blocks
==34== Rerun with --leak-check=full to see details of leaked memory
==34== 
==34== For lists of detected and suppressed errors, rerun with: -s
==34== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Crash detected:
==34==         suppressed: 0 bytes in 0 blocks
==34== Rerun with --leak-check=full to see details of leaked memory
==34== 
==34== For lists of detected and suppressed errors, rerun with: -s
==34== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Segmentation fault
Process 33 exited with status 139
reboot: Restarting system
reboot: machine restart
No test result found
##############################
Test: TestRunner_ioctl-tester - FAIL
Desc: Run ioctl-tester with test-runner
Output:
Total: 28, Passed: 0 (0.0%), Failed: 11, Not Run: 17

Failed Test Cases
Device List                                          Timed out  -31.835 seconds
Device Info                                          Timed out   -6.933 seconds
Reset Stat                                           Timed out   -6.940 seconds
Set Link Mode - ACCEPT                               Timed out   -6.946 seconds
Set Pkt Type - DM                                    Timed out  -15.222 seconds
Set Pkt Type - DH                                    Timed out  -15.230 seconds
Set Pkt Type - HV                                    Timed out  -15.236 seconds
Set Pkt Type - 2-DH                                  Timed out  -15.245 seconds
Set Pkt Type - 2-DH                                  Timed out  -15.253 seconds
Set Pkt Type - ALL                                   Timed out  -15.260 seconds
Set ACL MTU - 1                                      Timed out  -15.267 seconds


https://github.com/bluez/bluetooth-next/pull/148

---
Regards,
Linux Bluetooth


^ permalink raw reply

* [bluez/bluez] ccc22a: shared/hci: Add BPF filter for registered events
From: Luiz Augusto von Dentz @ 2026-05-06 13:56 UTC (permalink / raw)
  To: linux-bluetooth

  Branch: refs/heads/master
  Home:   https://github.com/bluez/bluez
  Commit: ccc22a9193884ccc3c3cb2b7a7b90100187c20b5
      https://github.com/bluez/bluez/commit/ccc22a9193884ccc3c3cb2b7a7b90100187c20b5
  Author: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
  Date:   2026-05-01 (Fri, 01 May 2026)

  Changed paths:
    M src/shared/hci.c

  Log Message:
  -----------
  shared/hci: Add BPF filter for registered events

Implement a BPF socket filter in bt_hci_register/bt_hci_unregister that
uses setsockopt(SO_ATTACH_FILTER) to only accept HCI events that have
been registered, plus BT_HCI_EVT_CMD_COMPLETE and BT_HCI_EVT_CMD_STATUS
which are always needed for command response processing.

The filter is rebuilt each time an event is registered or unregistered,
and only applies to non-stream (raw socket) connections.

Assisted-by: Claude:claude-opus-4.6


  Commit: 98f7190cf6b9e918943deeacd2f1494c9ca0710c
      https://github.com/bluez/bluez/commit/98f7190cf6b9e918943deeacd2f1494c9ca0710c
  Author: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
  Date:   2026-05-01 (Fri, 01 May 2026)

  Changed paths:
    M src/shared/hci.c
    M src/shared/hci.h

  Log Message:
  -----------
  shared/hci: Add bt_hci_register_subevent for LE Meta events

Add bt_hci_register_subevent/bt_hci_unregister_subevent API that allows
registering for specific LE Meta Event subevents. The BPF filter is
extended to accept BT_HCI_EVT_LE_META_EVENT packets and then check the
subevent byte (offset 4) against registered subevents.

Since bt_hci_register_subevent is only used with BT_HCI_EVT_LE_META_EVENT,
the event parameter is omitted. The subevent list reuses struct evt where
evt->event stores the subevent code.

Assisted-by: Claude:claude-opus-4.6


  Commit: 45e1e7ca2243fdea4fb0f31ac56de2e9ee9e9c5b
      https://github.com/bluez/bluez/commit/45e1e7ca2243fdea4fb0f31ac56de2e9ee9e9c5b
  Author: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
  Date:   2026-05-01 (Fri, 01 May 2026)

  Changed paths:
    M profiles/ranging/rap_hci.c

  Log Message:
  -----------
  ranging/rap_hci: Use bt_hci_register_subevent for LE CS events

Replace the single BT_HCI_EVT_LE_META_EVENT registration and subevent
dispatch table with individual bt_hci_register_subevent calls for each
CS subevent. This enables BPF filtering at the socket level for each
specific subevent and removes the manual subevent dispatch logic.

Event IDs are stored in a struct queue for flexible management.

Assisted-by: Claude:claude-opus-4.6


  Commit: 3502f9f51704acf8035b30e748462dd0fbf10be8
      https://github.com/bluez/bluez/commit/3502f9f51704acf8035b30e748462dd0fbf10be8
  Author: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
  Date:   2026-05-01 (Fri, 01 May 2026)

  Changed paths:
    M tools/hci-tester.c

  Log Message:
  -----------
  hci-tester: Use bt_hci_register_subevent for LE Meta events

Convert all bt_hci_register(BT_HCI_EVT_LE_META_EVENT) calls to use
bt_hci_register_subevent with the specific subevent code. Update
callbacks to work with data that no longer contains the subevent byte
prefix, since bt_hci_register_subevent strips it before dispatch.

Assisted-by: Claude:claude-opus-4.6


  Commit: fda84f7004fa4f1173c6482ac19973e1e7891655
      https://github.com/bluez/bluez/commit/fda84f7004fa4f1173c6482ac19973e1e7891655
  Author: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
  Date:   2026-05-04 (Mon, 04 May 2026)

  Changed paths:
    M monitor/packet.c

  Log Message:
  -----------
  monitor: Add features bits defined in 6.2

This adds features bits defined as per core spec 6.2:
https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-62/out/en/low-energy-controller/link-layer-specification.html#UUID-56ada5ed-4ae3-acee-198f-27ead57d86f1


  Commit: 79cfd07224ff3e2dc9828bdcb795fc49120da3f3
      https://github.com/bluez/bluez/commit/79cfd07224ff3e2dc9828bdcb795fc49120da3f3
  Author: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
  Date:   2026-05-04 (Mon, 04 May 2026)

  Changed paths:
    M monitor/bt.h
    M monitor/packet.c

  Log Message:
  -----------
  monitor: Add decoding for Short Connection Interval feature

This adds deconding support for SCI related commands, command bits, event
event mask bit and feature bits:

Events:

HCI_LE_Connection_Rate_Change(0x37)

Commands:

HCI_LE_Connection_Rate_Request(0x20a1)
HCI_LE_Set_Default_Rate_Parameters(0x20a2)
HCI_LE_Read_Minimum_Supported_Connection_Interval(0x20a3)


  Commit: 6aa7f5b4e0224e8b6668d7b9787d11d443ec72fd
      https://github.com/bluez/bluez/commit/6aa7f5b4e0224e8b6668d7b9787d11d443ec72fd
  Author: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
  Date:   2026-05-05 (Tue, 05 May 2026)

  Changed paths:
    M emulator/hciemu.c

  Log Message:
  -----------
  hciemu: Fix crash if hciemu_client_new return NULL

The following crahs can be observed if hciemu_client_new fails:

 Invalid read of size 8
   at 0x12DA79: queue_get_entries (queue.c:356)
   by 0x118434: hciemu_get_client (hciemu.c:277)
   by 0x1184A3: hciemu_client_get_host (hciemu.c:301)
   by 0x11536B: setup_powered_common (l2cap-tester.c:1452)
   by 0x11568E: setup_powered_client (l2cap-tester.c:1491)
   by 0x1324C6: setup_callback (tester.c:500)
   by 0x48A304D: g_main_context_dispatch (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
   by 0x48A33FF: ??? (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
   by 0x48A36F2: g_main_loop_run (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
   by 0x133868: mainloop_run (mainloop-glib.c:65)
   by 0x133C9F: mainloop_run_with_signal (mainloop-notify.c:196)
   by 0x13325F: tester_run (tester.c:1085)
  Address 0x4c1e388 is 8 bytes inside a block of size 32 free'd
   at 0x483CA3F: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
   by 0x1187BF: hciemu_new_num (hciemu.c:437)


  Commit: d0d42d034f9f7be3e743f885366becb758f19bde
      https://github.com/bluez/bluez/commit/d0d42d034f9f7be3e743f885366becb758f19bde
  Author: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
  Date:   2026-05-05 (Tue, 05 May 2026)

  Changed paths:
    M emulator/vhci.c

  Log Message:
  -----------
  emulator/vhci: Add debug messages to error paths

Add debug_callback, debug_destroy and debug_data fields to struct vhci
so vhci_set_debug stores the callback locally in addition to passing it
to btdev. Introduce a variadic vhci_debug() helper using util_debug_va
and add debug messages to the following error paths:

 - vhci_write_callback: failed io_send
 - vhci_read_callback: failed read
 - vhci_debugfs_write: failed open and failed write


  Commit: d4c965eec4d391d835b8884aed6f36d343ff73af
      https://github.com/bluez/bluez/commit/d4c965eec4d391d835b8884aed6f36d343ff73af
  Author: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
  Date:   2026-05-05 (Tue, 05 May 2026)

  Changed paths:
    M emulator/hciemu.c

  Log Message:
  -----------
  emulator/hciemu: Add debug messages to error paths

Introduce a variadic hciemu_debug() helper using util_debug_va and add
debug messages to the following error paths:

 - create_vhci: failed to open vhci
 - hciemu_client_new: failed to create btdev, bthost, or socketpair


  Commit: 164941a6c145b1ad9590faadc547de60bda4f020
      https://github.com/bluez/bluez/commit/164941a6c145b1ad9590faadc547de60bda4f020
  Author: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
  Date:   2026-05-05 (Tue, 05 May 2026)

  Changed paths:
    M tools/gap-tester.c

  Log Message:
  -----------
  tools/gap-tester: Enable hciemu debug output

Add print_debug callback and call hciemu_set_debug when debug output is
enabled so that hciemu error paths are visible during test runs.


  Commit: e51115ccd4dfd8ea9dc7662240c20d7703464a45
      https://github.com/bluez/bluez/commit/e51115ccd4dfd8ea9dc7662240c20d7703464a45
  Author: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
  Date:   2026-05-05 (Tue, 05 May 2026)

  Changed paths:
    M tools/userchan-tester.c

  Log Message:
  -----------
  tools/userchan-tester: Enable hciemu debug output

Call hciemu_set_debug when debug output is enabled so that hciemu error
paths are visible during test runs.


Compare: https://github.com/bluez/bluez/compare/31e4fb1498f4...e51115ccd4df

To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications

^ permalink raw reply

* [bluez/bluez]
From: BluezTestBot @ 2026-05-06 13:57 UTC (permalink / raw)
  To: linux-bluetooth

  Branch: refs/heads/1090123
  Home:   https://github.com/bluez/bluez

To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications

^ permalink raw reply

* [bluez/bluez]
From: BluezTestBot @ 2026-05-06 13:57 UTC (permalink / raw)
  To: linux-bluetooth

  Branch: refs/heads/1090113
  Home:   https://github.com/bluez/bluez

To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications

^ permalink raw reply

* [bluez/bluez]
From: BluezTestBot @ 2026-05-06 13:57 UTC (permalink / raw)
  To: linux-bluetooth

  Branch: refs/heads/1088547
  Home:   https://github.com/bluez/bluez

To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications

^ permalink raw reply

* [bluez/bluez]
From: BluezTestBot @ 2026-05-06 14:00 UTC (permalink / raw)
  To: linux-bluetooth

  Branch: refs/heads/1089499
  Home:   https://github.com/bluez/bluez

To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications

^ permalink raw reply

* [BlueZ v2 4/5] main: Use _cleanup_() to simplify configuration parsing
From: Bastien Nocera @ 2026-05-06 14:30 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <20260506143220.3076135-1-hadess@hadess.net>

Makes dealing with the error path easier.
---
 src/main.c | 70 ++++++++++++++++--------------------------------------
 1 file changed, 20 insertions(+), 50 deletions(-)

diff --git a/src/main.c b/src/main.c
index 8aa19a3e3346..3a2c3e645a74 100644
--- a/src/main.c
+++ b/src/main.c
@@ -462,7 +462,7 @@ static bool parse_config_int(GKeyFile *config, const char *group,
 					size_t min, size_t max)
 {
 	size_t tmp;
-	char *str = NULL;
+	_cleanup_(g_free) char *str = NULL;
 	char *endptr = NULL;
 
 	if (!parse_config_string(config, group, key, &str))
@@ -471,25 +471,21 @@ static bool parse_config_int(GKeyFile *config, const char *group,
 	tmp = strtol(str, &endptr, 0);
 	if (!endptr || *endptr != '\0') {
 		error("%s.%s = %s is not integer", group, key, str);
-		g_free(str);
 		return false;
 	}
 
 	if (tmp < min) {
-		g_free(str);
 		warn("%s.%s = %zu is out of range (< %zu)", group, key, tmp,
 									min);
 		return false;
 	}
 
 	if (tmp > max) {
-		g_free(str);
 		warn("%s.%s = %zu is out of range (> %zu)", group, key, tmp,
 									max);
 		return false;
 	}
 
-	g_free(str);
 	if (val)
 		*val = tmp;
 
@@ -500,10 +496,9 @@ static bool parse_config_signed_int(GKeyFile *config, const char *group,
 					const char *key, int8_t *val,
 					long min, long max)
 {
-	char *str = NULL;
+	_cleanup_(g_free) char *str = NULL;
 	char *endptr = NULL;
 	long tmp;
-	bool result = false;
 
 	str = g_key_file_get_string(config, group, key, NULL);
 	if (!str)
@@ -512,28 +507,24 @@ static bool parse_config_signed_int(GKeyFile *config, const char *group,
 	tmp = strtol(str, &endptr, 0);
 	if (!endptr || *endptr != '\0') {
 		warn("%s.%s = %s is not integer", group, key, str);
-		goto cleanup;
+		return false;
 	}
 
 	if (tmp < min) {
 		warn("%s.%s = %ld is out of range (< %ld)", group, key, tmp,
 			min);
-		goto cleanup;
+		return false;
 	}
 
 	if (tmp > max) {
 		warn("%s.%s = %ld is out of range (> %ld)", group, key, tmp,
 									max);
-		goto cleanup;
+		return false;
 	}
 
 	if (val)
 		*val = (int8_t) tmp;
-	result = true;
-
-cleanup:
-	g_free(str);
-	return result;
+	return true;
 }
 
 struct config_param {
@@ -915,7 +906,7 @@ static bool parse_config_bool(GKeyFile *config, const char *group,
 
 static void parse_privacy(GKeyFile *config)
 {
-	char *str = NULL;
+	_cleanup_(g_free) char *str = NULL;
 
 	if (!parse_config_string(config, "General", "Privacy", &str)) {
 		btd_opts.privacy = 0x00;
@@ -948,13 +939,11 @@ static void parse_privacy(GKeyFile *config)
 		DBG("Invalid privacy option: %s", str);
 		btd_opts.privacy = 0x00;
 	}
-
-	g_free(str);
 }
 
 static void parse_repairing(GKeyFile *config)
 {
-	char *str = NULL;
+	_cleanup_(g_free) char *str = NULL;
 
 	if (!parse_config_string(config, "General", "JustWorksRepairing",
 						&str)) {
@@ -963,13 +952,12 @@ static void parse_repairing(GKeyFile *config)
 	}
 
 	btd_opts.jw_repairing = parse_jw_repairing(str);
-	g_free(str);
 }
 
 static bool parse_config_hex(GKeyFile *config, char *group,
 					const char *key, uint32_t *val)
 {
-	char *str = NULL;
+	_cleanup_(g_free) char *str = NULL;
 
 	if (!parse_config_string(config, group, key, &str))
 		return false;
@@ -977,37 +965,34 @@ static bool parse_config_hex(GKeyFile *config, char *group,
 	if (val)
 		*val = strtol(str, NULL, 16);
 
-	g_free(str);
 	return true;
 }
 
 static void parse_device_id(GKeyFile *config)
 {
-	char *str = NULL;
+	_cleanup_(g_free) char *str = NULL;
 
 	parse_config_string(config, "General", "DeviceID", &str);
 	if (!str)
 		return;
 
 	parse_did(str);
-	g_free(str);
 }
 
 static void parse_ctrl_mode(GKeyFile *config)
 {
-	char *str = NULL;
+	_cleanup_(g_free) char *str = NULL;
 
 	parse_config_string(config, "General", "ControllerMode", &str);
 	if (!str)
 		return;
 
 	btd_opts.mode = get_mode(str);
-	g_free(str);
 }
 
 static void parse_multi_profile(GKeyFile *config)
 {
-	char *str = NULL;
+	_cleanup_(g_free) char *str = NULL;
 
 	parse_config_string(config, "General", "MultiProfile", &str);
 	if (!str)
@@ -1019,8 +1004,6 @@ static void parse_multi_profile(GKeyFile *config)
 		btd_opts.mps = MPS_MULTIPLE;
 	else
 		btd_opts.mps = MPS_OFF;
-
-	g_free(str);
 }
 
 static gboolean parse_kernel_experimental(const char *key, const char *value,
@@ -1043,20 +1026,18 @@ static gboolean parse_kernel_experimental(const char *key, const char *value,
 
 static void parse_kernel_exp(GKeyFile *config)
 {
-	char *str = NULL;
+	_cleanup_(g_free) char *str = NULL;
 
 	if (!parse_config_string(config, "General", "KernelExperimental",
 						&str))
 		return;
 
 	parse_kernel_experimental(NULL, str, NULL, NULL);
-
-	g_free(str);
 }
 
 static void parse_secure_conns(GKeyFile *config)
 {
-	char *str = NULL;
+	_cleanup_(g_free) char *str = NULL;
 
 	if (!parse_config_string(config, "General", "SecureConnections",
 								&str))
@@ -1068,8 +1049,6 @@ static void parse_secure_conns(GKeyFile *config)
 		btd_opts.secure_conn = SC_ON;
 	else if (!strcmp(str, "only"))
 		btd_opts.secure_conn = SC_ONLY;
-
-	g_free(str);
 }
 
 static void parse_general(GKeyFile *config)
@@ -1120,14 +1099,13 @@ static void parse_general(GKeyFile *config)
 
 static void parse_gatt_cache(GKeyFile *config)
 {
-	char *str = NULL;
+	_cleanup_(g_free) char *str = NULL;
 
 	parse_config_string(config, "GATT", "Cache", &str);
 	if (!str)
 		return;
 
 	btd_opts.gatt_cache = parse_gatt_cache_str(str);
-	g_free(str);
 }
 
 static enum bt_gatt_export_t parse_gatt_export_str(const char *str)
@@ -1147,14 +1125,13 @@ static enum bt_gatt_export_t parse_gatt_export_str(const char *str)
 
 static void parse_gatt_export(GKeyFile *config)
 {
-	char *str = NULL;
+	_cleanup_(g_free) char *str = NULL;
 
 	parse_config_string(config, "GATT", "ExportClaimedServices", &str);
 	if (!str)
 		return;
 
 	btd_opts.gatt_export = parse_gatt_export_str(str);
-	g_free(str);
 }
 
 static uint8_t parse_gatt_seclevel_str(const char *str)
@@ -1176,7 +1153,7 @@ static uint8_t parse_gatt_seclevel_str(const char *str)
 
 static void parse_gatt_seclevel(GKeyFile *config)
 {
-	char *str = NULL;
+	_cleanup_(g_free) char *str = NULL;
 
 	if (!btd_opts.testing)
 		return;
@@ -1186,7 +1163,6 @@ static void parse_gatt_seclevel(GKeyFile *config)
 		return;
 
 	btd_opts.gatt_seclevel = parse_gatt_seclevel_str(str);
-	g_free(str);
 }
 
 static void parse_gatt(GKeyFile *config)
@@ -1204,7 +1180,7 @@ static void parse_gatt(GKeyFile *config)
 
 static void parse_csis_sirk(GKeyFile *config)
 {
-	char *str = NULL;
+	_cleanup_(g_free) char *str = NULL;
 
 	if (!parse_config_string(config, "CSIS", "SIRK", &str))
 		return;
@@ -1213,8 +1189,6 @@ static void parse_csis_sirk(GKeyFile *config)
 		hex2bin(str, btd_opts.csis.sirk, sizeof(btd_opts.csis.sirk));
 	else if (!gen_sirk(str))
 		DBG("Unable to generate SIRK from string");
-
-	g_free(str);
 }
 
 static void parse_csis(GKeyFile *config)
@@ -1305,7 +1279,7 @@ static void parse_le_cs_config(GKeyFile *config)
 
 static void parse_avdtp_session_mode(GKeyFile *config)
 {
-	char *str = NULL;
+	_cleanup_(g_free) char *str = NULL;
 
 	if (!parse_config_string(config, "AVDTP", "SessionMode", &str))
 		return;
@@ -1318,13 +1292,11 @@ static void parse_avdtp_session_mode(GKeyFile *config)
 		DBG("Invalid mode option: %s", str);
 		btd_opts.avdtp.session_mode = BT_IO_MODE_BASIC;
 	}
-
-	g_free(str);
 }
 
 static void parse_avdtp_stream_mode(GKeyFile *config)
 {
-	char *str = NULL;
+	_cleanup_(g_free) char *str = NULL;
 
 	if (!parse_config_string(config, "AVDTP", "StreamMode", &str))
 		return;
@@ -1337,8 +1309,6 @@ static void parse_avdtp_stream_mode(GKeyFile *config)
 		DBG("Invalid mode option: %s", str);
 		btd_opts.avdtp.stream_mode = BT_IO_MODE_BASIC;
 	}
-
-	g_free(str);
 }
 
 static void parse_avdtp(GKeyFile *config)
-- 
2.54.0


^ permalink raw reply related

* [BlueZ v2 3/5] doc: Recommend using _cleanup_ and friends
From: Bastien Nocera @ 2026-05-06 14:30 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <20260506143220.3076135-1-hadess@hadess.net>

---
 doc/maintainer-guidelines.rst | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/doc/maintainer-guidelines.rst b/doc/maintainer-guidelines.rst
index 44d3e258db6e..b67c6596f4c1 100644
--- a/doc/maintainer-guidelines.rst
+++ b/doc/maintainer-guidelines.rst
@@ -98,6 +98,9 @@ do this:
 
 The above assumes that a kernel tree resides in ``~/src/linux/``.
 
+Also make sure to use ``_cleanup_free_`` and ``_cleanup_(free_func)`` when
+possible. It makes your code much nicer to read (and shorter), and avoids
+common memory leaks on error paths.
 
 Rule 4: Pay extra attention to adding new files to the tree
 -----------------------------------------------------------
-- 
2.54.0


^ permalink raw reply related

* [BlueZ v2 2/5] shared/util: Add helper for "cleanup" variable attribute
From: Bastien Nocera @ 2026-05-06 14:30 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <20260506143220.3076135-1-hadess@hadess.net>

Use the widespread "cleanup" variable attribute:
https://gcc.gnu.org/onlinedocs/gcc/Common-Attributes.html#index-cleanup

It is implemented by both GCC and clang on platforms where bluez is
used, and can help reduce memory leaks, while improving readability.

See also:
https://systemd.io/CODING_STYLE/#memory-allocation
https://docs.gtk.org/glib/auto-cleanup.html
---
 src/shared/util.h | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/src/shared/util.h b/src/shared/util.h
index 67629dddfaa9..1660b6ea5149 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -93,6 +93,14 @@ do {						\
 #define newa(t, n) ((t*) alloca(sizeof(t)*(n)))
 #define malloc0(n) (calloc(1, (n)))
 
+static inline void freep(void *p)
+{
+	free(*(void **) p);
+}
+
+#define _cleanup_(f) __attribute__((cleanup(f)))
+#define _cleanup_free_ _cleanup_(freep)
+
 char *strdelimit(char *str, char *del, char c);
 int strsuffix(const char *str, const char *suffix);
 char *strstrip(char *str);
-- 
2.54.0


^ permalink raw reply related

* [BlueZ v2 5/5] main: Use _cleanup_() to simplify GError-handling
From: Bastien Nocera @ 2026-05-06 14:30 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <20260506143220.3076135-1-hadess@hadess.net>

Use _cleanup_() to simplify GError-handling in the error paths.
---
 src/main.c | 30 +++++++++++++-----------------
 1 file changed, 13 insertions(+), 17 deletions(-)

diff --git a/src/main.c b/src/main.c
index 3a2c3e645a74..ef11b07d7a9a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -205,6 +205,13 @@ static const struct group_table {
 	{ }
 };
 
+static inline void free_error(void *err)
+{
+	g_error_free(*(void **) err);
+}
+
+#define _cleanup_error_ _cleanup_(free_error)
+
 static int8_t check_sirk_alpha_numeric(char *str)
 {
 	int8_t val = 0;
@@ -252,7 +259,7 @@ GKeyFile *btd_get_main_conf(void)
 
 static GKeyFile *load_config(const char *name)
 {
-	GError *err = NULL;
+	_cleanup_error_ GError *err = NULL;
 	GKeyFile *keyfile;
 	int len;
 
@@ -285,7 +292,6 @@ static GKeyFile *load_config(const char *name)
 		if (!g_error_matches(err, G_FILE_ERROR, G_FILE_ERROR_NOENT))
 			error("Parsing %s failed: %s", main_conf_file_path,
 				err->message);
-		g_error_free(err);
 		g_key_file_free(keyfile);
 		return NULL;
 	}
@@ -436,14 +442,13 @@ static int get_mode(const char *str)
 static bool parse_config_string(GKeyFile *config, const char *group,
 					const char *key, char **val)
 {
-	GError *err = NULL;
+	_cleanup_error_ GError *err = NULL;
 	char *tmp;
 
 	tmp = g_key_file_get_string(config, group, key, &err);
 	if (err) {
 		if (err->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND)
 			DBG("%s", err->message);
-		g_error_free(err);
 		return false;
 	}
 
@@ -885,14 +890,13 @@ static bool parse_config_u8(GKeyFile *config, const char *group,
 static bool parse_config_bool(GKeyFile *config, const char *group,
 					const char *key, bool *val)
 {
-	GError *err = NULL;
+	_cleanup_error_ GError *err = NULL;
 	gboolean tmp;
 
 	tmp = g_key_file_get_boolean(config, group, key, &err);
 	if (err) {
 		if (err->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND)
 			DBG("%s", err->message);
-		g_error_free(err);
 		return false;
 	}
 
@@ -1205,8 +1209,8 @@ static void parse_csis(GKeyFile *config)
 static bool parse_cs_role(GKeyFile *config, const char *group,
 					const char *key, uint8_t *val)
 {
-	GError *err = NULL;
-	char *str = NULL;
+	_cleanup_error_ GError *err = NULL;
+	_cleanup_(g_free) char *str = NULL;
 	char *endptr = NULL;
 	int numeric_val;
 
@@ -1215,7 +1219,6 @@ static bool parse_cs_role(GKeyFile *config, const char *group,
 	if (err) {
 		if (err->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND)
 			DBG("%s", err->message);
-		g_error_free(err);
 		return false;
 	}
 
@@ -1225,17 +1228,14 @@ static bool parse_cs_role(GKeyFile *config, const char *group,
 	if (!strcmp(str, "Initiator") || !strcmp(str, "initiator")) {
 		if (val)
 			*val = 1;
-		g_free(str);
 		return true;
 	} else if (!strcmp(str, "Reflector") || !strcmp(str, "reflector")) {
 		if (val)
 			*val = 2;
-		g_free(str);
 		return true;
 	} else if (!strcmp(str, "Both") || !strcmp(str, "both")) {
 		if (val)
 			*val = 3;
-		g_free(str);
 		return true;
 	}
 
@@ -1246,7 +1246,6 @@ static bool parse_cs_role(GKeyFile *config, const char *group,
 		warn("%s.%s = %s is not a valid value. "
 			"Expected: 1/Initiator, 2/Reflector, or 3/Both",
 			group, key, str);
-		g_free(str);
 		return false;
 	}
 
@@ -1254,14 +1253,12 @@ static bool parse_cs_role(GKeyFile *config, const char *group,
 		warn("%s.%s = %d is out of range. "
 			"Valid values: 1 (Initiator), 2 (Reflector), 3 (Both)",
 			group, key, numeric_val);
-		g_free(str);
 		return false;
 	}
 
 	if (val)
 		*val = numeric_val;
 
-	g_free(str);
 	return true;
 }
 
@@ -1575,7 +1572,7 @@ static GOptionEntry options[] = {
 int main(int argc, char *argv[])
 {
 	GOptionContext *context;
-	GError *err = NULL;
+	_cleanup_error_ GError *err = NULL;
 	uint16_t sdp_mtu = 0;
 	uint32_t sdp_flags = 0;
 	int gdbus_flags = 0;
@@ -1588,7 +1585,6 @@ int main(int argc, char *argv[])
 	if (g_option_context_parse(context, &argc, &argv, &err) == FALSE) {
 		if (err != NULL) {
 			g_printerr("%s\n", err->message);
-			g_error_free(err);
 		} else
 			g_printerr("An unknown error occurred\n");
 		exit(1);
-- 
2.54.0


^ permalink raw reply related

* [BlueZ v2 1/5] all: Remove more unneeded MIN/MAX macro definition
From: Bastien Nocera @ 2026-05-06 14:30 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <20260506143220.3076135-1-hadess@hadess.net>

---
 lib/bluetooth/hci.c      | 4 ----
 src/main.c               | 4 ----
 src/shared/gatt-server.c | 8 --------
 3 files changed, 16 deletions(-)

diff --git a/lib/bluetooth/hci.c b/lib/bluetooth/hci.c
index 44eea054b0ac..f50a30c610be 100644
--- a/lib/bluetooth/hci.c
+++ b/lib/bluetooth/hci.c
@@ -33,10 +33,6 @@
 #include "hci.h"
 #include "hci_lib.h"
 
-#ifndef MIN
-#define MIN(x, y) ((x) < (y) ? (x) : (y))
-#endif
-
 typedef struct {
 	char *str;
 	unsigned int val;
diff --git a/src/main.c b/src/main.c
index 9a3d2da25d4d..8aa19a3e3346 100644
--- a/src/main.c
+++ b/src/main.c
@@ -205,10 +205,6 @@ static const struct group_table {
 	{ }
 };
 
-#ifndef MIN
-#define MIN(x, y) ((x) < (y) ? (x) : (y))
-#endif
-
 static int8_t check_sirk_alpha_numeric(char *str)
 {
 	int8_t val = 0;
diff --git a/src/shared/gatt-server.c b/src/shared/gatt-server.c
index 6273899965c0..709a8f94bb6a 100644
--- a/src/shared/gatt-server.c
+++ b/src/shared/gatt-server.c
@@ -26,14 +26,6 @@
 #include "src/shared/util.h"
 #include "src/shared/timeout.h"
 
-#ifndef MAX
-#define MAX(a, b) ((a) > (b) ? (a) : (b))
-#endif
-
-#ifndef MIN
-#define MIN(a, b) ((a) < (b) ? (a) : (b))
-#endif
-
 /*
  * TODO: This is an arbitrary limit. Come up with something reasonable or
  * perhaps an API to set this value if there is a use case for it.
-- 
2.54.0


^ permalink raw reply related

* [BlueZ v2 0/5] Add helper for "cleanup" variable attribute
From: Bastien Nocera @ 2026-05-06 14:30 UTC (permalink / raw)
  To: linux-bluetooth

As discussed in:
https://lore.kernel.org/linux-bluetooth/ed949f2550f79a4bef19bd482bf8b069ad5b7e0c.camel@hadess.net/

Implement a cleanup helper.

The MIN/MAX fix is here because it touches the same hunk in src/main.c
as the other patches. Feel free to pick it up straight away while the
rest is discussed.

Changes since v1:
- Fixed checkpatch warnings

Bastien Nocera (5):
  all: Remove more unneeded MIN/MAX macro definition
  shared/util: Add helper for "cleanup" variable attribute
  doc: Recommend using _cleanup_ and friends
  main: Use _cleanup_() to simplify configuration parsing
  main: Use _cleanup_() to simplify GError-handling

 doc/maintainer-guidelines.rst |   3 +
 lib/bluetooth/hci.c           |   4 --
 src/main.c                    | 102 +++++++++++-----------------------
 src/shared/gatt-server.c      |   8 ---
 src/shared/util.h             |   8 +++
 5 files changed, 43 insertions(+), 82 deletions(-)

-- 
2.54.0


^ permalink raw reply

* [PATCH] Bluetooth: L2CAP: avoid using hci_conn after dropping hold
From: Cen Zhang @ 2026-05-06 15:53 UTC (permalink / raw)
  To: marcel, luiz.dentz; +Cc: linux-bluetooth, linux-kernel, baijiaju1990, Cen Zhang

l2cap_chan_connect() drops the temporary HCI connection hold after
__l2cap_chan_add() attaches the L2CAP channel and takes its own hold.
The function then checks hcon->state to see whether the channel can be
started immediately because the underlying HCI link is already connected.

Keep that state sample before hci_conn_drop(hcon), and only use the
cached result afterwards.  This avoids dereferencing hcon after the
temporary hold has been released.  Use READ_ONCE() for the sample because
HCI connection state can be advanced concurrently by the command-sync
worker while L2CAP is setting up the channel.

The sampled state is only an optimization for the already-connected case:
a stale non-connected value leaves the L2CAP channel pending for the
normal HCI connect confirmation path.

Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
---
 net/bluetooth/l2cap_core.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 95c65fece39bd..40e84c1623a9c 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -7078,6 +7078,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
 	struct l2cap_conn *conn;
 	struct hci_conn *hcon;
 	struct hci_dev *hdev;
+	bool link_connected;
 	int err;
 
 	BT_DBG("%pMR -> %pMR (type %u) psm 0x%4.4x mode 0x%2.2x", &chan->src,
@@ -7222,6 +7223,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
 	chan->src_type = bdaddr_src_type(hcon);
 
 	__l2cap_chan_add(conn, chan);
+	link_connected = READ_ONCE(hcon->state) == BT_CONNECTED;
 
 	/* l2cap_chan_add takes its own ref so we can drop this one */
 	hci_conn_drop(hcon);
@@ -7236,7 +7238,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
 	chan->sport = 0;
 	write_unlock(&chan_list_lock);
 
-	if (hcon->state == BT_CONNECTED) {
+	if (link_connected) {
 		if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
 			__clear_chan_timer(chan);
 			if (l2cap_chan_check_security(chan, true))

^ permalink raw reply related

* [bluez/bluez] eff7db: all: Remove more unneeded MIN/MAX macro definition
From: hadess @ 2026-05-06 15:55 UTC (permalink / raw)
  To: linux-bluetooth

  Branch: refs/heads/1090532
  Home:   https://github.com/bluez/bluez
  Commit: eff7db7ed10341dd510b0a045d31a49761f8dc4e
      https://github.com/bluez/bluez/commit/eff7db7ed10341dd510b0a045d31a49761f8dc4e
  Author: Bastien Nocera <hadess@hadess.net>
  Date:   2026-05-06 (Wed, 06 May 2026)

  Changed paths:
    M lib/bluetooth/hci.c
    M src/main.c
    M src/shared/gatt-server.c

  Log Message:
  -----------
  all: Remove more unneeded MIN/MAX macro definition


  Commit: c3200ddcfe6913d6959dc0baf2a66a42a58bf371
      https://github.com/bluez/bluez/commit/c3200ddcfe6913d6959dc0baf2a66a42a58bf371
  Author: Bastien Nocera <hadess@hadess.net>
  Date:   2026-05-06 (Wed, 06 May 2026)

  Changed paths:
    M src/shared/util.h

  Log Message:
  -----------
  shared/util: Add helper for "cleanup" variable attribute

Use the widespread "cleanup" variable attribute:
https://gcc.gnu.org/onlinedocs/gcc/Common-Attributes.html#index-cleanup

It is implemented by both GCC and clang on platforms where bluez is
used, and can help reduce memory leaks, while improving readability.

See also:
https://systemd.io/CODING_STYLE/#memory-allocation
https://docs.gtk.org/glib/auto-cleanup.html


  Commit: 706acaec9481a82aef2833b51a4c001cb96beea2
      https://github.com/bluez/bluez/commit/706acaec9481a82aef2833b51a4c001cb96beea2
  Author: Bastien Nocera <hadess@hadess.net>
  Date:   2026-05-06 (Wed, 06 May 2026)

  Changed paths:
    M doc/maintainer-guidelines.rst

  Log Message:
  -----------
  doc: Recommend using _cleanup_ and friends


  Commit: 5b442f494b6c9eba048ff06500d29d9b93f78821
      https://github.com/bluez/bluez/commit/5b442f494b6c9eba048ff06500d29d9b93f78821
  Author: Bastien Nocera <hadess@hadess.net>
  Date:   2026-05-06 (Wed, 06 May 2026)

  Changed paths:
    M src/main.c

  Log Message:
  -----------
  main: Use _cleanup_() to simplify configuration parsing

Makes dealing with the error path easier.


  Commit: dc4d19132e80ae285d9d7fbe776dad85b43f7121
      https://github.com/bluez/bluez/commit/dc4d19132e80ae285d9d7fbe776dad85b43f7121
  Author: Bastien Nocera <hadess@hadess.net>
  Date:   2026-05-06 (Wed, 06 May 2026)

  Changed paths:
    M src/main.c

  Log Message:
  -----------
  main: Use _cleanup_() to simplify GError-handling

Use _cleanup_() to simplify GError-handling in the error paths.


Compare: https://github.com/bluez/bluez/compare/eff7db7ed103%5E...dc4d19132e80

To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications

^ permalink raw reply

* [PATCH v2 1/2] Bluetooth: HCI: Add initial support for Short Connection Interval feature
From: Luiz Augusto von Dentz @ 2026-05-06 16:06 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This adds initial support for SCI related commands, command bits, event
event mask bit and feature bits:

Events:

HCI_LE_Connection_Rate_Change(0x37)

Commands:

HCI_LE_Connection_Rate_Request(0x20a1)
HCI_LE_Set_Default_Rate_Parameters(0x20a2)
HCI_LE_Read_Minimum_Supported_Connection_Interval(0x20a3)

Also update the init sequence to incorporte support for reading SCI
groups and then setting the Default Rate

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
 include/net/bluetooth/hci.h      | 52 +++++++++++++++++++
 include/net/bluetooth/hci_core.h | 15 ++++++
 net/bluetooth/hci_core.c         | 14 ++++-
 net/bluetooth/hci_event.c        | 62 ++++++++++++++++++++++
 net/bluetooth/hci_sync.c         | 88 +++++++++++++++++++++++++++++++-
 5 files changed, 229 insertions(+), 2 deletions(-)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 572b1c620c5d..848ec42de827 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -656,6 +656,7 @@ enum {
 #define HCI_LE_LL_EXT_FEATURE		0x80
 #define HCI_LE_CS			0x40
 #define HCI_LE_CS_HOST			0x80
+#define HCI_LE_SCI			0x01
 
 /* Connection modes */
 #define HCI_CM_ACTIVE	0x0000
@@ -2486,6 +2487,46 @@ struct hci_rp_le_cs_test {
 
 #define HCI_OP_LE_CS_TEST_END			0x2096
 
+#define HCI_OP_LE_CONN_RATE			0x20a1
+struct hci_cp_le_conn_rate {
+	__le16   handle;
+	__le16   interval_min;
+	__le16   interval_max;
+	__le16   subrate_min;
+	__le16   subrate_max;
+	__le16   max_latency;
+	__le16   cont_num;
+	__le16   supv_timeout;
+	__le16   min_ce_len;
+	__le16   max_ce_len;
+} __packed;
+
+#define HCI_OP_LE_SET_DEF_RATE		0x20a2
+struct hci_cp_le_set_def_rate {
+	__le16   interval_min;
+	__le16   interval_max;
+	__le16   subrate_min;
+	__le16   subrate_max;
+	__le16   max_latency;
+	__le16   cont_num;
+	__le16   supv_timeout;
+	__le16   min_ce_len;
+	__le16   max_ce_len;
+} __packed;
+
+#define HCI_OP_LE_READ_CONN_INTERVAL	0x20a3
+struct hci_le_conn_interval_group {
+	__le16   min;
+	__le16   max;
+	__le16   stride;
+} __packed;
+
+struct hci_rp_le_read_conn_interval {
+	__u8    status;
+	__u8    num_grps;
+	struct hci_le_conn_interval_group grps[] __counted_by(num_grps);
+} __packed;
+
 /* ---- HCI Events ---- */
 struct hci_ev_status {
 	__u8    status;
@@ -3300,6 +3341,17 @@ struct hci_evt_le_cs_test_end_complete {
 	__u8	status;
 } __packed;
 
+#define HCI_EVT_LE_CONN_RATE_CHANGE			0x37
+struct hci_evt_le_conn_rate_change {
+	__u8	status;
+	__le16	handle;
+	__le16	interval;
+	__le16	subrate;
+	__le16	latency;
+	__le16	cont_number;
+	__le16	supv_timeout;
+} __packed;
+
 #define HCI_EV_VENDOR			0xff
 
 /* Internal events generated by Bluetooth stack */
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index aa600fbf9a53..61872403fe65 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -333,6 +333,14 @@ struct adv_monitor {
 #define HCI_ADV_MONITOR_EXT_NONE		1
 #define HCI_ADV_MONITOR_EXT_MSFT		2
 
+
+struct sci_group {
+	struct list_head list;
+	__u16 min;
+	__u16 max;
+	__u16 stride;
+};
+
 #define HCI_MAX_SHORT_NAME_LENGTH	10
 
 #define HCI_CONN_HANDLE_MAX		0x0eff
@@ -572,6 +580,7 @@ struct hci_dev {
 	struct list_head	pend_le_reports;
 	struct list_head	blocked_keys;
 	struct list_head	local_codecs;
+	struct list_head	sci_groups;
 
 	struct hci_dev_stats	stat;
 
@@ -2082,6 +2091,12 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
 #define mws_transport_config_capable(dev) (((dev)->commands[30] & 0x08) && \
 	(!hci_test_quirk((dev), HCI_QUIRK_BROKEN_MWS_TRANSPORT_CONFIG)))
 
+/* Shorter Connection Intervals support */
+#define le_sci_capable(dev) \
+	((dev)->le_features[9] & HCI_LE_SCI)
+
+void hci_sci_groups_clear(struct hci_dev *hdev);
+
 /* ----- HCI protocols ----- */
 #define HCI_PROTO_DEFER             0x01
 
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index c46c1236ebfa..04c5559ef029 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -2543,8 +2543,9 @@ struct hci_dev *hci_alloc_dev_priv(int sizeof_priv)
 	INIT_LIST_HEAD(&hdev->adv_instances);
 	INIT_LIST_HEAD(&hdev->blocked_keys);
 	INIT_LIST_HEAD(&hdev->monitored_devices);
-
 	INIT_LIST_HEAD(&hdev->local_codecs);
+	INIT_LIST_HEAD(&hdev->sci_groups);
+
 	INIT_WORK(&hdev->rx_work, hci_rx_work);
 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
 	INIT_WORK(&hdev->tx_work, hci_tx_work);
@@ -2740,6 +2741,16 @@ void hci_unregister_dev(struct hci_dev *hdev)
 }
 EXPORT_SYMBOL(hci_unregister_dev);
 
+void hci_sci_groups_clear(struct hci_dev *hdev)
+{
+	struct sci_group *grp, *tmp;
+
+	list_for_each_entry_safe(grp, tmp, &hdev->sci_groups, list) {
+		list_del(&grp->list);
+		kfree(grp);
+	}
+}
+
 /* Release HCI device */
 void hci_release_dev(struct hci_dev *hdev)
 {
@@ -2766,6 +2777,7 @@ void hci_release_dev(struct hci_dev *hdev)
 	hci_discovery_filter_clear(hdev);
 	hci_blocked_keys_clear(hdev);
 	hci_codec_list_clear(&hdev->local_codecs);
+	hci_sci_groups_clear(hdev);
 	msft_release(hdev);
 	hci_dev_unlock(hdev);
 
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index eea2f810aafa..db2a8d5c456c 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -3957,6 +3957,51 @@ static u8 hci_cc_le_read_all_local_features(struct hci_dev *hdev, void *data,
 	return rp->status;
 }
 
+static u8 hci_cc_le_read_conn_interval(struct hci_dev *hdev, void *data,
+				       struct sk_buff *skb)
+{
+	struct hci_rp_le_read_conn_interval *rp = data;
+	__u8 i;
+
+	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
+
+	if (rp->status || !rp->num_grps)
+		return rp->status;
+
+	hci_dev_lock(hdev);
+
+	/* Clear any existing SCI groups before adding new ones. */
+	hci_sci_groups_clear(hdev);
+
+	for (i = 0; i < rp->num_grps; i++) {
+		struct hci_le_conn_interval_group *grp;
+		struct sci_group *sgrp;
+
+		/* Pull HCI event data for the current group. */
+		grp = skb_pull_data(skb, sizeof(*grp));
+		if (!grp) {
+			bt_dev_err(hdev, "invalid data length for SCI group");
+			break;
+		}
+
+		sgrp = kzalloc(sizeof(*sgrp), GFP_KERNEL);
+		if (!sgrp) {
+			bt_dev_err(hdev, "can't allocate memory for SCI group");
+			break;
+		}
+
+		sgrp->min = __le16_to_cpu(grp->min);
+		sgrp->max = __le16_to_cpu(grp->max);
+		sgrp->stride = __le16_to_cpu(grp->stride);
+
+		list_add(&sgrp->list, &hdev->sci_groups);
+	}
+
+	hci_dev_unlock(hdev);
+
+	return rp->status;
+}
+
 static void hci_cs_le_create_big(struct hci_dev *hdev, u8 status)
 {
 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
@@ -4239,6 +4284,10 @@ static const struct hci_cc {
 	HCI_CC(HCI_OP_LE_READ_ALL_LOCAL_FEATURES,
 	       hci_cc_le_read_all_local_features,
 	       sizeof(struct hci_rp_le_read_all_local_features)),
+	HCI_CC_VL(HCI_OP_LE_READ_CONN_INTERVAL,
+		  hci_cc_le_read_conn_interval,
+		  sizeof(struct hci_rp_le_read_conn_interval),
+		  HCI_MAX_EVENT_SIZE),
 };
 
 static u8 hci_cc_func(struct hci_dev *hdev, const struct hci_cc *cc,
@@ -7372,6 +7421,16 @@ static void hci_le_read_all_remote_features_evt(struct hci_dev *hdev,
 	hci_dev_unlock(hdev);
 }
 
+static void hci_le_conn_rate_change_evt(struct hci_dev *hdev, void *data,
+					struct sk_buff *skb)
+{
+	struct hci_evt_le_conn_rate_change *ev = data;
+
+	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
+
+	/* TODO: Store rate to be used for next connection? */
+}
+
 #define HCI_LE_EV_VL(_op, _func, _min_len, _max_len) \
 [_op] = { \
 	.func = _func, \
@@ -7483,6 +7542,9 @@ static const struct hci_le_ev {
 		     sizeof(struct
 			    hci_evt_le_read_all_remote_features_complete),
 		     HCI_MAX_EVENT_SIZE),
+	/* [0x37 = HCI_EVT_LE_CONN_RATE_CHANGE] */
+	HCI_LE_EV(HCI_EVT_LE_CONN_RATE_CHANGE, hci_le_conn_rate_change_evt,
+		  sizeof(struct hci_evt_le_conn_rate_change)),
 };
 
 static void hci_le_meta_evt(struct hci_dev *hdev, void *data,
diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
index fd3aacdea512..31c3c873e33d 100644
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -4449,6 +4449,10 @@ static int hci_le_set_event_mask_sync(struct hci_dev *hdev)
 		events[6] |= 0x02;	/* LE CS Subevent Result Continue event */
 		events[6] |= 0x04;	/* LE CS Test End Complete event */
 	}
+
+	if (le_sci_capable(hdev))
+		events[6] |= 0x20;	/* LE Connection Rate Change */
+
 	return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_EVENT_MASK,
 				     sizeof(events), events, HCI_CMD_TIMEOUT);
 }
@@ -4611,9 +4615,16 @@ static int hci_le_set_host_features_sync(struct hci_dev *hdev)
 			return err;
 	}
 
-	if (le_cs_capable(hdev))
+	if (le_cs_capable(hdev)) {
 		/* Channel Sounding (Host Support) */
 		err = hci_le_set_host_feature_sync(hdev, 47, 0x01);
+		if (err)
+			return err;
+	}
+
+	if (le_sci_capable(hdev))
+		/* Short Connection Interval (Host Support) */
+		err = hci_le_set_host_feature_sync(hdev, 73, 0x01);
 
 	return err;
 }
@@ -4896,11 +4907,86 @@ static int hci_le_set_default_phy_sync(struct hci_dev *hdev)
 				     sizeof(cp), &cp, HCI_CMD_TIMEOUT);
 }
 
+/* Read Connection Interval if command is supported and SCI feature bit is
+ * marked as supported.
+ */
+static int hci_le_read_conn_interval_sync(struct hci_dev *hdev)
+{
+	if (!(hdev->commands[48] & BIT(7)) || !le_sci_capable(hdev))
+		return 0;
+
+	return __hci_cmd_sync_status(hdev, HCI_OP_LE_READ_CONN_INTERVAL,
+				     0, NULL, HCI_CMD_TIMEOUT);
+}
+
+/* Set Default Connection Rate Parameters if command is supported, SCI feature
+ * bit is marked as supported and at least one of the supported SCI groups
+ * exists.
+ */
+static int hci_le_set_def_rate_sync(struct hci_dev *hdev)
+{
+	struct hci_cp_le_set_def_rate cp;
+	struct sci_group *grp, *tmp;
+	__u16 min = 0, max = 0;
+
+	if (!(hdev->commands[48] & BIT(6)) || !le_sci_capable(hdev) ||
+	    list_empty(&hdev->sci_groups))
+		return 0;
+
+	memset(&cp, 0, sizeof(cp));
+
+	/* Iterate over the SCI groups and find the widest supported connection
+	 * interval range to maximize compatibility with peer devices.
+	 */
+	list_for_each_entry_safe(grp, tmp, &hdev->sci_groups, list) {
+		if (!min == 0 || grp->min < min)
+			min = grp->min;
+
+		if (!max == 0 || grp->max > max)
+			max = grp->max;
+	}
+
+	cp.interval_min = cpu_to_le16(min);
+	cp.interval_max = cpu_to_le16(max);
+
+	/* HOG 1.2 Table 7.4. Modes with recommended parameter values suggests
+	 * subrate 1-4 for all modes so use that as default.
+	 */
+	cp.subrate_min = cpu_to_le16(0x0001);
+	cp.subrate_max = cpu_to_le16(0x0004);
+
+	/* HIP 1.2 Table 7.5. Modes with recommended parameter values suggests
+	 * max latency of 0 for all modes expect low power.
+	 */
+	cp.max_latency = 0x0000;
+
+	/* HIP 1.2 Table 7.5. Modes with recommended parameter values suggests
+	 * continuation number 1 for full range.
+	 */
+	cp.cont_num = cpu_to_le16(0x0001);
+
+	/* HOG 1.2 Table 7.4. Modes with recommended parameter values states
+	 * that link supervision timeout should be: Greater than or equal to
+	 * (1 + Peripheral Latency) x Subrate max x Connection Interval max x 2.
+	 */
+	cp.supv_timeout = cpu_to_le16((1 + 0) * 0x0004 * max * 2 / 10);
+
+	cp.min_ce_len = cpu_to_le16(min);
+	cp.max_ce_len = cpu_to_le16(max);
+
+	return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_DEF_RATE,
+				     sizeof(cp), &cp, HCI_CMD_TIMEOUT);
+}
+
 static const struct hci_init_stage le_init4[] = {
 	/* HCI_OP_LE_WRITE_DEF_DATA_LEN */
 	HCI_INIT(hci_le_set_write_def_data_len_sync),
 	/* HCI_OP_LE_SET_DEFAULT_PHY */
 	HCI_INIT(hci_le_set_default_phy_sync),
+	/* HCI_OP_LE_READ_CONN_INTERVAL */
+	HCI_INIT(hci_le_read_conn_interval_sync),
+	/* HCI_OP_LE_SET_DEF_RATE */
+	HCI_INIT(hci_le_set_def_rate_sync),
 	{}
 };
 
-- 
2.53.0


^ permalink raw reply related

* [PATCH v2 2/2] Bluetooth: MGMT: Add SCI setting bit(25)
From: Luiz Augusto von Dentz @ 2026-05-06 16:06 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <20260506160651.1585012-1-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This adds MGMT_SETTING_SCI(25) which indicates that the controller is
support SCI feature.

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
 include/net/bluetooth/hci_core.h | 2 ++
 include/net/bluetooth/mgmt.h     | 1 +
 net/bluetooth/mgmt.c             | 6 ++++++
 3 files changed, 9 insertions(+)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 61872403fe65..84a1ee798da1 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -2094,6 +2094,8 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
 /* Shorter Connection Intervals support */
 #define le_sci_capable(dev) \
 	((dev)->le_features[9] & HCI_LE_SCI)
+#define le_sci_enabled(dev) \
+	(le_enabled(dev) && le_sci_capable(dev))
 
 void hci_sci_groups_clear(struct hci_dev *hdev);
 
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 8234915854b6..dfd264f0bac7 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -121,6 +121,7 @@ struct mgmt_rp_read_index_list {
 #define MGMT_SETTING_LL_PRIVACY		BIT(22)
 #define MGMT_SETTING_PAST_SENDER	BIT(23)
 #define MGMT_SETTING_PAST_RECEIVER	BIT(24)
+#define MGMT_SETTING_SCI		BIT(25)
 
 #define MGMT_OP_READ_INFO		0x0004
 #define MGMT_READ_INFO_SIZE		0
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index b05bb380e5f8..1ea06ae1efdc 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -864,6 +864,9 @@ static u32 get_supported_settings(struct hci_dev *hdev)
 	if (past_receiver_capable(hdev))
 		settings |= MGMT_SETTING_PAST_RECEIVER;
 
+	if (le_sci_capable(hdev))
+		settings |= MGMT_SETTING_SCI;
+
 	settings |= MGMT_SETTING_PHY_CONFIGURATION;
 
 	return settings;
@@ -955,6 +958,9 @@ static u32 get_current_settings(struct hci_dev *hdev)
 	if (past_receiver_enabled(hdev))
 		settings |= MGMT_SETTING_PAST_RECEIVER;
 
+	if (le_sci_enabled(hdev))
+		settings |= MGMT_SETTING_SCI;
+
 	return settings;
 }
 
-- 
2.53.0


^ permalink raw reply related

* Re: [PATCH v4] Bluetooth: serialize accept_q access
From: Jann Horn @ 2026-05-06 17:04 UTC (permalink / raw)
  To: Ren Wei, luiz.dentz
  Cc: linux-bluetooth, netdev, marcel, davem, edumazet, kuba, pabeni,
	horms, yuantan098, yifanwucs, tomapufckgml, bird, wangjiexun2025
In-Reply-To: <20260506114338.2873496-1-n05ec@lzu.edu.cn>

[-- Attachment #1: Type: text/plain, Size: 10085 bytes --]

On Wed, May 6, 2026 at 1:43 PM Ren Wei <n05ec@lzu.edu.cn> wrote:
> bt_sock_poll() walks the accept queue without synchronization, while
> child teardown can unlink the same socket and drop its last reference.
> The unsynchronized accept queue walk has existed since the initial
> Bluetooth import.
>
> Protect accept_q with a dedicated lock for queue updates and polling.
> Also rework bt_accept_dequeue() to take temporary child references under
> the queue lock before dropping it and locking the child socket.
>
> Fixes: 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 ("Linux-2.6.12-rc2")
> Cc: stable@vger.kernel.org
> Reported-by: Jann Horn <jannh@google.com>
> Reported-by: Yuan Tan <yuantan098@gmail.com>
> Reported-by: Yifan Wu <yifanwucs@gmail.com>
> Reported-by: Juefei Pu <tomapufckgml@gmail.com>
> Reported-by: Xin Liu <bird@lzu.edu.cn>
> Signed-off-by: Jiexun Wang <wangjiexun2025@gmail.com>
> Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>

The patch looks good to me. I have some comments below, but they're
not important - from my perspective, this patch is ready to land in
the tree.

Reviewed-by: Jann Horn <jannh@google.com>

> ---
> Changes in v4:
> - no functional changes
> - clarify that the race dates back to the initial Bluetooth import
> - update trailers
>   I noticed Jann also proposed a fix at
>   https://patchwork.kernel.org/project/bluetooth/patch/20260504-bluetooth-accept-uaf-fix-v1-1-1ca63c0efadd@google.com/,
>   so we're adding his Reported-by tag here. Please let us know if this
>   isn't appropriate.

Thanks for letting me know that my patch was redundant, and for
listing me in Reported-by.
This addresses the race I described.
(You could add the line
"Closes: https://lore.kernel.org/r/20260504-bluetooth-accept-uaf-fix-v1-1-1ca63c0efadd@google.com"
after the "Reported-by: Jann Horn <jannh@google.com>".)

[...]
> @@ -254,45 +258,72 @@ EXPORT_SYMBOL(bt_accept_enqueue);
>   */
>  void bt_accept_unlink(struct sock *sk)
>  {
> +       struct sock *parent = bt_sk(sk)->parent;
> +
>         BT_DBG("sk %p state %d", sk, sk->sk_state);
>
> +       spin_lock_bh(&bt_sk(parent)->accept_q_lock);
>         list_del_init(&bt_sk(sk)->accept_q);
> -       sk_acceptq_removed(bt_sk(sk)->parent);
> +       sk_acceptq_removed(parent);
> +       spin_unlock_bh(&bt_sk(parent)->accept_q_lock);
>         bt_sk(sk)->parent = NULL;
>         sock_put(sk);
>  }
>  EXPORT_SYMBOL(bt_accept_unlink);
>
> +static struct sock *bt_accept_get(struct sock *parent, struct sock *sk)
> +{
> +       struct bt_sock *bt = bt_sk(parent);
> +       struct sock *next = NULL;
> +
> +       /* accept_q is modified from child teardown paths too, so take a
> +        * temporary reference before dropping the queue lock.
> +        */
> +       spin_lock_bh(&bt->accept_q_lock);
> +
> +       if (sk) {
> +               if (bt_sk(sk)->parent != parent)
> +                       goto out;

This check seems redundant? The caller already bailed out if
"bt_sk(sk)->parent != parent", and lock_sock(sk) ensures that
bt_sk(sk)->parent can't change concurrently because bt_accept_unlink()
is also protected by lock_sock() or lock_sock_nested(), as the comment
above bt_accept_unlink() documents.

> +
> +               if (!list_is_last(&bt_sk(sk)->accept_q, &bt->accept_q)) {
> +                       next = &list_next_entry(bt_sk(sk), accept_q)->sk;
> +                       sock_hold(next);
> +               }
> +       } else if (!list_empty(&bt->accept_q)) {
> +               next = &list_first_entry(&bt->accept_q,
> +                                        struct bt_sock, accept_q)->sk;
> +               sock_hold(next);
> +       }
> +
> +out:
> +       spin_unlock_bh(&bt->accept_q_lock);
> +       return next;
> +}

Hmm. This looks a bit complicated to me, and I find it hard to reason
about how accept_q walks are restarted after temporarily dropping the
lock; I think it would be nice if you could instead walk the
->accept_q while holding the accept_q_lock until you identify a socket
with the right ->sk_state, then drop the accept_q_lock and lock the
sock. Something like this diff on top of your patch (completely
untested); I have attached a properly formatted version of this diff
that you can apply with "git apply":

```
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index 9d68dd86023c..26e7c7198522 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -271,50 +271,36 @@ void bt_accept_unlink(struct sock *sk)
 }
 EXPORT_SYMBOL(bt_accept_unlink);

-static struct sock *bt_accept_get(struct sock *parent, struct sock *sk)
-{
-       struct bt_sock *bt = bt_sk(parent);
-       struct sock *next = NULL;
-
-       /* accept_q is modified from child teardown paths too, so take a
-        * temporary reference before dropping the queue lock.
-        */
-       spin_lock_bh(&bt->accept_q_lock);
-
-       if (sk) {
-               if (bt_sk(sk)->parent != parent)
-                       goto out;
-
-               if (!list_is_last(&bt_sk(sk)->accept_q, &bt->accept_q)) {
-                       next = &list_next_entry(bt_sk(sk), accept_q)->sk;
-                       sock_hold(next);
-               }
-       } else if (!list_empty(&bt->accept_q)) {
-               next = &list_first_entry(&bt->accept_q,
-                                        struct bt_sock, accept_q)->sk;
-               sock_hold(next);
-       }
-
-out:
-       spin_unlock_bh(&bt->accept_q_lock);
-       return next;
-}
-
 struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)
 {
-       struct sock *sk, *next;
+       struct bt_sock *s;
+       struct sock *sk;

        BT_DBG("parent %p", parent);

 restart:
-       for (sk = bt_accept_get(parent, NULL); sk; sk = next) {
+       spin_lock_bh(&bt_sk(parent)->accept_q_lock);
+       list_for_each_entry(s, &bt_sk(parent)->accept_q, accept_q) {
+               unsigned char state;
+
+               sk = &s->sk;
+
+               /* lockless version of the checks below */
+               state = data_race(READ_ONCE(sk->sk_state));
+               if (state != BT_CLOSED && state != BT_CONNECTED && newsock &&
+                   !test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags))
+                       continue;
+
                /* Prevent early freeing of sk due to unlink and sock_kill */
+               sock_hold(sk);
+               spin_unlock_bh(&bt_sk(parent)->accept_q_lock);
                lock_sock(sk);
+               /* socket is now locked, redo checks reliably */

                /* Check sk has not already been unlinked via
                 * bt_accept_unlink() due to serialisation caused by sk locking
                 */
-               if (bt_sk(sk)->parent != parent) {
+               if (s->parent != parent) {
                        BT_DBG("sk %p, already unlinked", sk);
                        release_sock(sk);
                        sock_put(sk);
@@ -322,8 +308,6 @@ struct sock *bt_accept_dequeue(struct sock
*parent, struct socket *newsock)
                        goto restart;
                }

-               next = bt_accept_get(parent, sk);
-
                /* sk is safely in the parent list so reduce reference count */
                sock_put(sk);

@@ -331,7 +315,7 @@ struct sock *bt_accept_dequeue(struct sock
*parent, struct socket *newsock)
                if (sk->sk_state == BT_CLOSED) {
                        bt_accept_unlink(sk);
                        release_sock(sk);
-                       continue;
+                       goto restart;
                }

                if (sk->sk_state == BT_CONNECTED || !newsock ||
@@ -341,12 +325,11 @@ struct sock *bt_accept_dequeue(struct sock
*parent, struct socket *newsock)
                                sock_graft(sk, newsock);

                        release_sock(sk);
-                       if (next)
-                               sock_put(next);
                        return sk;
                }

                release_sock(sk);
+               goto restart;
        }

        return NULL;
```

I think this makes the code simpler, and it reduces the line count;
however, I think your approach is okay too, so it would also be fine
to keep your approach if you prefer.

[...]
> @@ -518,18 +551,28 @@ EXPORT_SYMBOL(bt_sock_stream_recvmsg);
>
>  static inline __poll_t bt_accept_poll(struct sock *parent)
>  {
> -       struct bt_sock *s, *n;
> +       struct bt_sock *bt = bt_sk(parent);
> +       struct bt_sock *s;
>         struct sock *sk;
> +       __poll_t mask = 0;
> +
> +       spin_lock_bh(&bt->accept_q_lock);
> +       list_for_each_entry(s, &bt->accept_q, accept_q) {
> +               int state;
>
> -       list_for_each_entry_safe(s, n, &bt_sk(parent)->accept_q, accept_q) {
>                 sk = (struct sock *)s;
> -               if (sk->sk_state == BT_CONNECTED ||
> -                   (test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags) &&
> -                    sk->sk_state == BT_CONNECT2))
> -                       return EPOLLIN | EPOLLRDNORM;
> +               state = READ_ONCE(sk->sk_state);

nitpick: This READ_ONCE() is not synchronized with a corresponding
WRITE_ONCE(); that's not really clean, and it might be appropriate to
mark this with data_race() if this is intentionally racy with
potentially-torn stores. But that's a minor detail.


> +
> +               if (state == BT_CONNECTED ||
> +                   (test_bit(BT_SK_DEFER_SETUP, &bt->flags) &&
> +                    state == BT_CONNECT2)) {
> +                       mask = EPOLLIN | EPOLLRDNORM;
> +                       break;
> +               }
>         }
> +       spin_unlock_bh(&bt->accept_q_lock);
>
> -       return 0;
> +       return mask;
>  }
>
>  __poll_t bt_sock_poll(struct file *file, struct socket *sock,
> --
> 2.34.1
>

[-- Attachment #2: locked-walk.diff --]
[-- Type: application/x-patch, Size: 2914 bytes --]

^ permalink raw reply related

* [bluez/bluez]
From: BluezTestBot @ 2026-05-06 17:18 UTC (permalink / raw)
  To: linux-bluetooth

  Branch: refs/heads/1090349
  Home:   https://github.com/bluez/bluez

To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications

^ permalink raw reply

* RE: Bluetooth: L2CAP: avoid using hci_conn after dropping hold
From: bluez.test.bot @ 2026-05-06 17:39 UTC (permalink / raw)
  To: linux-bluetooth, zzzccc427
In-Reply-To: <20260506155313.1412894-1-zzzccc427@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 4632 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=1090570

---Test result---

Test Summary:
CheckPatch                    PASS      0.76 seconds
GitLint                       PASS      0.35 seconds
SubjectPrefix                 PASS      0.13 seconds
BuildKernel                   PASS      24.95 seconds
CheckAllWarning               PASS      28.20 seconds
CheckSparse                   PASS      26.80 seconds
BuildKernel32                 PASS      24.75 seconds
TestRunnerSetup               PASS      530.45 seconds
TestRunner_l2cap-tester       FAIL      20.24 seconds
IncrementalBuild              PASS      25.67 seconds

Details
##############################
Test: TestRunner_l2cap-tester - FAIL
Desc: Run l2cap-tester with test-runner
Output:
Crash detected:
==33==    by 0x13350F: tester_run (tester.c:1085)
==33==    by 0x1142AD: main (l2cap-tester.c:3295)
==33==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==33== 
==33== 
==33== Process terminating with default action of signal 11 (SIGSEGV)
==33==  Access not within mapped region at address 0x0
==33==    at 0x483FF54: __strcmp_sse2 (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==33==    by 0x115C46: read_info_callback (l2cap-tester.c:156)
==33==    by 0x12E860: request_complete (mgmt.c:320)
==33==    by 0x12F2F5: can_read_data (mgmt.c:408)
==33==    by 0x131D68: watch_callback (io-glib.c:173)
==33==    by 0x48A304D: g_main_context_dispatch (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==33==    by 0x48A33FF: ??? (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==33==    by 0x48A36F2: g_main_loop_run (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==33==    by 0x133B18: mainloop_run (mainloop-glib.c:65)
==33==    by 0x133F4F: mainloop_run_with_signal (mainloop-notify.c:196)
==33==    by 0x13350F: tester_run (tester.c:1085)
==33==    by 0x1142AD: main (l2cap-tester.c:3295)
==33==  If you believe this happened as a result of a stack
==33==  overflow in your program's main thread (unlikely but
==33==  possible), you can try to increase the size of the
==33==  main thread stack using the --main-stacksize= flag.
==33==  The main thread stack size used in this run was 8388608.
==33== 
Valgrind errors:
==33==    by 0x115C46: read_info_callback (l2cap-tester.c:156)
==33==    by 0x12E860: request_complete (mgmt.c:320)
==33==    by 0x12F2F5: can_read_data (mgmt.c:408)
==33==    by 0x131D68: watch_callback (io-glib.c:173)
==33==    by 0x48A304D: g_main_context_dispatch (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==33==    by 0x48A33FF: ??? (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==33==    by 0x48A36F2: g_main_loop_run (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==33==    by 0x133B18: mainloop_run (mainloop-glib.c:65)
==33==    by 0x133F4F: mainloop_run_with_signal (mainloop-notify.c:196)
==33==    by 0x13350F: tester_run (tester.c:1085)
==33==    by 0x1142AD: main (l2cap-tester.c:3295)
==33==  If you believe this happened as a result of a stack
==33==  overflow in your program's main thread (unlikely but
==33==  possible), you can try to increase the size of the
==33==  main thread stack using the --main-stacksize= flag.
==33==  The main thread stack size used in this run was 8388608.
==33== 
==33== HEAP SUMMARY:
==33==     in use at exit: 66,009 bytes in 462 blocks
==33==   total heap usage: 592 allocs, 130 frees, 79,004 bytes allocated
==33== 
==33== LEAK SUMMARY:
==33==    definitely lost: 0 bytes in 0 blocks
==33==    indirectly lost: 0 bytes in 0 blocks
==33==      possibly lost: 0 bytes in 0 blocks
==33==    still reachable: 66,009 bytes in 462 blocks
==33==         suppressed: 0 bytes in 0 blocks
==33== Rerun with --leak-check=full to see details of leaked memory
==33== 
==33== For lists of detected and suppressed errors, rerun with: -s
==33== ERROR SUMMARY: 51 errors from 3 contexts (suppressed: 0 from 0)
Crash detected:
==33==         suppressed: 0 bytes in 0 blocks
==33== Rerun with --leak-check=full to see details of leaked memory
==33== 
==33== For lists of detected and suppressed errors, rerun with: -s
==33== ERROR SUMMARY: 51 errors from 3 contexts (suppressed: 0 from 0)
Segmentation fault
Process 32 exited with status 139
reboot: Restarting system
reboot: machine restart
No test result found


https://github.com/bluez/bluetooth-next/pull/149

---
Regards,
Linux Bluetooth


^ permalink raw reply

* RE: [v2,1/2] Bluetooth: HCI: Add initial support for Short Connection Interval feature
From: bluez.test.bot @ 2026-05-06 17:53 UTC (permalink / raw)
  To: linux-bluetooth, luiz.dentz
In-Reply-To: <20260506160651.1585012-1-luiz.dentz@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 18767 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=1090572

---Test result---

Test Summary:
CheckPatch                    FAIL      2.47 seconds
GitLint                       FAIL      1.12 seconds
SubjectPrefix                 PASS      0.14 seconds
BuildKernel                   PASS      26.59 seconds
CheckAllWarning               PASS      28.99 seconds
CheckSparse                   PASS      27.43 seconds
BuildKernel32                 PASS      25.44 seconds
TestRunnerSetup               PASS      577.31 seconds
TestRunner_l2cap-tester       FAIL      18.84 seconds
TestRunner_iso-tester         PASS      311.35 seconds
TestRunner_bnep-tester        FAIL      18.23 seconds
TestRunner_mgmt-tester        FAIL      23.63 seconds
TestRunner_rfcomm-tester      PASS      40.63 seconds
TestRunner_sco-tester         PASS      79.85 seconds
TestRunner_ioctl-tester       FAIL      49.58 seconds
TestRunner_mesh-tester        PASS      38.97 seconds
TestRunner_smp-tester         PASS      17.68 seconds
TestRunner_userchan-tester    FAIL      18.28 seconds
TestRunner_6lowpan-tester     PASS      34.60 seconds
IncrementalBuild              PASS      42.57 seconds

Details
##############################
Test: CheckPatch - FAIL
Desc: Run checkpatch.pl script
Output:
[v2,1/2] Bluetooth: HCI: Add initial support for Short Connection Interval feature
WARNING: Possible unnecessary 'out of memory' message
#317: FILE: net/bluetooth/hci_event.c:3989:
+		if (!sgrp) {
+			bt_dev_err(hdev, "can't allocate memory for SCI group");

total: 0 errors, 1 warnings, 0 checks, 335 lines checked

NOTE: For some of the reported defects, checkpatch may be able to
      mechanically convert to the typical style using --fix or --fix-inplace.

/github/workspace/src/patch/14557669.patch has style problems, please review.

NOTE: Ignored message types: UNKNOWN_COMMIT_ID

NOTE: If any of the errors are false positives, please report
      them to the maintainer, see CHECKPATCH in MAINTAINERS.


##############################
Test: GitLint - FAIL
Desc: Run gitlint
Output:
[v2,1/2] Bluetooth: HCI: Add initial support for Short Connection Interval feature

WARNING: I3 - ignore-body-lines: gitlint will be switching from using Python regex 'match' (match beginning) to 'search' (match anywhere) semantics. Please review your ignore-body-lines.regex option accordingly. To remove this warning, set general.regex-style-search=True. More details: https://jorisroovers.github.io/gitlint/configuration/#regex-style-search
1: T1 Title exceeds max length (82>80): "[v2,1/2] Bluetooth: HCI: Add initial support for Short Connection Interval feature"
##############################
Test: TestRunner_l2cap-tester - FAIL
Desc: Run l2cap-tester with test-runner
Output:
Crash detected:
==34==    by 0x13350F: tester_run (tester.c:1085)
==34==    by 0x1142AD: main (l2cap-tester.c:3295)
==34==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==34== 
==34== 
==34== Process terminating with default action of signal 11 (SIGSEGV)
==34==  Access not within mapped region at address 0x0
==34==    at 0x483FF54: __strcmp_sse2 (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==34==    by 0x115C46: read_info_callback (l2cap-tester.c:156)
==34==    by 0x12E860: request_complete (mgmt.c:320)
==34==    by 0x12F2F5: can_read_data (mgmt.c:408)
==34==    by 0x131D68: watch_callback (io-glib.c:173)
==34==    by 0x48A304D: g_main_context_dispatch (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==34==    by 0x48A33FF: ??? (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==34==    by 0x48A36F2: g_main_loop_run (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==34==    by 0x133B18: mainloop_run (mainloop-glib.c:65)
==34==    by 0x133F4F: mainloop_run_with_signal (mainloop-notify.c:196)
==34==    by 0x13350F: tester_run (tester.c:1085)
==34==    by 0x1142AD: main (l2cap-tester.c:3295)
==34==  If you believe this happened as a result of a stack
==34==  overflow in your program's main thread (unlikely but
==34==  possible), you can try to increase the size of the
==34==  main thread stack using the --main-stacksize= flag.
==34==  The main thread stack size used in this run was 8388608.
==34== 
Valgrind errors:
==34==    by 0x115C46: read_info_callback (l2cap-tester.c:156)
==34==    by 0x12E860: request_complete (mgmt.c:320)
==34==    by 0x12F2F5: can_read_data (mgmt.c:408)
==34==    by 0x131D68: watch_callback (io-glib.c:173)
==34==    by 0x48A304D: g_main_context_dispatch (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==34==    by 0x48A33FF: ??? (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==34==    by 0x48A36F2: g_main_loop_run (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==34==    by 0x133B18: mainloop_run (mainloop-glib.c:65)
==34==    by 0x133F4F: mainloop_run_with_signal (mainloop-notify.c:196)
==34==    by 0x13350F: tester_run (tester.c:1085)
==34==    by 0x1142AD: main (l2cap-tester.c:3295)
==34==  If you believe this happened as a result of a stack
==34==  overflow in your program's main thread (unlikely but
==34==  possible), you can try to increase the size of the
==34==  main thread stack using the --main-stacksize= flag.
==34==  The main thread stack size used in this run was 8388608.
==34== 
==34== HEAP SUMMARY:
==34==     in use at exit: 66,009 bytes in 462 blocks
==34==   total heap usage: 592 allocs, 130 frees, 79,004 bytes allocated
==34== 
==34== LEAK SUMMARY:
==34==    definitely lost: 0 bytes in 0 blocks
==34==    indirectly lost: 0 bytes in 0 blocks
==34==      possibly lost: 0 bytes in 0 blocks
==34==    still reachable: 66,009 bytes in 462 blocks
==34==         suppressed: 0 bytes in 0 blocks
==34== Rerun with --leak-check=full to see details of leaked memory
==34== 
==34== For lists of detected and suppressed errors, rerun with: -s
==34== ERROR SUMMARY: 51 errors from 3 contexts (suppressed: 0 from 0)
Crash detected:
==34==         suppressed: 0 bytes in 0 blocks
==34== Rerun with --leak-check=full to see details of leaked memory
==34== 
==34== For lists of detected and suppressed errors, rerun with: -s
==34== ERROR SUMMARY: 51 errors from 3 contexts (suppressed: 0 from 0)
Segmentation fault
Process 33 exited with status 139
reboot: Restarting system
reboot: machine restart
No test result found
##############################
Test: TestRunner_bnep-tester - FAIL
Desc: Run bnep-tester with test-runner
Output:
Crash detected:
==34==    by 0x12CC4F: tester_run (tester.c:1085)
==34==    by 0x111CB3: main (bnep-tester.c:298)
==34==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==34== 
==34== 
==34== Process terminating with default action of signal 11 (SIGSEGV)
==34==  Access not within mapped region at address 0x0
==34==    at 0x483FF54: __strcmp_sse2 (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==34==    by 0x112206: read_info_callback (bnep-tester.c:101)
==34==    by 0x1281B0: request_complete (mgmt.c:320)
==34==    by 0x128B65: can_read_data (mgmt.c:408)
==34==    by 0x12B5D8: watch_callback (io-glib.c:173)
==34==    by 0x48A304D: g_main_context_dispatch (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==34==    by 0x48A33FF: ??? (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==34==    by 0x48A36F2: g_main_loop_run (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==34==    by 0x12D258: mainloop_run (mainloop-glib.c:65)
==34==    by 0x12D68F: mainloop_run_with_signal (mainloop-notify.c:196)
==34==    by 0x12CC4F: tester_run (tester.c:1085)
==34==    by 0x111CB3: main (bnep-tester.c:298)
==34==  If you believe this happened as a result of a stack
==34==  overflow in your program's main thread (unlikely but
==34==  possible), you can try to increase the size of the
==34==  main thread stack using the --main-stacksize= flag.
==34==  The main thread stack size used in this run was 8388608.
==34== 
Valgrind errors:
==34==    by 0x112206: read_info_callback (bnep-tester.c:101)
==34==    by 0x1281B0: request_complete (mgmt.c:320)
==34==    by 0x128B65: can_read_data (mgmt.c:408)
==34==    by 0x12B5D8: watch_callback (io-glib.c:173)
==34==    by 0x48A304D: g_main_context_dispatch (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==34==    by 0x48A33FF: ??? (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==34==    by 0x48A36F2: g_main_loop_run (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==34==    by 0x12D258: mainloop_run (mainloop-glib.c:65)
==34==    by 0x12D68F: mainloop_run_with_signal (mainloop-notify.c:196)
==34==    by 0x12CC4F: tester_run (tester.c:1085)
==34==    by 0x111CB3: main (bnep-tester.c:298)
==34==  If you believe this happened as a result of a stack
==34==  overflow in your program's main thread (unlikely but
==34==  possible), you can try to increase the size of the
==34==  main thread stack using the --main-stacksize= flag.
==34==  The main thread stack size used in this run was 8388608.
==34== 
==34== HEAP SUMMARY:
==34==     in use at exit: 25,264 bytes in 82 blocks
==34==   total heap usage: 212 allocs, 130 frees, 38,256 bytes allocated
==34== 
==34== LEAK SUMMARY:
==34==    definitely lost: 0 bytes in 0 blocks
==34==    indirectly lost: 0 bytes in 0 blocks
==34==      possibly lost: 0 bytes in 0 blocks
==34==    still reachable: 25,264 bytes in 82 blocks
==34==         suppressed: 0 bytes in 0 blocks
==34== Rerun with --leak-check=full to see details of leaked memory
==34== 
==34== For lists of detected and suppressed errors, rerun with: -s
==34== ERROR SUMMARY: 51 errors from 3 contexts (suppressed: 0 from 0)
Crash detected:
==34==         suppressed: 0 bytes in 0 blocks
==34== Rerun with --leak-check=full to see details of leaked memory
==34== 
==34== For lists of detected and suppressed errors, rerun with: -s
==34== ERROR SUMMARY: 51 errors from 3 contexts (suppressed: 0 from 0)
Segmentation fault
Process 33 exited with status 139
reboot: Restarting system
reboot: machine restart
No test result found
##############################
Test: TestRunner_mgmt-tester - FAIL
Desc: Run mgmt-tester with test-runner
Output:
Crash detected:
==34==    by 0x14F4FF: tester_run (tester.c:1085)
==34==    by 0x12B999: main (mgmt-tester.c:15134)
==34==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==34== 
==34== 
==34== Process terminating with default action of signal 11 (SIGSEGV)
==34==  Access not within mapped region at address 0x0
==34==    at 0x483FF54: __strcmp_sse2 (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==34==    by 0x12F8E8: read_info_callback (mgmt-tester.c:181)
==34==    by 0x14A740: request_complete (mgmt.c:320)
==34==    by 0x14B2F5: can_read_data (mgmt.c:408)
==34==    by 0x14DD68: watch_callback (io-glib.c:173)
==34==    by 0x48A304D: g_main_context_dispatch (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==34==    by 0x48A33FF: ??? (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==34==    by 0x48A36F2: g_main_loop_run (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==34==    by 0x14FB08: mainloop_run (mainloop-glib.c:65)
==34==    by 0x14FF3F: mainloop_run_with_signal (mainloop-notify.c:196)
==34==    by 0x14F4FF: tester_run (tester.c:1085)
==34==    by 0x12B999: main (mgmt-tester.c:15134)
==34==  If you believe this happened as a result of a stack
==34==  overflow in your program's main thread (unlikely but
==34==  possible), you can try to increase the size of the
==34==  main thread stack using the --main-stacksize= flag.
==34==  The main thread stack size used in this run was 8388608.
==34== 
Valgrind errors:
==34==    by 0x12F8E8: read_info_callback (mgmt-tester.c:181)
==34==    by 0x14A740: request_complete (mgmt.c:320)
==34==    by 0x14B2F5: can_read_data (mgmt.c:408)
==34==    by 0x14DD68: watch_callback (io-glib.c:173)
==34==    by 0x48A304D: g_main_context_dispatch (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==34==    by 0x48A33FF: ??? (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==34==    by 0x48A36F2: g_main_loop_run (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==34==    by 0x14FB08: mainloop_run (mainloop-glib.c:65)
==34==    by 0x14FF3F: mainloop_run_with_signal (mainloop-notify.c:196)
==34==    by 0x14F4FF: tester_run (tester.c:1085)
==34==    by 0x12B999: main (mgmt-tester.c:15134)
==34==  If you believe this happened as a result of a stack
==34==  overflow in your program's main thread (unlikely but
==34==  possible), you can try to increase the size of the
==34==  main thread stack using the --main-stacksize= flag.
==34==  The main thread stack size used in this run was 8388608.
==34== 
==34== HEAP SUMMARY:
==34==     in use at exit: 182,263 bytes in 2,112 blocks
==34==   total heap usage: 2,389 allocs, 277 frees, 204,641 bytes allocated
==34== 
==34== LEAK SUMMARY:
==34==    definitely lost: 0 bytes in 0 blocks
==34==    indirectly lost: 0 bytes in 0 blocks
==34==      possibly lost: 0 bytes in 0 blocks
==34==    still reachable: 182,263 bytes in 2,112 blocks
==34==         suppressed: 0 bytes in 0 blocks
==34== Rerun with --leak-check=full to see details of leaked memory
==34== 
==34== For lists of detected and suppressed errors, rerun with: -s
==34== ERROR SUMMARY: 51 errors from 3 contexts (suppressed: 0 from 0)
Crash detected:
==34==         suppressed: 0 bytes in 0 blocks
==34== Rerun with --leak-check=full to see details of leaked memory
==34== 
==34== For lists of detected and suppressed errors, rerun with: -s
==34== ERROR SUMMARY: 51 errors from 3 contexts (suppressed: 0 from 0)
Segmentation fault
Process 33 exited with status 139
reboot: Restarting system
reboot: machine restart
No test result found
##############################
Test: TestRunner_ioctl-tester - FAIL
Desc: Run ioctl-tester with test-runner
Output:
Total: 28, Passed: 0 (0.0%), Failed: 11, Not Run: 17

Failed Test Cases
Device List                                          Timed out  -31.728 seconds
Device Info                                          Timed out   -6.907 seconds
Reset Stat                                           Timed out   -6.913 seconds
Set Link Mode - ACCEPT                               Timed out   -6.919 seconds
Set Pkt Type - DM                                    Timed out  -15.160 seconds
Set Pkt Type - DH                                    Timed out  -15.166 seconds
Set Pkt Type - HV                                    Timed out  -15.172 seconds
Set Pkt Type - 2-DH                                  Timed out  -15.179 seconds
Set Pkt Type - 2-DH                                  Timed out  -15.185 seconds
Set Pkt Type - ALL                                   Timed out  -15.191 seconds
Set ACL MTU - 1                                      Timed out  -15.197 seconds
##############################
Test: TestRunner_userchan-tester - FAIL
Desc: Run userchan-tester with test-runner
Output:
Crash detected:
==34==    by 0x12D77F: tester_run (tester.c:1085)
==34==    by 0x111DFB: main (userchan-tester.c:392)
==34==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==34== 
==34== 
==34== Process terminating with default action of signal 11 (SIGSEGV)
==34==  Access not within mapped region at address 0x0
==34==    at 0x483FF54: __strcmp_sse2 (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==34==    by 0x11250B: read_info_callback (userchan-tester.c:88)
==34==    by 0x128450: request_complete (mgmt.c:320)
==34==    by 0x128E95: can_read_data (mgmt.c:408)
==34==    by 0x12C108: watch_callback (io-glib.c:173)
==34==    by 0x48A304D: g_main_context_dispatch (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==34==    by 0x48A33FF: ??? (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==34==    by 0x48A36F2: g_main_loop_run (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==34==    by 0x12DD88: mainloop_run (mainloop-glib.c:65)
==34==    by 0x12E1BF: mainloop_run_with_signal (mainloop-notify.c:196)
==34==    by 0x12D77F: tester_run (tester.c:1085)
==34==    by 0x111DFB: main (userchan-tester.c:392)
==34==  If you believe this happened as a result of a stack
==34==  overflow in your program's main thread (unlikely but
==34==  possible), you can try to increase the size of the
==34==  main thread stack using the --main-stacksize= flag.
==34==  The main thread stack size used in this run was 8388608.
==34== 
Valgrind errors:
==34==    by 0x11250B: read_info_callback (userchan-tester.c:88)
==34==    by 0x128450: request_complete (mgmt.c:320)
==34==    by 0x128E95: can_read_data (mgmt.c:408)
==34==    by 0x12C108: watch_callback (io-glib.c:173)
==34==    by 0x48A304D: g_main_context_dispatch (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==34==    by 0x48A33FF: ??? (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==34==    by 0x48A36F2: g_main_loop_run (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==34==    by 0x12DD88: mainloop_run (mainloop-glib.c:65)
==34==    by 0x12E1BF: mainloop_run_with_signal (mainloop-notify.c:196)
==34==    by 0x12D77F: tester_run (tester.c:1085)
==34==    by 0x111DFB: main (userchan-tester.c:392)
==34==  If you believe this happened as a result of a stack
==34==  overflow in your program's main thread (unlikely but
==34==  possible), you can try to increase the size of the
==34==  main thread stack using the --main-stacksize= flag.
==34==  The main thread stack size used in this run was 8388608.
==34== 
==34== HEAP SUMMARY:
==34==     in use at exit: 26,001 bytes in 92 blocks
==34==   total heap usage: 222 allocs, 130 frees, 38,997 bytes allocated
==34== 
==34== LEAK SUMMARY:
==34==    definitely lost: 0 bytes in 0 blocks
==34==    indirectly lost: 0 bytes in 0 blocks
==34==      possibly lost: 0 bytes in 0 blocks
==34==    still reachable: 26,001 bytes in 92 blocks
==34==         suppressed: 0 bytes in 0 blocks
==34== Rerun with --leak-check=full to see details of leaked memory
==34== 
==34== For lists of detected and suppressed errors, rerun with: -s
==34== ERROR SUMMARY: 51 errors from 3 contexts (suppressed: 0 from 0)
Crash detected:
==34==         suppressed: 0 bytes in 0 blocks
==34== Rerun with --leak-check=full to see details of leaked memory
==34== 
==34== For lists of detected and suppressed errors, rerun with: -s
==34== ERROR SUMMARY: 51 errors from 3 contexts (suppressed: 0 from 0)
Segmentation fault
Process 33 exited with status 139
reboot: Restarting system
reboot: machine restart
No test result found


https://github.com/bluez/bluetooth-next/pull/150

---
Regards,
Linux Bluetooth


^ permalink raw reply

* [PATCH BlueZ v1 1/3] tools/tester: Fix crash when hciemu_new fails
From: Luiz Augusto von Dentz @ 2026-05-06 19:41 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

When hciemu_new returns NULL, the mgmt object was not being unreferenced
before returning from the pre-setup failure path. This could lead to a
NULL dereference in read_info_callback when it later calls
hciemu_get_address on the NULL hciemu pointer.

Add mgmt_unref and return to the error path across all testers.
---
 tools/6lowpan-tester.c  | 2 ++
 tools/bnep-tester.c     | 3 +++
 tools/ioctl-tester.c    | 3 +++
 tools/iso-tester.c      | 2 ++
 tools/l2cap-tester.c    | 3 +++
 tools/mesh-tester.c     | 3 +++
 tools/mgmt-tester.c     | 3 +++
 tools/rfcomm-tester.c   | 3 +++
 tools/sco-tester.c      | 2 ++
 tools/smp-tester.c      | 3 +++
 tools/userchan-tester.c | 3 +++
 11 files changed, 30 insertions(+)

diff --git a/tools/6lowpan-tester.c b/tools/6lowpan-tester.c
index 65dba173b18e..2b43719f153e 100644
--- a/tools/6lowpan-tester.c
+++ b/tools/6lowpan-tester.c
@@ -181,6 +181,8 @@ static void read_index_list_callback(uint8_t status, uint16_t length,
 	if (!data->hciemu) {
 		tester_warn("Failed to setup HCI emulation");
 		tester_pre_setup_failed();
+		mgmt_unref(data->mgmt);
+		data->mgmt = NULL;
 		return;
 	}
 
diff --git a/tools/bnep-tester.c b/tools/bnep-tester.c
index 2a9b843098f4..581f54c20829 100644
--- a/tools/bnep-tester.c
+++ b/tools/bnep-tester.c
@@ -162,6 +162,9 @@ static void read_index_list_callback(uint8_t status, uint16_t length,
 	if (!data->hciemu) {
 		tester_warn("Failed to setup HCI emulation");
 		tester_pre_setup_failed();
+		mgmt_unref(data->mgmt);
+		data->mgmt = NULL;
+		return;
 	}
 
 	if (tester_use_debug())
diff --git a/tools/ioctl-tester.c b/tools/ioctl-tester.c
index e0627eef5bdc..969fbd955b76 100644
--- a/tools/ioctl-tester.c
+++ b/tools/ioctl-tester.c
@@ -230,6 +230,9 @@ static void read_index_list_callback(uint8_t status, uint16_t length,
 	if (!data->hciemu) {
 		tester_warn("Failed to setup HCI emulation");
 		tester_pre_setup_failed();
+		mgmt_unref(data->mgmt);
+		data->mgmt = NULL;
+		return;
 	}
 
 	if (tester_use_debug())
diff --git a/tools/iso-tester.c b/tools/iso-tester.c
index 4c30e9951bcb..8dfea0b417f0 100644
--- a/tools/iso-tester.c
+++ b/tools/iso-tester.c
@@ -637,6 +637,8 @@ static void read_index_list_callback(uint8_t status, uint16_t length,
 	if (!data->hciemu) {
 		tester_warn("Failed to setup HCI emulation");
 		tester_pre_setup_failed();
+		mgmt_unref(data->mgmt);
+		data->mgmt = NULL;
 		return;
 	}
 
diff --git a/tools/l2cap-tester.c b/tools/l2cap-tester.c
index c3aa96f84ea0..5c013d4704e5 100644
--- a/tools/l2cap-tester.c
+++ b/tools/l2cap-tester.c
@@ -217,6 +217,9 @@ static void read_index_list_callback(uint8_t status, uint16_t length,
 	if (!data->hciemu) {
 		tester_warn("Failed to setup HCI emulation");
 		tester_pre_setup_failed();
+		mgmt_unref(data->mgmt);
+		data->mgmt = NULL;
+		return;
 	}
 
 	if (tester_use_debug())
diff --git a/tools/mesh-tester.c b/tools/mesh-tester.c
index 7c42dff76fb1..27628b627957 100644
--- a/tools/mesh-tester.c
+++ b/tools/mesh-tester.c
@@ -419,6 +419,9 @@ static void read_index_list_callback(uint8_t status, uint16_t length,
 	if (!data->hciemu) {
 		tester_warn("Failed to setup HCI emulation");
 		test_pre_setup_failed();
+		mgmt_unref(data->mgmt);
+		data->mgmt = NULL;
+		return;
 	}
 
 	if (tester_use_debug())
diff --git a/tools/mgmt-tester.c b/tools/mgmt-tester.c
index 90dfa35272c0..213fd996b032 100644
--- a/tools/mgmt-tester.c
+++ b/tools/mgmt-tester.c
@@ -431,6 +431,9 @@ static void read_index_list_callback(uint8_t status, uint16_t length,
 	if (!data->hciemu) {
 		tester_warn("Failed to setup HCI emulation");
 		test_pre_setup_failed();
+		mgmt_unref(data->mgmt);
+		data->mgmt = NULL;
+		return;
 	}
 
 	if (tester_use_debug())
diff --git a/tools/rfcomm-tester.c b/tools/rfcomm-tester.c
index 25b3a41e0f4f..06e9fbdd6143 100644
--- a/tools/rfcomm-tester.c
+++ b/tools/rfcomm-tester.c
@@ -167,6 +167,9 @@ static void read_index_list_callback(uint8_t status, uint16_t length,
 	if (!data->hciemu) {
 		tester_warn("Failed to setup HCI emulation");
 		tester_pre_setup_failed();
+		mgmt_unref(data->mgmt);
+		data->mgmt = NULL;
+		return;
 	}
 
 	if (tester_use_debug())
diff --git a/tools/sco-tester.c b/tools/sco-tester.c
index 3d6b590924db..f09ba04aeaf7 100644
--- a/tools/sco-tester.c
+++ b/tools/sco-tester.c
@@ -195,6 +195,8 @@ static void read_index_list_callback(uint8_t status, uint16_t length,
 	if (!data->hciemu) {
 		tester_warn("Failed to setup HCI emulation");
 		tester_pre_setup_failed();
+		mgmt_unref(data->mgmt);
+		data->mgmt = NULL;
 		return;
 	}
 
diff --git a/tools/smp-tester.c b/tools/smp-tester.c
index 04b7ee088705..aaf149c0deb7 100644
--- a/tools/smp-tester.c
+++ b/tools/smp-tester.c
@@ -185,6 +185,9 @@ static void read_index_list_callback(uint8_t status, uint16_t length,
 	if (!data->hciemu) {
 		tester_warn("Failed to setup HCI emulation");
 		tester_pre_setup_failed();
+		mgmt_unref(data->mgmt);
+		data->mgmt = NULL;
+		return;
 	}
 
 	if (tester_use_debug())
diff --git a/tools/userchan-tester.c b/tools/userchan-tester.c
index f61d2779ed26..a03f64d84c0b 100644
--- a/tools/userchan-tester.c
+++ b/tools/userchan-tester.c
@@ -156,6 +156,9 @@ static void read_index_list_callback(uint8_t status, uint16_t length,
 	if (!data->hciemu) {
 		tester_warn("Failed to setup HCI emulation");
 		tester_pre_setup_failed();
+		mgmt_unref(data->mgmt);
+		data->mgmt = NULL;
+		return;
 	}
 
 	if (tester_use_debug())
-- 
2.53.0


^ permalink raw reply related

* [PATCH BlueZ v1 2/3] emulator/hciemu: Add hciemu_new_debug/hciemu_new_num_debug
From: Luiz Augusto von Dentz @ 2026-05-06 19:41 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <20260506194150.1701855-1-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

Add new constructors that accept debug callback and user_data parameters,
setting them up immediately after allocation so errors during early
initialization (create_vhci, hciemu_client_new) are captured by the debug
output.
---
 emulator/hciemu.c | 20 +++++++++++++++++++-
 emulator/hciemu.h | 11 +++++++++--
 2 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/emulator/hciemu.c b/emulator/hciemu.c
index 9534d82bac39..15d806a62aa6 100644
--- a/emulator/hciemu.c
+++ b/emulator/hciemu.c
@@ -396,7 +396,9 @@ static struct hciemu_client *hciemu_client_new(struct hciemu *hciemu,
 	return client;
 }
 
-struct hciemu *hciemu_new_num(enum hciemu_type type, uint8_t num)
+struct hciemu *hciemu_new_num_debug(enum hciemu_type type, uint8_t num,
+			hciemu_debug_func_t callback, void *user_data,
+			hciemu_destroy_func_t destroy)
 {
 
 	struct hciemu *hciemu;
@@ -409,6 +411,10 @@ struct hciemu *hciemu_new_num(enum hciemu_type type, uint8_t num)
 	if (!hciemu)
 		return NULL;
 
+	hciemu->debug_callback = callback;
+	hciemu->debug_destroy = destroy;
+	hciemu->debug_data = user_data;
+
 	switch (type) {
 	case HCIEMU_TYPE_BREDRLE:
 		hciemu->btdev_type = BTDEV_TYPE_BREDRLE;
@@ -465,11 +471,23 @@ struct hciemu *hciemu_new_num(enum hciemu_type type, uint8_t num)
 	return hciemu_ref(hciemu);
 }
 
+struct hciemu *hciemu_new_num(enum hciemu_type type, uint8_t num)
+{
+	return hciemu_new_num_debug(type, num, NULL, NULL, NULL);
+}
+
 struct hciemu *hciemu_new(enum hciemu_type type)
 {
 	return hciemu_new_num(type, 1);
 }
 
+struct hciemu *hciemu_new_debug(enum hciemu_type type,
+			hciemu_debug_func_t callback, void *user_data,
+			hciemu_destroy_func_t destroy)
+{
+	return hciemu_new_num_debug(type, 1, callback, user_data, destroy);
+}
+
 struct hciemu *hciemu_ref(struct hciemu *hciemu)
 {
 	if (!hciemu)
diff --git a/emulator/hciemu.h b/emulator/hciemu.h
index 1164be6510a3..e832d6350bb3 100644
--- a/emulator/hciemu.h
+++ b/emulator/hciemu.h
@@ -31,8 +31,17 @@ enum hciemu_hook_type {
 	HCIEMU_HOOK_POST_EVT,
 };
 
+typedef void (*hciemu_debug_func_t)(const char *str, void *user_data);
+typedef void (*hciemu_destroy_func_t)(void *user_data);
+
 struct hciemu *hciemu_new(enum hciemu_type type);
 struct hciemu *hciemu_new_num(enum hciemu_type type, uint8_t num);
+struct hciemu *hciemu_new_debug(enum hciemu_type type,
+			hciemu_debug_func_t callback, void *user_data,
+			hciemu_destroy_func_t destroy);
+struct hciemu *hciemu_new_num_debug(enum hciemu_type type, uint8_t num,
+			hciemu_debug_func_t callback, void *user_data,
+			hciemu_destroy_func_t destroy);
 
 struct hciemu *hciemu_ref(struct hciemu *hciemu);
 void hciemu_unref(struct hciemu *hciemu);
@@ -43,8 +52,6 @@ const uint8_t *hciemu_client_bdaddr(struct hciemu_client *client);
 bool hciemu_set_client_bdaddr(struct hciemu_client *client,
 				const uint8_t *bdaddr);
 
-typedef void (*hciemu_debug_func_t)(const char *str, void *user_data);
-typedef void (*hciemu_destroy_func_t)(void *user_data);
 bool hciemu_set_debug(struct hciemu *hciemu, hciemu_debug_func_t callback,
 			void *user_data, hciemu_destroy_func_t destroy);
 
-- 
2.53.0


^ permalink raw reply related

* [PATCH BlueZ v1 3/3] tools/tester: Retry with debug on hciemu_new failure
From: Luiz Augusto von Dentz @ 2026-05-06 19:41 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <20260506194150.1701855-1-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

When hciemu_new fails, retry using hciemu_new_debug to capture early
initialization errors before reporting the failure. This helps diagnose
issues like vhci or client creation failures in CI.
---
 tools/6lowpan-tester.c  | 3 +++
 tools/bnep-tester.c     | 3 +++
 tools/ioctl-tester.c    | 3 +++
 tools/iso-tester.c      | 4 ++++
 tools/l2cap-tester.c    | 3 +++
 tools/mesh-tester.c     | 3 +++
 tools/mgmt-tester.c     | 3 +++
 tools/rfcomm-tester.c   | 3 +++
 tools/sco-tester.c      | 3 +++
 tools/smp-tester.c      | 3 +++
 tools/userchan-tester.c | 3 +++
 11 files changed, 34 insertions(+)

diff --git a/tools/6lowpan-tester.c b/tools/6lowpan-tester.c
index 2b43719f153e..95fdf206fc0c 100644
--- a/tools/6lowpan-tester.c
+++ b/tools/6lowpan-tester.c
@@ -178,6 +178,9 @@ static void read_index_list_callback(uint8_t status, uint16_t length,
 					index_removed_callback, NULL, NULL);
 
 	data->hciemu = hciemu_new(HCIEMU_TYPE_LE);
+	if (!data->hciemu)
+		data->hciemu = hciemu_new_debug(HCIEMU_TYPE_LE, print_debug,
+							"hciemu: ", NULL);
 	if (!data->hciemu) {
 		tester_warn("Failed to setup HCI emulation");
 		tester_pre_setup_failed();
diff --git a/tools/bnep-tester.c b/tools/bnep-tester.c
index 581f54c20829..1c53d024c0f8 100644
--- a/tools/bnep-tester.c
+++ b/tools/bnep-tester.c
@@ -159,6 +159,9 @@ static void read_index_list_callback(uint8_t status, uint16_t length,
 					index_removed_callback, NULL, NULL);
 
 	data->hciemu = hciemu_new(data->hciemu_type);
+	if (!data->hciemu)
+		data->hciemu = hciemu_new_debug(data->hciemu_type, print_debug,
+							"hciemu: ", NULL);
 	if (!data->hciemu) {
 		tester_warn("Failed to setup HCI emulation");
 		tester_pre_setup_failed();
diff --git a/tools/ioctl-tester.c b/tools/ioctl-tester.c
index 969fbd955b76..e957b0d01bfa 100644
--- a/tools/ioctl-tester.c
+++ b/tools/ioctl-tester.c
@@ -227,6 +227,9 @@ static void read_index_list_callback(uint8_t status, uint16_t length,
 					index_removed_callback, NULL, NULL);
 
 	data->hciemu = hciemu_new(data->hciemu_type);
+	if (!data->hciemu)
+		data->hciemu = hciemu_new_debug(data->hciemu_type, print_debug,
+							"hciemu: ", NULL);
 	if (!data->hciemu) {
 		tester_warn("Failed to setup HCI emulation");
 		tester_pre_setup_failed();
diff --git a/tools/iso-tester.c b/tools/iso-tester.c
index 8dfea0b417f0..767ee0c57c47 100644
--- a/tools/iso-tester.c
+++ b/tools/iso-tester.c
@@ -634,6 +634,10 @@ static void read_index_list_callback(uint8_t status, uint16_t length,
 					index_removed_callback, NULL, NULL);
 
 	data->hciemu = hciemu_new_num(HCIEMU_TYPE_BREDRLE52, data->client_num);
+	if (!data->hciemu)
+		data->hciemu = hciemu_new_num_debug(HCIEMU_TYPE_BREDRLE52,
+						data->client_num, hciemu_debug,
+						"hciemu: ", NULL);
 	if (!data->hciemu) {
 		tester_warn("Failed to setup HCI emulation");
 		tester_pre_setup_failed();
diff --git a/tools/l2cap-tester.c b/tools/l2cap-tester.c
index 5c013d4704e5..a8cac3902b32 100644
--- a/tools/l2cap-tester.c
+++ b/tools/l2cap-tester.c
@@ -214,6 +214,9 @@ static void read_index_list_callback(uint8_t status, uint16_t length,
 					index_removed_callback, NULL, NULL);
 
 	data->hciemu = hciemu_new(data->hciemu_type);
+	if (!data->hciemu)
+		data->hciemu = hciemu_new_debug(data->hciemu_type, print_debug,
+							"hciemu: ", NULL);
 	if (!data->hciemu) {
 		tester_warn("Failed to setup HCI emulation");
 		tester_pre_setup_failed();
diff --git a/tools/mesh-tester.c b/tools/mesh-tester.c
index 27628b627957..4412bfdb727e 100644
--- a/tools/mesh-tester.c
+++ b/tools/mesh-tester.c
@@ -416,6 +416,9 @@ static void read_index_list_callback(uint8_t status, uint16_t length,
 			index_removed_callback, NULL, NULL);
 
 	data->hciemu = hciemu_new(data->hciemu_type);
+	if (!data->hciemu)
+		data->hciemu = hciemu_new_debug(data->hciemu_type, print_debug,
+							"hciemu: ", NULL);
 	if (!data->hciemu) {
 		tester_warn("Failed to setup HCI emulation");
 		test_pre_setup_failed();
diff --git a/tools/mgmt-tester.c b/tools/mgmt-tester.c
index 213fd996b032..4d28090271e9 100644
--- a/tools/mgmt-tester.c
+++ b/tools/mgmt-tester.c
@@ -428,6 +428,9 @@ static void read_index_list_callback(uint8_t status, uint16_t length,
 					index_removed_callback, NULL, NULL);
 
 	data->hciemu = hciemu_new(data->hciemu_type);
+	if (!data->hciemu)
+		data->hciemu = hciemu_new_debug(data->hciemu_type, print_debug,
+							"hciemu: ", NULL);
 	if (!data->hciemu) {
 		tester_warn("Failed to setup HCI emulation");
 		test_pre_setup_failed();
diff --git a/tools/rfcomm-tester.c b/tools/rfcomm-tester.c
index 06e9fbdd6143..b7f7d9ebd794 100644
--- a/tools/rfcomm-tester.c
+++ b/tools/rfcomm-tester.c
@@ -164,6 +164,9 @@ static void read_index_list_callback(uint8_t status, uint16_t length,
 					index_removed_callback, NULL, NULL);
 
 	data->hciemu = hciemu_new(data->hciemu_type);
+	if (!data->hciemu)
+		data->hciemu = hciemu_new_debug(data->hciemu_type, print_debug,
+							"hciemu: ", NULL);
 	if (!data->hciemu) {
 		tester_warn("Failed to setup HCI emulation");
 		tester_pre_setup_failed();
diff --git a/tools/sco-tester.c b/tools/sco-tester.c
index f09ba04aeaf7..a2185b8ef198 100644
--- a/tools/sco-tester.c
+++ b/tools/sco-tester.c
@@ -192,6 +192,9 @@ static void read_index_list_callback(uint8_t status, uint16_t length,
 					index_removed_callback, NULL, NULL);
 
 	data->hciemu = hciemu_new(HCIEMU_TYPE_BREDRLE);
+	if (!data->hciemu)
+		data->hciemu = hciemu_new_debug(HCIEMU_TYPE_BREDRLE, print_debug,
+							"hciemu: ", NULL);
 	if (!data->hciemu) {
 		tester_warn("Failed to setup HCI emulation");
 		tester_pre_setup_failed();
diff --git a/tools/smp-tester.c b/tools/smp-tester.c
index aaf149c0deb7..581f3a233704 100644
--- a/tools/smp-tester.c
+++ b/tools/smp-tester.c
@@ -182,6 +182,9 @@ static void read_index_list_callback(uint8_t status, uint16_t length,
 					index_removed_callback, NULL, NULL);
 
 	data->hciemu = hciemu_new(data->hciemu_type);
+	if (!data->hciemu)
+		data->hciemu = hciemu_new_debug(data->hciemu_type, print_debug,
+							"hciemu: ", NULL);
 	if (!data->hciemu) {
 		tester_warn("Failed to setup HCI emulation");
 		tester_pre_setup_failed();
diff --git a/tools/userchan-tester.c b/tools/userchan-tester.c
index a03f64d84c0b..9164fc33f5d9 100644
--- a/tools/userchan-tester.c
+++ b/tools/userchan-tester.c
@@ -153,6 +153,9 @@ static void read_index_list_callback(uint8_t status, uint16_t length,
 					index_added_callback, NULL, NULL);
 
 	data->hciemu = hciemu_new(data->hciemu_type);
+	if (!data->hciemu)
+		data->hciemu = hciemu_new_debug(data->hciemu_type, mgmt_debug,
+							"hciemu: ", NULL);
 	if (!data->hciemu) {
 		tester_warn("Failed to setup HCI emulation");
 		tester_pre_setup_failed();
-- 
2.53.0


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox