* [PATCH] Bluetooth: L2CAP: avoid using hci_conn after dropping hold
@ 2026-05-06 15:53 Cen Zhang
2026-05-06 17:39 ` bluez.test.bot
2026-05-07 13:58 ` [PATCH] " Luiz Augusto von Dentz
0 siblings, 2 replies; 3+ messages in thread
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 [flat|nested] 3+ messages in thread
* RE: Bluetooth: L2CAP: avoid using hci_conn after dropping hold
2026-05-06 15:53 [PATCH] Bluetooth: L2CAP: avoid using hci_conn after dropping hold Cen Zhang
@ 2026-05-06 17:39 ` bluez.test.bot
2026-05-07 13:58 ` [PATCH] " Luiz Augusto von Dentz
1 sibling, 0 replies; 3+ messages in thread
From: bluez.test.bot @ 2026-05-06 17:39 UTC (permalink / raw)
To: linux-bluetooth, zzzccc427
[-- 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 [flat|nested] 3+ messages in thread
* Re: [PATCH] Bluetooth: L2CAP: avoid using hci_conn after dropping hold
2026-05-06 15:53 [PATCH] Bluetooth: L2CAP: avoid using hci_conn after dropping hold Cen Zhang
2026-05-06 17:39 ` bluez.test.bot
@ 2026-05-07 13:58 ` Luiz Augusto von Dentz
1 sibling, 0 replies; 3+ messages in thread
From: Luiz Augusto von Dentz @ 2026-05-07 13:58 UTC (permalink / raw)
To: Cen Zhang; +Cc: marcel, linux-bluetooth, linux-kernel, baijiaju1990
Hi Cen,
On Wed, May 6, 2026 at 11:53 AM Cen Zhang <zzzccc427@gmail.com> wrote:
>
> 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))
It doesn't seem to be very useful to read the hcon->state and cache it
while other function still going to access it, anyway we refcount the
hcon and hci_dev_lock is being held accourding to sashiko:
https://sashiko.dev/#/patchset/20260506155313.1412894-1-zzzccc427%40gmail.com
--
Luiz Augusto von Dentz
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-05-07 13:58 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-06 15:53 [PATCH] Bluetooth: L2CAP: avoid using hci_conn after dropping hold Cen Zhang
2026-05-06 17:39 ` bluez.test.bot
2026-05-07 13:58 ` [PATCH] " Luiz Augusto von Dentz
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox