* [bluez/action-ci] 92ec40: ci: add CheckKernelLLVM
From: Pauli Virtanen @ 2026-06-15 21:46 UTC (permalink / raw)
To: linux-bluetooth
Branch: refs/heads/main
Home: https://github.com/bluez/action-ci
Commit: 92ec4064e91267f1d90ae7d9a391100c04ad09d2
https://github.com/bluez/action-ci/commit/92ec4064e91267f1d90ae7d9a391100c04ad09d2
Author: Pauli Virtanen <pav@iki.fi>
Date: 2026-06-15 (Mon, 15 Jun 2026)
Changed paths:
M ci.py
M ci/__init__.py
M ci/checkallwarning.py
A ci/checkkernelllvm.py
M ci/generickernelbuild.py
M entrypoint.sh
Log Message:
-----------
ci: add CheckKernelLLVM
Add task to build kernel with LLVM + checking context analysis warnings:
https://docs.kernel.org/dev-tools/context-analysis.html
This feature does static compile time checking of the __must_hold,
__guarded_by etc annotations now used by kernel.
Commit: a562057313abc7aef89ec87faaab11caa5aaf94e
https://github.com/bluez/action-ci/commit/a562057313abc7aef89ec87faaab11caa5aaf94e
Author: Pauli Virtanen <pav@iki.fi>
Date: 2026-06-15 (Mon, 15 Jun 2026)
Changed paths:
M entrypoint.sh
M libs/context.py
Log Message:
-----------
entrypoint: add localci command for local CI dry run
Add localci command so that the docker CI can be tested locally without
secrets.
Example:
git clone --depth 1 https://github.com/bluez/bluetooth-next work/src
docker run --volume $PWD/work:/work/base:O $IMG localci kernel bluez/bluetooth-next 103
Commit: 058d4cc766443e37c4c1150f44d474b4e98dc61e
https://github.com/bluez/action-ci/commit/058d4cc766443e37c4c1150f44d474b4e98dc61e
Author: Pauli Virtanen <pav@iki.fi>
Date: 2026-06-15 (Mon, 15 Jun 2026)
Changed paths:
M ci.py
M ci/buildbluez.py
M ci/buildell.py
M ci/buildkernel.py
M ci/buildkernel32.py
M ci/checkallwarning.py
M ci/checksparse.py
M ci/checkvalgrind.py
M ci/genericbuild.py
M ci/generickernelbuild.py
M ci/incrementalbuild.py
M ci/makedistcheck.py
M ci/makeextell.py
M ci/scanbuild.py
M entrypoint.sh
Log Message:
-----------
ci: add --jobs setting to set make -j
Add option for setting make -j option value.
Compare: https://github.com/bluez/action-ci/compare/979e8164c387...058d4cc76644
To unsubscribe from these emails, change your notification settings at https://github.com/bluez/action-ci/settings/notifications
^ permalink raw reply
* [bluez/bluez] 80ec1f: test-bap: Fix using BT_ISO_QOS_CIG_UNSET for CIS_ID
From: Šimon Mikuda @ 2026-06-15 21:16 UTC (permalink / raw)
To: linux-bluetooth
Branch: refs/heads/master
Home: https://github.com/bluez/bluez
Commit: 80ec1f9d01c44768219c2842795652c6b6bb291c
https://github.com/bluez/bluez/commit/80ec1f9d01c44768219c2842795652c6b6bb291c
Author: Simon Mikuda <simon.mikuda@streamunlimited.com>
Date: 2026-06-15 (Mon, 15 Jun 2026)
Changed paths:
M unit/test-bap.c
Log Message:
-----------
test-bap: Fix using BT_ISO_QOS_CIG_UNSET for CIS_ID
Although there are the same value the proper define is
BT_ISO_QOS_CIS_UNSET.
Commit: 64ae65d8958e67fb65f7413ef4ceab2ad51a6b28
https://github.com/bluez/bluez/commit/64ae65d8958e67fb65f7413ef4ceab2ad51a6b28
Author: Simon Mikuda <simon.mikuda@streamunlimited.com>
Date: 2026-06-15 (Mon, 15 Jun 2026)
Changed paths:
M src/shared/bap.c
Log Message:
-----------
shared/bap: Initialize ucast/bcast IDs as unset
Also change some lines where CIS should be used instead of CIG.
Commit: 5297cf2b6af6970e12081e20f1a978c2bf52fd1f
https://github.com/bluez/bluez/commit/5297cf2b6af6970e12081e20f1a978c2bf52fd1f
Author: Simon Mikuda <simon.mikuda@streamunlimited.com>
Date: 2026-06-15 (Mon, 15 Jun 2026)
Changed paths:
M src/shared/bap.c
Log Message:
-----------
shared/bap: Don't link server ucast streams before CIS IDs are assigned
bap_ucast_io_link pairs streams whose CIG/CIS IDs match, but the IDs
are unset in Codec Configured state, so a Sink and Source bound for
different CISes get linked. The stray link later propagates a
disconnect to the wrong ASE and breaks Receiver Start Ready.
Skip linking until QoS Configured assigns the IDs.
Fixes PTS test BAP/USR/STR/BV-362-C
Compare: https://github.com/bluez/bluez/compare/9c36e4189e32...5297cf2b6af6
To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications
^ permalink raw reply
* Re: [PATCH BlueZ v6 3/6] build: add functional testing target
From: Pauli Virtanen @ 2026-06-15 19:45 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <CABBYNZ+6Bp6yV4kzB4Y53XD+6i0mbhNTFoU=qpXq4Qu5o3=6og@mail.gmail.com>
Hi,
ma, 2026-06-15 kello 15:08 -0400, Luiz Augusto von Dentz kirjoitti:
[clip]
>
> Seems to be working if I do ./bootstrap-configure
> --enable-functional-testing=../linux:
>
> platform linux -- Python 3.13.13, pytest-8.3.3, pluggy-1.5.0 -- /usr/bin/python3
> cachedir: .pytest_cache
> rootdir: /home/vudentz/git/bluez/test
> configfile: pytest.ini
> plugins: venv-0.3, anyio-4.8.0
> collected 13 items
>
[clip]
> test/functional/test_tests.py::test_formatting SKIPPED (could not
> import 'black': No module named 'black')
>
>
> [ 7%]
> test/functional/test_bluetoothctl_vm.py::test_bluetoothctl_show[hosts1-vm1]
> PASSED
[clip]
> I wonder why the first one is being skipped though, since I did install:
>
> python3 -mpip install -r test/functional/requirements.txt
Right, the requirements file could have `black` added to it.
> That said maybe we could run it as part of a container that builds the
> kernel environment, which would download and build bluetooth-next.
> Even better, that could load a prebuilt kernel image (pushed by CI)
> but it perhaps needs to detect if the prebuilt image needs updating;
> if so, it builds it locally or something.
Having some docker image that builds/downloads the kernel image and
runs these could make sense, which could then run on some schedule on
CI.
If it should be integrated with Patchwork and run on every patch, then
it may be simplest to do it in the action-ci together with the other
testers.
Otherwise, probably separate image + separate Github action.
If running locally, you can say
`test/test-functional --kernel-build=force` and it'll pull & build
bluetooth-next kernel, with ccache it rebuilds in reasonable time.
--
Pauli Virtanen
^ permalink raw reply
* Re: [PATCH] Bluetooth: MGMT: Fix UAF of hci_conn_params in add_device_complete
From: patchwork-bot+bluetooth @ 2026-06-15 19:40 UTC (permalink / raw)
To: Samuel Page; +Cc: marcel, luiz.dentz, linux-bluetooth, linux-kernel, stable
In-Reply-To: <20260615150922.1737274-1-sam@bynar.io>
Hello:
This patch was applied to bluetooth/bluetooth-next.git (master)
by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>:
On Mon, 15 Jun 2026 16:09:22 +0100 you wrote:
> add_device_complete() runs from the hci_cmd_sync_work kworker, which
> holds only hci_req_sync_lock and *not* hci_dev_lock. It calls
> hci_conn_params_lookup() and then dereferences the returned object
> (params->flags) without taking hci_dev_lock:
>
> params = hci_conn_params_lookup(hdev, &cp->addr.bdaddr,
> le_addr_type(cp->addr.type));
> ...
> device_flags_changed(NULL, hdev, &cp->addr.bdaddr,
> cp->addr.type, hdev->conn_flags,
> params ? params->flags : 0);
>
> [...]
Here is the summary with links:
- Bluetooth: MGMT: Fix UAF of hci_conn_params in add_device_complete
https://git.kernel.org/bluetooth/bluetooth-next/c/cb20f6afc25b
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 v3 1/2] shared/bap: Initialize ucast/bcast IDs as unset
From: patchwork-bot+bluetooth @ 2026-06-15 19:30 UTC (permalink / raw)
To: Simon Mikuda; +Cc: linux-bluetooth
In-Reply-To: <20260614105016.1147112-1-simon.mikuda@streamunlimited.com>
Hello:
This series was applied to bluetooth/bluez.git (master)
by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>:
On Sun, 14 Jun 2026 12:50:15 +0200 you wrote:
> Also change some lines where CIS should be used instead of CIG
> ---
> src/shared/bap.c | 13 +++++++++++++
> unit/test-bap.c | 4 ++--
> 2 files changed, 15 insertions(+), 2 deletions(-)
Here is the summary with links:
- [BlueZ,v3,1/2] shared/bap: Initialize ucast/bcast IDs as unset
(no matching commit)
- [BlueZ,v3,2/2] shared/bap: Don't link server ucast streams before CIS IDs are assigned
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=5297cf2b6af6
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 v6 3/6] build: add functional testing target
From: Luiz Augusto von Dentz @ 2026-06-15 19:08 UTC (permalink / raw)
To: Pauli Virtanen; +Cc: linux-bluetooth
In-Reply-To: <199523aaa32d2be835216f583dfe9bf7d9eacf42.1781365708.git.pav@iki.fi>
Hi Pauli,
On Sat, Jun 13, 2026 at 11:49 AM Pauli Virtanen <pav@iki.fi> wrote:
>
> This adds check-functional: target that runs the functional test suite.
>
> Also add a --enable-functional-testing=<kernel-image> argument for
> configure that can be used to include it in the check: make target,
> possibly with a predefined kernel image.
> ---
> Makefile.am | 10 ++++++++++
> configure.ac | 22 ++++++++++++++++++++++
> 2 files changed, 32 insertions(+)
>
> diff --git a/Makefile.am b/Makefile.am
> index 76c4ab5d4..7920cae68 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -812,6 +812,16 @@ endif
> TESTS = $(unit_tests)
> AM_TESTS_ENVIRONMENT = MALLOC_CHECK_=3 MALLOC_PERTURB_=69
>
> +check-functional: all
> + python3 -m pytest "$(srcdir)/test/functional" -v \
> + --kernel="$(FUNCTIONAL_TESTING_KERNEL)" \
> + --bluez-build-dir="$(top_builddir)" \
> + --bluez-src-dir="$(srcdir)"
> +
> +if FUNCTIONAL_TESTING
> +check: check-functional
> +endif
> +
> if DBUS_RUN_SESSION
> AM_TESTS_ENVIRONMENT += dbus-run-session --
> endif
> diff --git a/configure.ac b/configure.ac
> index 1cdd551f6..f50d8c9b3 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -407,6 +407,28 @@ if (test "${enable_testing}" = "yes"); then
> #include <linux/net_tstamp.h>]])
> fi
>
> +AC_ARG_ENABLE(functional-testing, AS_HELP_STRING([--enable-functional-testing],
> + [enable functional testing tools]),
> + [enable_functional_testing=yes; functional_testing_kernel=${enableval}],
> + [enable_functional_testing=no])
> +AM_CONDITIONAL(FUNCTIONAL_TESTING, test "${enable_functional_testing}" = "yes")
> +AC_ARG_VAR(FUNCTIONAL_TESTING_KERNEL, [vmlinux image to use for functional testing])
> +FUNCTIONAL_TESTING_KERNEL=${functional_testing_kernel}
> +
> +if (test "${enable_functional_testing}" = "yes"); then
> + if (test "${enable_client}" = "no" || \
> + test "${enable_tools}" != "yes" || \
> + test "${enable_testing}" != "yes"); then
> + AC_MSG_ERROR([--enable-functional-testing requires --enable-client --enable-tools --enable-testing])
> + fi
> + AC_MSG_CHECKING([pytest and dependencies])
> + python3 -m pip install --dry-run --no-index -r "${srcdir}/test/functional/requirements.txt" >/dev/null
> + if (test "$?" != "0"); then
> + AC_MSG_ERROR([pytest or dependencies missing])
> + fi
> + AC_MSG_RESULT([ok])
> +fi
> +
> AC_ARG_ENABLE(experimental, AS_HELP_STRING([--enable-experimental],
> [enable experimental tools]),
> [enable_experimental=${enableval}])
> --
> 2.54.0
Seems to be working if I do ./bootstrap-configure
--enable-functional-testing=../linux:
platform linux -- Python 3.13.13, pytest-8.3.3, pluggy-1.5.0 -- /usr/bin/python3
cachedir: .pytest_cache
rootdir: /home/vudentz/git/bluez/test
configfile: pytest.ini
plugins: venv-0.3, anyio-4.8.0
collected 13 items
test/functional/test_tests.py::test_formatting SKIPPED (could not
import 'black': No module named 'black')
[ 7%]
test/functional/test_bluetoothctl_vm.py::test_bluetoothctl_show[hosts1-vm1]
PASSED
[ 15%]
test/functional/test_bluetoothctl_vm.py::test_bluetoothctl_list[hosts1-vm1]
PASSED
[ 23%]
test/functional/test_bluetoothctl_vm.py::test_bluetoothctl_script_show[hosts1-vm1]
PASSED
[ 30%]
test/functional/test_bluetoothctl_vm.py::test_bluetoothctl_script_list[hosts1-vm1]
PASSED
[ 38%]
test/functional/test_btmgmt_vm.py::test_btmgmt_info[hosts4-vm1] PASSED
[
46%]
test/functional/test_agent.py::test_agent_pair_bredr[accept-hosts0-vm2]
PASSED
[
53%]
test/functional/test_agent.py::test_agent_pair_bredr[reject-hosts0-vm2]
PASSED
[
61%]
test/functional/test_bluetoothctl_vm.py::test_bluetoothctl_pair_bredr[hosts2-vm2]
PASSED
[ 69%]
test/functional/test_bluetoothctl_vm.py::test_bluetoothctl_pair_le[hosts3-vm2]
PASSED
[ 76%]
test/functional/test_obex.py::test_obex_ftp_list[hosts5-vm2] PASSED
[
84%]
test/functional/test_obex.py::test_obex_ftp_get[hosts5-vm2] PASSED
[
92%]
test/functional/test_obex.py::test_obexctl_list[hosts5-vm2] PASSED
[100%]
I wonder why the first one is being skipped though, since I did install:
python3 -mpip install -r test/functional/requirements.txt
That said maybe we could run it as part of a container that builds the
kernel environment, which would download and build bluetooth-next.
Even better, that could load a prebuilt kernel image (pushed by CI)
but it perhaps needs to detect if the prebuilt image needs updating;
if so, it builds it locally or something.
--
Luiz Augusto von Dentz
^ permalink raw reply
* Re: [PATCH v2] Bluetooth: 6lowpan: Fix using chan->conn as indication to no remote netdev
From: patchwork-bot+bluetooth @ 2026-06-15 18:20 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <20260615152948.776154-1-luiz.dentz@gmail.com>
Hello:
This patch was applied to bluetooth/bluetooth-next.git (master)
by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>:
On Mon, 15 Jun 2026 11:29:48 -0400 you wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>
> b66774b48dd9 ("Bluetooth: L2CAP: Fix UAF in channel timeout by holding
> conn ref") don't reset the chan->conn to NULL anymore making the bt#
> netdev not be remove once the last l2cap_chan_del is removed.
>
> Instead of restoring the original behavior this remove the logic of
> keeping the interface after the last channel is removed because it
> never worked as intended and the l2cap_chan_del always detach its
> l2cap_conn which results in always removing the channel anyway.
>
> [...]
Here is the summary with links:
- [v2] Bluetooth: 6lowpan: Fix using chan->conn as indication to no remote netdev
https://git.kernel.org/bluetooth/bluetooth-next/c/d35e2950daaf
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* [bluez/bluez]
From: BluezTestBot @ 2026-06-15 18:10 UTC (permalink / raw)
To: linux-bluetooth
Branch: refs/heads/1111249
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-06-15 18:10 UTC (permalink / raw)
To: linux-bluetooth
Branch: refs/heads/1111253
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-06-15 18:10 UTC (permalink / raw)
To: linux-bluetooth
Branch: refs/heads/1111256
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: [PATCH RESEND] Bluetooth: btusb: Add new VID/PID 0x0489/0xe156 for MT7902
From: patchwork-bot+bluetooth @ 2026-06-15 18:10 UTC (permalink / raw)
To: Kirill Shubin
Cc: luiz.dentz, marcel, linux-bluetooth, linux-mediatek, sean.wang,
sean.wang
In-Reply-To: <20260614141258.1011-1-kirill.kz.902@gmail.com>
Hello:
This patch was applied to bluetooth/bluetooth-next.git (master)
by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>:
On Sun, 14 Jun 2026 17:12:58 +0300 you wrote:
> From: Sean Wang <sean.wang@mediatek.com>
>
> Add VID 0489 & PID e156 for MediaTek MT7902 USB Bluetooth chip.
>
> The information in /sys/kernel/debug/usb/devices about the Bluetooth
> device is listed as the below.
>
> [...]
Here is the summary with links:
- [RESEND] Bluetooth: btusb: Add new VID/PID 0x0489/0xe156 for MT7902
https://git.kernel.org/bluetooth/bluetooth-next/c/5d31430fc208
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 v2] Bluetooth: hci_uart: clear HCI_UART_SENDING when write_work is canceled
From: patchwork-bot+bluetooth @ 2026-06-15 18:10 UTC (permalink / raw)
To: Pauli Virtanen
Cc: linux-bluetooth, marcel, luiz.dentz, 25181214217, linux-kernel,
stable
In-Reply-To: <9fdead8517c36f37c0b23b7b60f590d735792cfa.1781375875.git.pav@iki.fi>
Hello:
This patch was applied to bluetooth/bluetooth-next.git (master)
by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>:
On Sat, 13 Jun 2026 21:43:37 +0300 you wrote:
> HCI_UART_SENDING bit in tx_state means write_work is pending and blocks
> queueing it again. Currently this bit is not cleared when canceling the
> work in hci_uart_close(), which blocks future writes when device is
> reopened later if write_work was pending.
>
> Fix by clearing HCI_UART_SENDING when canceling the work.
>
> [...]
Here is the summary with links:
- [v2] Bluetooth: hci_uart: clear HCI_UART_SENDING when write_work is canceled
https://git.kernel.org/bluetooth/bluetooth-next/c/3b7686310806
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* [bluez/bluez] 237d4d: shared/bap: Transition ASE to QoS Configured on CI...
From: Šimon Mikuda @ 2026-06-15 18:09 UTC (permalink / raw)
To: linux-bluetooth
Branch: refs/heads/master
Home: https://github.com/bluez/bluez
Commit: 237d4d5d20a556ea11f6cf5d0013884a0a70962e
https://github.com/bluez/bluez/commit/237d4d5d20a556ea11f6cf5d0013884a0a70962e
Author: Simon Mikuda <simon.mikuda@streamunlimited.com>
Date: 2026-06-15 (Mon, 15 Jun 2026)
Changed paths:
M src/shared/bap.c
Log Message:
-----------
shared/bap: Transition ASE to QoS Configured on CIS loss
stream_io_disconnected() only handled the Releasing state, leaving
Enabling, Streaming and Disabling ASEs stuck when the CIS was lost
unexpectedly.
The ASE shall autonomously move to QoS Configured on loss of the
CIS and notify the peer
Fixes PTS test BAP/USR/SCC/BV-167-C
Commit: 986e220b77ea7803af0279200db7b011667302d7
https://github.com/bluez/bluez/commit/986e220b77ea7803af0279200db7b011667302d7
Author: Simon Mikuda <simon.mikuda@streamunlimited.com>
Date: 2026-06-15 (Mon, 15 Jun 2026)
Changed paths:
M unit/test-bap.c
Log Message:
-----------
unit/bap: Add CIS loss test
Verify a Source ASE in the Enabling state transitions to QoS Configured
rather than Disabling when its CIS is lost.
Assisted-by: ClaudeCode:claude-opus-4.8
Commit: bd9eac15a27ac2eb14f9b2f69d046088d687bfa3
https://github.com/bluez/bluez/commit/bd9eac15a27ac2eb14f9b2f69d046088d687bfa3
Author: Pauli Virtanen <pav@iki.fi>
Date: 2026-06-15 (Mon, 15 Jun 2026)
Changed paths:
M profiles/audio/media.c
Log Message:
-----------
media: use custom DBus timeouts only when remote side is waiting
Under high system load (VM instance on boot) it's observed the 3 sec
timeout BlueZ uses for BAP broadcast SetConfiguration may be missed by
Wireplumber, as these are set up immediately on startup together with
any other setup (eg ALSA) that may need time.
There's no actual need for using a short custom timeout in BlueZ for
this, as in this case there is no remote side that is waiting for a reply.
Fix by limiting custom timeouts to cases where there is a waiting
remote, and use separate defines for A2DP and BAP.
Commit: 9c36e4189e32f4b8ab1376749dda4b97e71af9af
https://github.com/bluez/bluez/commit/9c36e4189e32f4b8ab1376749dda4b97e71af9af
Author: Simon Mikuda <simon.mikuda@streamunlimited.com>
Date: 2026-06-15 (Mon, 15 Jun 2026)
Changed paths:
M src/gatt-database.c
Log Message:
-----------
gatt-database: Prefer notifications over indications
When both notifications and indications are enabled (CCC value=0x0003)
we will send notifications by default.
Compare: https://github.com/bluez/bluez/compare/40f2e34b3739...9c36e4189e32
To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications
^ permalink raw reply
* RE: [v6,1/2] Bluetooth: hci_conn: Fix null ptr deref in hci_abort_conn()
From: bluez.test.bot @ 2026-06-15 17:04 UTC (permalink / raw)
To: linux-bluetooth, oss
In-Reply-To: <20260615153527.1583705-1-oss@fourdim.xyz>
[-- Attachment #1: Type: text/plain, Size: 2794 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=1111791
---Test result---
Test Summary:
CheckPatch PASS 1.82 seconds
VerifyFixes PASS 0.09 seconds
VerifySignedoff PASS 0.09 seconds
GitLint PASS 0.47 seconds
SubjectPrefix PASS 0.16 seconds
BuildKernel PASS 26.58 seconds
CheckAllWarning PASS 28.89 seconds
CheckSparse PASS 27.60 seconds
BuildKernel32 PASS 25.49 seconds
TestRunnerSetup PASS 571.42 seconds
TestRunner_l2cap-tester PASS 58.94 seconds
TestRunner_iso-tester PASS 96.66 seconds
TestRunner_bnep-tester PASS 30.75 seconds
TestRunner_mgmt-tester FAIL 207.20 seconds
TestRunner_rfcomm-tester PASS 30.92 seconds
TestRunner_sco-tester PASS 31.50 seconds
TestRunner_ioctl-tester PASS 26.69 seconds
TestRunner_mesh-tester FAIL 25.83 seconds
TestRunner_smp-tester PASS 22.80 seconds
TestRunner_userchan-tester PASS 19.22 seconds
TestRunner_6lowpan-tester FAIL 45.81 seconds
IncrementalBuild PASS 43.45 seconds
Details
##############################
Test: TestRunner_mgmt-tester - FAIL
Desc: Run mgmt-tester with test-runner
Output:
Total: 494, Passed: 489 (99.0%), Failed: 1, Not Run: 4
Failed Test Cases
Read Exp Feature - Success Failed 0.234 seconds
##############################
Test: TestRunner_mesh-tester - FAIL
Desc: Run mesh-tester with test-runner
Output:
Total: 10, Passed: 8 (80.0%), Failed: 2, Not Run: 0
Failed Test Cases
Mesh - Send cancel - 1 Timed out 2.808 seconds
Mesh - Send cancel - 2 Timed out 1.989 seconds
##############################
Test: TestRunner_6lowpan-tester - FAIL
Desc: Run 6lowpan-tester with test-runner
Output:
Total: 8, Passed: 3 (37.5%), Failed: 5, Not Run: 0
Failed Test Cases
Client Connect - Disconnect Timed out 5.480 seconds
Client Recv Dgram - Success Timed out 4.991 seconds
Client Recv Raw - Success Timed out 4.993 seconds
Client Recv IPHC Dgram - Success Timed out 4.999 seconds
Client Recv IPHC Raw - Success Timed out 4.993 seconds
https://github.com/bluez/bluetooth-next/pull/318
---
Regards,
Linux Bluetooth
^ permalink raw reply
* RE: [v2] Bluetooth: 6lowpan: Fix using chan->conn as indication to no remote netdev
From: bluez.test.bot @ 2026-06-15 16:55 UTC (permalink / raw)
To: linux-bluetooth, luiz.dentz
In-Reply-To: <20260615152948.776154-1-luiz.dentz@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1946 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=1111788
---Test result---
Test Summary:
CheckPatch FAIL 0.67 seconds
VerifyFixes PASS 0.11 seconds
VerifySignedoff PASS 0.11 seconds
GitLint PASS 0.29 seconds
SubjectPrefix PASS 0.11 seconds
BuildKernel PASS 26.71 seconds
CheckAllWarning PASS 29.48 seconds
CheckSparse PASS 28.54 seconds
BuildKernel32 PASS 26.28 seconds
TestRunnerSetup PASS 588.05 seconds
TestRunner_6lowpan-tester PASS 22.78 seconds
IncrementalBuild PASS 40.30 seconds
Details
##############################
Test: CheckPatch - FAIL
Desc: Run checkpatch.pl script
Output:
[v2] Bluetooth: 6lowpan: Fix using chan->conn as indication to no remote netdev
ERROR: Please use git commit description style 'commit <12+ chars of sha1> ("<title line>")' - ie: 'commit b66774b48dd9 ("Bluetooth: L2CAP: Fix UAF in channel timeout by holding conn ref")'
#98:
b66774b48dd9 ("Bluetooth: L2CAP: Fix UAF in channel timeout by holding
total: 1 errors, 0 warnings, 0 checks, 33 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/14629714.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.
https://github.com/bluez/bluetooth-next/pull/317
---
Regards,
Linux Bluetooth
^ permalink raw reply
* [PATCH v6 2/2] Bluetooth: hci_sync: Remove unused hci_cmd_sync_dequeue_once()
From: Siwei Zhang @ 2026-06-15 15:33 UTC (permalink / raw)
To: Luiz Augusto von Dentz, Pauli Virtanen, XIAO WU
Cc: linux-bluetooth, Siwei Zhang
In-Reply-To: <20260615153527.1583705-1-oss@fourdim.xyz>
hci_cmd_sync_dequeue_once() had a single in-tree caller,
hci_cancel_connect_sync(), which now holds cmd_sync_work_lock across the
in-flight create flag test and the dequeue and so open-codes the lookup
and cancel under that lock. That leaves the exported
hci_cmd_sync_dequeue_once() with no in-tree user, so remove it along with
its declaration.
Signed-off-by: Siwei Zhang <oss@fourdim.xyz>
---
include/net/bluetooth/hci_sync.h | 3 ---
net/bluetooth/hci_sync.c | 26 --------------------------
2 files changed, 29 deletions(-)
diff --git a/include/net/bluetooth/hci_sync.h b/include/net/bluetooth/hci_sync.h
index 73e494b2591d..818e62d9fe9e 100644
--- a/include/net/bluetooth/hci_sync.h
+++ b/include/net/bluetooth/hci_sync.h
@@ -84,9 +84,6 @@ void hci_cmd_sync_cancel_entry(struct hci_dev *hdev,
struct hci_cmd_sync_work_entry *entry);
bool hci_cmd_sync_dequeue(struct hci_dev *hdev, hci_cmd_sync_work_func_t func,
void *data, hci_cmd_sync_work_destroy_t destroy);
-bool hci_cmd_sync_dequeue_once(struct hci_dev *hdev,
- hci_cmd_sync_work_func_t func, void *data,
- hci_cmd_sync_work_destroy_t destroy);
int hci_update_eir_sync(struct hci_dev *hdev);
int hci_update_class_sync(struct hci_dev *hdev);
diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
index a3df69bdec1e..753198b401ac 100644
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -860,32 +860,6 @@ void hci_cmd_sync_cancel_entry(struct hci_dev *hdev,
}
EXPORT_SYMBOL(hci_cmd_sync_cancel_entry);
-/* Dequeue one HCI command entry:
- *
- * - Lookup and cancel first entry that matches.
- */
-bool hci_cmd_sync_dequeue_once(struct hci_dev *hdev,
- hci_cmd_sync_work_func_t func,
- void *data, hci_cmd_sync_work_destroy_t destroy)
-{
- struct hci_cmd_sync_work_entry *entry;
-
- mutex_lock(&hdev->cmd_sync_work_lock);
-
- entry = _hci_cmd_sync_lookup_entry(hdev, func, data, destroy);
- if (!entry) {
- mutex_unlock(&hdev->cmd_sync_work_lock);
- return false;
- }
-
- _hci_cmd_sync_cancel_entry(hdev, entry, -ECANCELED);
-
- mutex_unlock(&hdev->cmd_sync_work_lock);
-
- return true;
-}
-EXPORT_SYMBOL(hci_cmd_sync_dequeue_once);
-
/* Dequeue HCI command entry:
*
* - Lookup and cancel any entry that matches by function callback or data or
--
2.54.0
^ permalink raw reply related
* [PATCH v6 1/2] Bluetooth: hci_conn: Fix null ptr deref in hci_abort_conn()
From: Siwei Zhang @ 2026-06-15 15:33 UTC (permalink / raw)
To: Luiz Augusto von Dentz, Pauli Virtanen, XIAO WU
Cc: linux-bluetooth, Siwei Zhang
hci_abort_conn() read hci_skb_event(hdev->sent_cmd) when a connection
was pending, but hdev->sent_cmd can be NULL while req_status is still
HCI_REQ_PEND, leading to a NULL pointer dereference and a general
protection fault from the hci_rx_work() receive path.
Instead of inspecting hdev->sent_cmd, track the in-flight create
connection command with a new per-connection HCI_CONN_CREATE flag and
route all cancellation through hci_cancel_connect_sync(), which
dispatches to a dedicated per-type cancel function. The create command
is in exactly one of two states: still queued, or in flight. The cancel
function holds cmd_sync_work_lock across the whole decision: the worker
takes this lock to dequeue every entry, so while it is held a queued
command cannot start running and an in-flight command cannot complete
and let the next command become pending. This keeps the flag test and
hci_cmd_sync_cancel() atomic with respect to the worker, so a queued
command is simply dequeued, and an in-flight command owned by this
connection is cancelled without the risk of cancelling an unrelated
command that became pending in the meantime. CIS uses the same flag
mechanism via HCI_CONN_CREATE_CIS but cannot be dequeued per-connection.
hci_acl_create_conn_sync() and hci_le_create_conn_sync() clear
HCI_CONN_CREATE after the create command completes, but the command
status handler can free conn via hci_conn_del() (for example when the
controller rejects the connection) while the worker is still blocked on
the connection complete event. Hold a reference on conn across the
create command so the flag can be cleared without a use-after-free.
Fixes: a13f316e90fd ("Bluetooth: hci_conn: Consolidate code for aborting connections")
Cc: stable@vger.kernel.org
Suggested-by: XIAO WU <xiaowu.417@qq.com>
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Siwei Zhang <oss@fourdim.xyz>
---
include/net/bluetooth/hci_core.h | 1 +
net/bluetooth/hci_conn.c | 21 +----
net/bluetooth/hci_sync.c | 133 +++++++++++++++++++++++++++----
3 files changed, 123 insertions(+), 32 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index aa600fbf9a53..aa554c34f9ec 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -988,6 +988,7 @@ enum {
HCI_CONN_AUTH_FAILURE,
HCI_CONN_PER_ADV,
HCI_CONN_BIG_CREATED,
+ HCI_CONN_CREATE,
HCI_CONN_CREATE_CIS,
HCI_CONN_CREATE_BIG_SYNC,
HCI_CONN_BIG_SYNC,
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 54eabaa46960..eba4a548bef5 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -3181,26 +3181,11 @@ int hci_abort_conn(struct hci_conn *conn, u8 reason)
conn->abort_reason = reason;
- /* If the connection is pending check the command opcode since that
- * might be blocking on hci_cmd_sync_work while waiting its respective
- * event so we need to hci_cmd_sync_cancel to cancel it.
- *
- * hci_connect_le serializes the connection attempts so only one
- * connection can be in BT_CONNECT at time.
+ /* Cancel the connect attempt. A return of 0 means the create command
+ * was still queued and got dequeued, so there is nothing to disconnect.
*/
- if (conn->state == BT_CONNECT && READ_ONCE(hdev->req_status) == HCI_REQ_PEND) {
- switch (hci_skb_event(hdev->sent_cmd)) {
- case HCI_EV_CONN_COMPLETE:
- case HCI_EV_LE_CONN_COMPLETE:
- case HCI_EV_LE_ENHANCED_CONN_COMPLETE:
- case HCI_EVT_LE_CIS_ESTABLISHED:
- hci_cmd_sync_cancel(hdev, ECANCELED);
- break;
- }
- /* Cancel connect attempt if still queued/pending */
- } else if (!hci_cancel_connect_sync(hdev, conn)) {
+ if (!hci_cancel_connect_sync(hdev, conn))
return 0;
- }
/* Run immediately if on cmd_sync_work since this may be called
* as a result to MGMT_OP_DISCONNECT/MGMT_OP_UNPAIR which does
diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
index df23245d6ccd..a3df69bdec1e 100644
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -6611,6 +6611,11 @@ static int hci_le_create_conn_sync(struct hci_dev *hdev, void *data)
bt_dev_dbg(hdev, "conn %p", conn);
+ /* Hold a reference so conn stays valid for the HCI_CONN_CREATE
+ * clear_bit() at done.
+ */
+ hci_conn_get(conn);
+
clear_bit(HCI_CONN_SCANNING, &conn->flags);
conn->state = BT_CONNECT;
@@ -6623,6 +6628,7 @@ static int hci_le_create_conn_sync(struct hci_dev *hdev, void *data)
hdev->le_scan_type == LE_SCAN_ACTIVE &&
!hci_dev_test_flag(hdev, HCI_LE_SIMULTANEOUS_ROLES)) {
hci_conn_del(conn);
+ hci_conn_put(conn);
return -EBUSY;
}
@@ -6668,6 +6674,12 @@ static int hci_le_create_conn_sync(struct hci_dev *hdev, void *data)
&own_addr_type);
if (err)
goto done;
+
+ /* Mark create connection in flight so hci_cancel_connect_sync() can
+ * cancel it while blocking on the connection complete event.
+ */
+ set_bit(HCI_CONN_CREATE, &conn->flags);
+
/* Send command LE Extended Create Connection if supported */
if (use_ext_conn(hdev)) {
err = hci_le_ext_create_conn_sync(hdev, conn, own_addr_type);
@@ -6703,11 +6715,14 @@ static int hci_le_create_conn_sync(struct hci_dev *hdev, void *data)
conn->conn_timeout, NULL);
done:
+ clear_bit(HCI_CONN_CREATE, &conn->flags);
+
if (err == -ETIMEDOUT)
hci_le_connect_cancel_sync(hdev, conn, 0x00);
/* Re-enable advertising after the connection attempt is finished. */
hci_resume_advertising_sync(hdev);
+ hci_conn_put(conn);
return err;
}
@@ -6982,10 +6997,25 @@ static int hci_acl_create_conn_sync(struct hci_dev *hdev, void *data)
else
cp.role_switch = 0x00;
- return __hci_cmd_sync_status_sk(hdev, HCI_OP_CREATE_CONN,
- sizeof(cp), &cp,
- HCI_EV_CONN_COMPLETE,
- conn->conn_timeout, NULL);
+ /* Hold a reference so conn stays valid for the HCI_CONN_CREATE
+ * clear_bit() below.
+ */
+ hci_conn_get(conn);
+
+ /* Mark create connection in flight so hci_cancel_connect_sync() can
+ * cancel it while blocking on the connection complete event.
+ */
+ set_bit(HCI_CONN_CREATE, &conn->flags);
+
+ err = __hci_cmd_sync_status_sk(hdev, HCI_OP_CREATE_CONN,
+ sizeof(cp), &cp,
+ HCI_EV_CONN_COMPLETE,
+ conn->conn_timeout, NULL);
+
+ clear_bit(HCI_CONN_CREATE, &conn->flags);
+ hci_conn_put(conn);
+
+ return err;
}
int hci_connect_acl_sync(struct hci_dev *hdev, struct hci_conn *conn)
@@ -7037,22 +7067,97 @@ int hci_connect_le_sync(struct hci_dev *hdev, struct hci_conn *conn)
return (err == -EEXIST) ? 0 : err;
}
-int hci_cancel_connect_sync(struct hci_dev *hdev, struct hci_conn *conn)
+static int hci_acl_cancel_create_conn_sync(struct hci_dev *hdev,
+ struct hci_conn *conn)
{
- if (conn->state != BT_OPEN)
- return -EINVAL;
+ struct hci_cmd_sync_work_entry *entry;
+ int err = -EBUSY;
+
+ /* cmd_sync_work_lock makes the HCI_CONN_CREATE test and the cancel
+ * atomic against the worker, which takes this lock to dequeue every
+ * entry: while it is held no other command can become pending, so
+ * hci_cmd_sync_cancel() cannot cancel an unrelated command.
+ */
+ mutex_lock(&hdev->cmd_sync_work_lock);
+
+ /* In flight: this connection owns the pending request, cancel it. */
+ if (test_bit(HCI_CONN_CREATE, &conn->flags)) {
+ hci_cmd_sync_cancel(hdev, ECANCELED);
+ goto unlock;
+ }
+
+ /* Still queued: a successful dequeue means it never started, so there
+ * is nothing to disconnect.
+ */
+ entry = _hci_cmd_sync_lookup_entry(hdev, hci_acl_create_conn_sync, conn,
+ NULL);
+ if (entry) {
+ _hci_cmd_sync_cancel_entry(hdev, entry, -ECANCELED);
+ err = 0;
+ }
+
+unlock:
+ mutex_unlock(&hdev->cmd_sync_work_lock);
+ return err;
+}
+
+static int hci_le_cancel_create_conn_sync(struct hci_dev *hdev,
+ struct hci_conn *conn)
+{
+ struct hci_cmd_sync_work_entry *entry;
+ int err = -EBUSY;
+
+ /* cmd_sync_work_lock keeps the HCI_CONN_CREATE test and the cancel
+ * atomic against the cmd_sync worker.
+ */
+ mutex_lock(&hdev->cmd_sync_work_lock);
+ if (test_bit(HCI_CONN_CREATE, &conn->flags)) {
+ hci_cmd_sync_cancel(hdev, ECANCELED);
+ goto unlock;
+ }
+
+ entry = _hci_cmd_sync_lookup_entry(hdev, hci_le_create_conn_sync, conn,
+ create_le_conn_complete);
+ if (entry) {
+ _hci_cmd_sync_cancel_entry(hdev, entry, -ECANCELED);
+ err = 0;
+ }
+
+unlock:
+ mutex_unlock(&hdev->cmd_sync_work_lock);
+ return err;
+}
+
+static int hci_cis_cancel_create_conn_sync(struct hci_dev *hdev,
+ struct hci_conn *conn)
+{
+ /* LE Create CIS is shared by the whole CIG and cannot be dequeued
+ * per-connection, so only an in-flight command can be cancelled.
+ * cmd_sync_work_lock keeps the test and the cancel atomic against the
+ * cmd_sync worker.
+ */
+ mutex_lock(&hdev->cmd_sync_work_lock);
+
+ if (test_bit(HCI_CONN_CREATE_CIS, &conn->flags))
+ hci_cmd_sync_cancel(hdev, ECANCELED);
+
+ mutex_unlock(&hdev->cmd_sync_work_lock);
+ return -EBUSY;
+}
+
+int hci_cancel_connect_sync(struct hci_dev *hdev, struct hci_conn *conn)
+{
switch (conn->type) {
case ACL_LINK:
- return !hci_cmd_sync_dequeue_once(hdev,
- hci_acl_create_conn_sync,
- conn, NULL);
+ return hci_acl_cancel_create_conn_sync(hdev, conn);
case LE_LINK:
- return !hci_cmd_sync_dequeue_once(hdev, hci_le_create_conn_sync,
- conn, create_le_conn_complete);
+ return hci_le_cancel_create_conn_sync(hdev, conn);
+ case CIS_LINK:
+ return hci_cis_cancel_create_conn_sync(hdev, conn);
+ default:
+ return -ENOENT;
}
-
- return -ENOENT;
}
int hci_le_conn_update_sync(struct hci_dev *hdev, struct hci_conn *conn,
--
2.54.0
^ permalink raw reply related
* [PATCH v2] Bluetooth: 6lowpan: Fix using chan->conn as indication to no remote netdev
From: Luiz Augusto von Dentz @ 2026-06-15 15:29 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
b66774b48dd9 ("Bluetooth: L2CAP: Fix UAF in channel timeout by holding
conn ref") don't reset the chan->conn to NULL anymore making the bt#
netdev not be remove once the last l2cap_chan_del is removed.
Instead of restoring the original behavior this remove the logic of
keeping the interface after the last channel is removed because it
never worked as intended and the l2cap_chan_del always detach its
l2cap_conn which results in always removing the channel anyway.
Fixes: b66774b48dd9 ("Bluetooth: L2CAP: Fix UAF in channel timeout by holding conn ref")
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
net/bluetooth/6lowpan.c | 18 +++---------------
1 file changed, 3 insertions(+), 15 deletions(-)
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index cb1e329d66fd..962e0e885105 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -797,20 +797,10 @@ static void chan_close_cb(struct l2cap_chan *chan)
struct lowpan_btle_dev *dev = NULL;
struct lowpan_peer *peer;
int err = -ENOENT;
- bool last = false, remove = true;
+ bool last = false;
BT_DBG("chan %p conn %p", chan, chan->conn);
- if (chan->conn && chan->conn->hcon) {
- if (!is_bt_6lowpan(chan->conn->hcon))
- return;
-
- /* If conn is set, then the netdev is also there and we should
- * not remove it.
- */
- remove = false;
- }
-
spin_lock(&devices_lock);
list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list) {
@@ -837,10 +827,8 @@ static void chan_close_cb(struct l2cap_chan *chan)
ifdown(dev->netdev);
- if (remove) {
- INIT_WORK(&entry->delete_netdev, delete_netdev);
- schedule_work(&entry->delete_netdev);
- }
+ INIT_WORK(&entry->delete_netdev, delete_netdev);
+ schedule_work(&entry->delete_netdev);
} else {
spin_unlock(&devices_lock);
}
--
2.54.0
^ permalink raw reply related
* Re: [PATCH BlueZ v2 1/2] shared/bap: Transition ASE to QoS Configured on CIS loss
From: patchwork-bot+bluetooth @ 2026-06-15 15:20 UTC (permalink / raw)
To: Simon Mikuda; +Cc: linux-bluetooth
In-Reply-To: <20260614100208.1091560-1-simon.mikuda@streamunlimited.com>
Hello:
This series was applied to bluetooth/bluez.git (master)
by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>:
On Sun, 14 Jun 2026 12:02:07 +0200 you wrote:
> stream_io_disconnected() only handled the Releasing state, leaving
> Enabling, Streaming and Disabling ASEs stuck when the CIS was lost
> unexpectedly.
>
> The ASE shall autonomously move to QoS Configured on loss of the
> CIS and notify the peer
>
> [...]
Here is the summary with links:
- [BlueZ,v2,1/2] shared/bap: Transition ASE to QoS Configured on CIS loss
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=237d4d5d20a5
- [BlueZ,v2,2/2] unit/bap: Add CIS loss test
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=986e220b77ea
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 2/2] gatt-database: Prefer notifications over indications
From: patchwork-bot+bluetooth @ 2026-06-15 15:20 UTC (permalink / raw)
To: Simon Mikuda; +Cc: linux-bluetooth
In-Reply-To: <20260614102931.1133819-1-simon.mikuda@streamunlimited.com>
Hello:
This patch was applied to bluetooth/bluez.git (master)
by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>:
On Sun, 14 Jun 2026 12:29:31 +0200 you wrote:
> When both notifications and indications are enabled (CCC value=0x0003)
> we will send notifications by default.
> ---
> src/gatt-database.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
Here is the summary with links:
- [BlueZ,2/2] gatt-database: Prefer notifications over indications
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=9c36e4189e32
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 v2] media: use custom DBus timeouts only when remote side is waiting
From: patchwork-bot+bluetooth @ 2026-06-15 15:20 UTC (permalink / raw)
To: Pauli Virtanen; +Cc: linux-bluetooth
In-Reply-To: <499a2bfcdd6ed488104bad57b285ddc9c7788f7e.1781436012.git.pav@iki.fi>
Hello:
This patch was applied to bluetooth/bluez.git (master)
by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>:
On Sun, 14 Jun 2026 14:22:23 +0300 you wrote:
> Under high system load (VM instance on boot) it's observed the 3 sec
> timeout BlueZ uses for BAP broadcast SetConfiguration may be missed by
> Wireplumber, as these are set up immediately on startup together with
> any other setup (eg ALSA) that may need time.
>
> There's no actual need for using a short custom timeout in BlueZ for
> this, as in this case there is no remote side that is waiting for a reply.
>
> [...]
Here is the summary with links:
- [BlueZ,v2] media: use custom DBus timeouts only when remote side is waiting
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=bd9eac15a27a
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 v5 1/2] Bluetooth: hci_conn: Fix null ptr deref in hci_abort_conn()
From: Siwei Zhang @ 2026-06-15 15:15 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: Pauli Virtanen, XIAO WU, linux-bluetooth
In-Reply-To: <CABBYNZLvSOHWQVmCX_T6wEXTPuS=JCii8Aujdh-C6Oo__1CGSw@mail.gmail.com>
Hi Luiz,
On Mon, Jun 15, 2026, at 11:11 AM, Luiz Augusto von Dentz wrote:
> Hi Siwei,
>
> On Mon, Jun 15, 2026 at 11:06 AM Siwei Zhang <oss@fourdim.xyz> wrote:
>>
>> Hi Luiz,
>>
>> On Mon, Jun 15, 2026, at 10:09 AM, Luiz Augusto von Dentz wrote:
>> > Hi Siwei,
>> >
>> > On Mon, Jun 15, 2026 at 9:12 AM Siwei Zhang <oss@fourdim.xyz> wrote:
>> >>
>> >> hci_abort_conn() read hci_skb_event(hdev->sent_cmd) when a connection
>> >> was pending, but hdev->sent_cmd can be NULL while req_status is still
>> >> HCI_REQ_PEND, leading to a NULL pointer dereference and a general
>> >> protection fault from the hci_rx_work() receive path.
>> >>
>> >> Instead of inspecting hdev->sent_cmd, track the in-flight create
>> >> connection command with a new per-connection HCI_CONN_CREATE flag and
>> >> route all cancellation through hci_cancel_connect_sync(). The create
>> >> command is in exactly one of two states: still queued, or in flight.
>> >> hci_cancel_connect_sync() holds cmd_sync_work_lock across the whole
>> >> decision: the worker takes this lock to dequeue every entry, so while it
>> >> is held a queued command cannot start running and an in-flight command
>> >> cannot complete and let the next command become pending. This keeps the
>> >> flag test and hci_cmd_sync_cancel() atomic with respect to the worker,
>> >> so a queued command is simply dequeued, and an in-flight command owned
>> >> by this connection is cancelled without the risk of cancelling an
>> >> unrelated command that became pending in the meantime. CIS uses the same
>> >> path via the existing HCI_CONN_CREATE_CIS flag.
>> >>
>> >> hci_acl_create_conn_sync() and hci_le_create_conn_sync() clear
>> >> HCI_CONN_CREATE after the create command completes, but the command
>> >> status handler can free conn via hci_conn_del() (for example when the
>> >> controller rejects the connection) while the worker is still blocked on
>> >> the connection complete event. Hold a reference on conn across the
>> >> create command so the flag can be cleared without a use-after-free.
>> >>
>> >> Fixes: a13f316e90fd ("Bluetooth: hci_conn: Consolidate code for aborting connections")
>> >> Cc: stable@vger.kernel.org
>> >> Suggested-by: XIAO WU <xiaowu.417@qq.com>
>> >> Assisted-by: Claude:claude-opus-4-8
>> >> Signed-off-by: Siwei Zhang <oss@fourdim.xyz>
>> >> ---
>> >> include/net/bluetooth/hci_core.h | 1 +
>> >> net/bluetooth/hci_conn.c | 21 +------
>> >> net/bluetooth/hci_sync.c | 96 ++++++++++++++++++++++++++++----
>> >> 3 files changed, 88 insertions(+), 30 deletions(-)
>> >>
>> >> diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
>> >> index aa600fbf9a53..aa554c34f9ec 100644
>> >> --- a/include/net/bluetooth/hci_core.h
>> >> +++ b/include/net/bluetooth/hci_core.h
>> >> @@ -988,6 +988,7 @@ enum {
>> >> HCI_CONN_AUTH_FAILURE,
>> >> HCI_CONN_PER_ADV,
>> >> HCI_CONN_BIG_CREATED,
>> >> + HCI_CONN_CREATE,
>> >> HCI_CONN_CREATE_CIS,
>> >> HCI_CONN_CREATE_BIG_SYNC,
>> >> HCI_CONN_BIG_SYNC,
>> >> diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
>> >> index 54eabaa46960..eba4a548bef5 100644
>> >> --- a/net/bluetooth/hci_conn.c
>> >> +++ b/net/bluetooth/hci_conn.c
>> >> @@ -3181,26 +3181,11 @@ int hci_abort_conn(struct hci_conn *conn, u8 reason)
>> >>
>> >> conn->abort_reason = reason;
>> >>
>> >> - /* If the connection is pending check the command opcode since that
>> >> - * might be blocking on hci_cmd_sync_work while waiting its respective
>> >> - * event so we need to hci_cmd_sync_cancel to cancel it.
>> >> - *
>> >> - * hci_connect_le serializes the connection attempts so only one
>> >> - * connection can be in BT_CONNECT at time.
>> >> + /* Cancel the connect attempt. A return of 0 means the create command
>> >> + * was still queued and got dequeued, so there is nothing to disconnect.
>> >> */
>> >> - if (conn->state == BT_CONNECT && READ_ONCE(hdev->req_status) == HCI_REQ_PEND) {
>> >> - switch (hci_skb_event(hdev->sent_cmd)) {
>> >> - case HCI_EV_CONN_COMPLETE:
>> >> - case HCI_EV_LE_CONN_COMPLETE:
>> >> - case HCI_EV_LE_ENHANCED_CONN_COMPLETE:
>> >> - case HCI_EVT_LE_CIS_ESTABLISHED:
>> >> - hci_cmd_sync_cancel(hdev, ECANCELED);
>> >> - break;
>> >> - }
>> >> - /* Cancel connect attempt if still queued/pending */
>> >> - } else if (!hci_cancel_connect_sync(hdev, conn)) {
>> >> + if (!hci_cancel_connect_sync(hdev, conn))
>> >> return 0;
>> >> - }
>> >>
>> >> /* Run immediately if on cmd_sync_work since this may be called
>> >> * as a result to MGMT_OP_DISCONNECT/MGMT_OP_UNPAIR which does
>> >> diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
>> >> index df23245d6ccd..06b87e9cd999 100644
>> >> --- a/net/bluetooth/hci_sync.c
>> >> +++ b/net/bluetooth/hci_sync.c
>> >> @@ -6611,6 +6611,11 @@ static int hci_le_create_conn_sync(struct hci_dev *hdev, void *data)
>> >>
>> >> bt_dev_dbg(hdev, "conn %p", conn);
>> >>
>> >> + /* Hold a reference so conn stays valid for the HCI_CONN_CREATE
>> >> + * clear_bit() at done.
>> >> + */
>> >> + hci_conn_get(conn);
>> >> +
>> >> clear_bit(HCI_CONN_SCANNING, &conn->flags);
>> >> conn->state = BT_CONNECT;
>> >>
>> >> @@ -6623,6 +6628,7 @@ static int hci_le_create_conn_sync(struct hci_dev *hdev, void *data)
>> >> hdev->le_scan_type == LE_SCAN_ACTIVE &&
>> >> !hci_dev_test_flag(hdev, HCI_LE_SIMULTANEOUS_ROLES)) {
>> >> hci_conn_del(conn);
>> >> + hci_conn_put(conn);
>> >> return -EBUSY;
>> >> }
>> >>
>> >> @@ -6668,6 +6674,12 @@ static int hci_le_create_conn_sync(struct hci_dev *hdev, void *data)
>> >> &own_addr_type);
>> >> if (err)
>> >> goto done;
>> >> +
>> >> + /* Mark create connection in flight so hci_cancel_connect_sync() can
>> >> + * cancel it while blocking on the connection complete event.
>> >> + */
>> >> + set_bit(HCI_CONN_CREATE, &conn->flags);
>> >> +
>> >> /* Send command LE Extended Create Connection if supported */
>> >> if (use_ext_conn(hdev)) {
>> >> err = hci_le_ext_create_conn_sync(hdev, conn, own_addr_type);
>> >> @@ -6703,11 +6715,14 @@ static int hci_le_create_conn_sync(struct hci_dev *hdev, void *data)
>> >> conn->conn_timeout, NULL);
>> >>
>> >> done:
>> >> + clear_bit(HCI_CONN_CREATE, &conn->flags);
>> >> +
>> >> if (err == -ETIMEDOUT)
>> >> hci_le_connect_cancel_sync(hdev, conn, 0x00);
>> >>
>> >> /* Re-enable advertising after the connection attempt is finished. */
>> >> hci_resume_advertising_sync(hdev);
>> >> + hci_conn_put(conn);
>> >> return err;
>> >> }
>> >>
>> >> @@ -6982,10 +6997,25 @@ static int hci_acl_create_conn_sync(struct hci_dev *hdev, void *data)
>> >> else
>> >> cp.role_switch = 0x00;
>> >>
>> >> - return __hci_cmd_sync_status_sk(hdev, HCI_OP_CREATE_CONN,
>> >> - sizeof(cp), &cp,
>> >> - HCI_EV_CONN_COMPLETE,
>> >> - conn->conn_timeout, NULL);
>> >> + /* Hold a reference so conn stays valid for the HCI_CONN_CREATE
>> >> + * clear_bit() below.
>> >> + */
>> >> + hci_conn_get(conn);
>> >> +
>> >> + /* Mark create connection in flight so hci_cancel_connect_sync() can
>> >> + * cancel it while blocking on the connection complete event.
>> >> + */
>> >> + set_bit(HCI_CONN_CREATE, &conn->flags);
>> >> +
>> >> + err = __hci_cmd_sync_status_sk(hdev, HCI_OP_CREATE_CONN,
>> >> + sizeof(cp), &cp,
>> >> + HCI_EV_CONN_COMPLETE,
>> >> + conn->conn_timeout, NULL);
>> >> +
>> >> + clear_bit(HCI_CONN_CREATE, &conn->flags);
>> >> + hci_conn_put(conn);
>> >> +
>> >> + return err;
>> >> }
>> >>
>> >> int hci_connect_acl_sync(struct hci_dev *hdev, struct hci_conn *conn)
>> >> @@ -7039,20 +7069,62 @@ int hci_connect_le_sync(struct hci_dev *hdev, struct hci_conn *conn)
>> >>
>> >> int hci_cancel_connect_sync(struct hci_dev *hdev, struct hci_conn *conn)
>> >> {
>> >> - if (conn->state != BT_OPEN)
>> >> - return -EINVAL;
>> >> + struct hci_cmd_sync_work_entry *entry;
>> >> + hci_cmd_sync_work_func_t func = NULL;
>> >> + hci_cmd_sync_work_destroy_t destroy = NULL;
>> >> + int create_flag = -1;
>> >> + int err = -EBUSY;
>> >>
>> >> switch (conn->type) {
>> >> case ACL_LINK:
>> >> - return !hci_cmd_sync_dequeue_once(hdev,
>> >> - hci_acl_create_conn_sync,
>> >> - conn, NULL);
>> >> + func = hci_acl_create_conn_sync;
>> >> + create_flag = HCI_CONN_CREATE;
>> >> + break;
>> >> case LE_LINK:
>> >> - return !hci_cmd_sync_dequeue_once(hdev, hci_le_create_conn_sync,
>> >> - conn, create_le_conn_complete);
>> >> + func = hci_le_create_conn_sync;
>> >> + destroy = create_le_conn_complete;
>> >> + create_flag = HCI_CONN_CREATE;
>> >> + break;
>> >> + case CIS_LINK:
>> >> + /* LE Create CIS is shared by the whole CIG and cannot be
>> >> + * dequeued per-connection; only cancel it in-flight below.
>> >> + */
>> >> + create_flag = HCI_CONN_CREATE_CIS;
>> >
>> > Instead of doing everything in the same function, it probably makes
>> > more sense to add dedicated functions for each type, for example,
>> > `hci_acl_cancel_create_conn_sync`, etc.
>> >
>>
>> int hci_cancel_connect_sync(struct hci_dev *hdev, struct hci_conn *conn)
>> {
>> switch (conn->type) {
>> case ACL_LINK:
>> return hci_cancel_create_conn_sync(hdev, conn, HCI_CONN_CREATE,
>> hci_acl_create_conn_sync,
>> NULL);
>> case LE_LINK:
>> return hci_cancel_create_conn_sync(hdev, conn, HCI_CONN_CREATE,
>> hci_le_create_conn_sync,
>> create_le_conn_complete);
>> case CIS_LINK:
>> return hci_cancel_create_conn_sync(hdev, conn,
>> HCI_CONN_CREATE_CIS, NULL,
>> NULL);
>> default:
>> return -ENOENT;
>> }
>> }
>>
>> I would like to have something like this.
>> hci_acl_cancel_create_conn_sync will have an unnecessary wrapper.
>> What do you think?
>
> No, just do what I said. Things like hci_cis_cancel_create_conn_sync
> are actually quite different on their own. In fact, if we handle more
> variants of conn->type the differences will actually become more
> pronounced so let's not pretend they are similar.
>
OK, will do.
>> >> + break;
>> >> + default:
>> >> + return -ENOENT;
>> >> }
>> >>
>> >> - return -ENOENT;
>> >> + /* The create command is either still queued or in flight. Hold
>> >> + * cmd_sync_work_lock across the test and the cancel: the worker takes
>> >> + * this lock to dequeue every entry, so while it is held no other command
>> >> + * can become pending, which keeps hci_cmd_sync_cancel() from racing with
>> >> + * completion and cancelling an unrelated command.
>> >> + */
>> >> + mutex_lock(&hdev->cmd_sync_work_lock);
>> >> +
>> >> + /* The flag is set while the worker blocks on the connection complete
>> >> + * event, so if it is set this connection owns the pending request.
>> >> + */
>> >> + if (create_flag >= 0 && test_bit(create_flag, &conn->flags)) {
>> >> + hci_cmd_sync_cancel(hdev, ECANCELED);
>> >> + goto unlock;
>> >> + }
>> >> +
>> >> + /* Otherwise it may still be queued; dequeue it. A successful dequeue
>> >> + * means it never started, so there is nothing to disconnect.
>> >> + */
>> >> + if (func) {
>> >> + entry = _hci_cmd_sync_lookup_entry(hdev, func, conn, destroy);
>> >> + if (entry) {
>> >> + _hci_cmd_sync_cancel_entry(hdev, entry, -ECANCELED);
>> >> + err = 0;
>> >> + }
>> >> + }
>> >> +
>> >> +unlock:
>> >> + mutex_unlock(&hdev->cmd_sync_work_lock);
>> >> + return err;
>> >> }
>> >>
>> >> int hci_le_conn_update_sync(struct hci_dev *hdev, struct hci_conn *conn,
>> >> --
>> >> 2.54.0
>> >>
>> >
>> >
>> > --
>> > Luiz Augusto von Dentz
>>
>> Best,
>> Siwei
>
>
>
> --
> Luiz Augusto von Dentz
Best,
Siwei
^ permalink raw reply
* Re: [PATCH v5 1/2] Bluetooth: hci_conn: Fix null ptr deref in hci_abort_conn()
From: Luiz Augusto von Dentz @ 2026-06-15 15:11 UTC (permalink / raw)
To: Siwei Zhang; +Cc: Pauli Virtanen, XIAO WU, linux-bluetooth
In-Reply-To: <cbe3c81f-7919-4a13-b636-5d2bc776e094@app.fastmail.com>
Hi Siwei,
On Mon, Jun 15, 2026 at 11:06 AM Siwei Zhang <oss@fourdim.xyz> wrote:
>
> Hi Luiz,
>
> On Mon, Jun 15, 2026, at 10:09 AM, Luiz Augusto von Dentz wrote:
> > Hi Siwei,
> >
> > On Mon, Jun 15, 2026 at 9:12 AM Siwei Zhang <oss@fourdim.xyz> wrote:
> >>
> >> hci_abort_conn() read hci_skb_event(hdev->sent_cmd) when a connection
> >> was pending, but hdev->sent_cmd can be NULL while req_status is still
> >> HCI_REQ_PEND, leading to a NULL pointer dereference and a general
> >> protection fault from the hci_rx_work() receive path.
> >>
> >> Instead of inspecting hdev->sent_cmd, track the in-flight create
> >> connection command with a new per-connection HCI_CONN_CREATE flag and
> >> route all cancellation through hci_cancel_connect_sync(). The create
> >> command is in exactly one of two states: still queued, or in flight.
> >> hci_cancel_connect_sync() holds cmd_sync_work_lock across the whole
> >> decision: the worker takes this lock to dequeue every entry, so while it
> >> is held a queued command cannot start running and an in-flight command
> >> cannot complete and let the next command become pending. This keeps the
> >> flag test and hci_cmd_sync_cancel() atomic with respect to the worker,
> >> so a queued command is simply dequeued, and an in-flight command owned
> >> by this connection is cancelled without the risk of cancelling an
> >> unrelated command that became pending in the meantime. CIS uses the same
> >> path via the existing HCI_CONN_CREATE_CIS flag.
> >>
> >> hci_acl_create_conn_sync() and hci_le_create_conn_sync() clear
> >> HCI_CONN_CREATE after the create command completes, but the command
> >> status handler can free conn via hci_conn_del() (for example when the
> >> controller rejects the connection) while the worker is still blocked on
> >> the connection complete event. Hold a reference on conn across the
> >> create command so the flag can be cleared without a use-after-free.
> >>
> >> Fixes: a13f316e90fd ("Bluetooth: hci_conn: Consolidate code for aborting connections")
> >> Cc: stable@vger.kernel.org
> >> Suggested-by: XIAO WU <xiaowu.417@qq.com>
> >> Assisted-by: Claude:claude-opus-4-8
> >> Signed-off-by: Siwei Zhang <oss@fourdim.xyz>
> >> ---
> >> include/net/bluetooth/hci_core.h | 1 +
> >> net/bluetooth/hci_conn.c | 21 +------
> >> net/bluetooth/hci_sync.c | 96 ++++++++++++++++++++++++++++----
> >> 3 files changed, 88 insertions(+), 30 deletions(-)
> >>
> >> diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
> >> index aa600fbf9a53..aa554c34f9ec 100644
> >> --- a/include/net/bluetooth/hci_core.h
> >> +++ b/include/net/bluetooth/hci_core.h
> >> @@ -988,6 +988,7 @@ enum {
> >> HCI_CONN_AUTH_FAILURE,
> >> HCI_CONN_PER_ADV,
> >> HCI_CONN_BIG_CREATED,
> >> + HCI_CONN_CREATE,
> >> HCI_CONN_CREATE_CIS,
> >> HCI_CONN_CREATE_BIG_SYNC,
> >> HCI_CONN_BIG_SYNC,
> >> diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
> >> index 54eabaa46960..eba4a548bef5 100644
> >> --- a/net/bluetooth/hci_conn.c
> >> +++ b/net/bluetooth/hci_conn.c
> >> @@ -3181,26 +3181,11 @@ int hci_abort_conn(struct hci_conn *conn, u8 reason)
> >>
> >> conn->abort_reason = reason;
> >>
> >> - /* If the connection is pending check the command opcode since that
> >> - * might be blocking on hci_cmd_sync_work while waiting its respective
> >> - * event so we need to hci_cmd_sync_cancel to cancel it.
> >> - *
> >> - * hci_connect_le serializes the connection attempts so only one
> >> - * connection can be in BT_CONNECT at time.
> >> + /* Cancel the connect attempt. A return of 0 means the create command
> >> + * was still queued and got dequeued, so there is nothing to disconnect.
> >> */
> >> - if (conn->state == BT_CONNECT && READ_ONCE(hdev->req_status) == HCI_REQ_PEND) {
> >> - switch (hci_skb_event(hdev->sent_cmd)) {
> >> - case HCI_EV_CONN_COMPLETE:
> >> - case HCI_EV_LE_CONN_COMPLETE:
> >> - case HCI_EV_LE_ENHANCED_CONN_COMPLETE:
> >> - case HCI_EVT_LE_CIS_ESTABLISHED:
> >> - hci_cmd_sync_cancel(hdev, ECANCELED);
> >> - break;
> >> - }
> >> - /* Cancel connect attempt if still queued/pending */
> >> - } else if (!hci_cancel_connect_sync(hdev, conn)) {
> >> + if (!hci_cancel_connect_sync(hdev, conn))
> >> return 0;
> >> - }
> >>
> >> /* Run immediately if on cmd_sync_work since this may be called
> >> * as a result to MGMT_OP_DISCONNECT/MGMT_OP_UNPAIR which does
> >> diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
> >> index df23245d6ccd..06b87e9cd999 100644
> >> --- a/net/bluetooth/hci_sync.c
> >> +++ b/net/bluetooth/hci_sync.c
> >> @@ -6611,6 +6611,11 @@ static int hci_le_create_conn_sync(struct hci_dev *hdev, void *data)
> >>
> >> bt_dev_dbg(hdev, "conn %p", conn);
> >>
> >> + /* Hold a reference so conn stays valid for the HCI_CONN_CREATE
> >> + * clear_bit() at done.
> >> + */
> >> + hci_conn_get(conn);
> >> +
> >> clear_bit(HCI_CONN_SCANNING, &conn->flags);
> >> conn->state = BT_CONNECT;
> >>
> >> @@ -6623,6 +6628,7 @@ static int hci_le_create_conn_sync(struct hci_dev *hdev, void *data)
> >> hdev->le_scan_type == LE_SCAN_ACTIVE &&
> >> !hci_dev_test_flag(hdev, HCI_LE_SIMULTANEOUS_ROLES)) {
> >> hci_conn_del(conn);
> >> + hci_conn_put(conn);
> >> return -EBUSY;
> >> }
> >>
> >> @@ -6668,6 +6674,12 @@ static int hci_le_create_conn_sync(struct hci_dev *hdev, void *data)
> >> &own_addr_type);
> >> if (err)
> >> goto done;
> >> +
> >> + /* Mark create connection in flight so hci_cancel_connect_sync() can
> >> + * cancel it while blocking on the connection complete event.
> >> + */
> >> + set_bit(HCI_CONN_CREATE, &conn->flags);
> >> +
> >> /* Send command LE Extended Create Connection if supported */
> >> if (use_ext_conn(hdev)) {
> >> err = hci_le_ext_create_conn_sync(hdev, conn, own_addr_type);
> >> @@ -6703,11 +6715,14 @@ static int hci_le_create_conn_sync(struct hci_dev *hdev, void *data)
> >> conn->conn_timeout, NULL);
> >>
> >> done:
> >> + clear_bit(HCI_CONN_CREATE, &conn->flags);
> >> +
> >> if (err == -ETIMEDOUT)
> >> hci_le_connect_cancel_sync(hdev, conn, 0x00);
> >>
> >> /* Re-enable advertising after the connection attempt is finished. */
> >> hci_resume_advertising_sync(hdev);
> >> + hci_conn_put(conn);
> >> return err;
> >> }
> >>
> >> @@ -6982,10 +6997,25 @@ static int hci_acl_create_conn_sync(struct hci_dev *hdev, void *data)
> >> else
> >> cp.role_switch = 0x00;
> >>
> >> - return __hci_cmd_sync_status_sk(hdev, HCI_OP_CREATE_CONN,
> >> - sizeof(cp), &cp,
> >> - HCI_EV_CONN_COMPLETE,
> >> - conn->conn_timeout, NULL);
> >> + /* Hold a reference so conn stays valid for the HCI_CONN_CREATE
> >> + * clear_bit() below.
> >> + */
> >> + hci_conn_get(conn);
> >> +
> >> + /* Mark create connection in flight so hci_cancel_connect_sync() can
> >> + * cancel it while blocking on the connection complete event.
> >> + */
> >> + set_bit(HCI_CONN_CREATE, &conn->flags);
> >> +
> >> + err = __hci_cmd_sync_status_sk(hdev, HCI_OP_CREATE_CONN,
> >> + sizeof(cp), &cp,
> >> + HCI_EV_CONN_COMPLETE,
> >> + conn->conn_timeout, NULL);
> >> +
> >> + clear_bit(HCI_CONN_CREATE, &conn->flags);
> >> + hci_conn_put(conn);
> >> +
> >> + return err;
> >> }
> >>
> >> int hci_connect_acl_sync(struct hci_dev *hdev, struct hci_conn *conn)
> >> @@ -7039,20 +7069,62 @@ int hci_connect_le_sync(struct hci_dev *hdev, struct hci_conn *conn)
> >>
> >> int hci_cancel_connect_sync(struct hci_dev *hdev, struct hci_conn *conn)
> >> {
> >> - if (conn->state != BT_OPEN)
> >> - return -EINVAL;
> >> + struct hci_cmd_sync_work_entry *entry;
> >> + hci_cmd_sync_work_func_t func = NULL;
> >> + hci_cmd_sync_work_destroy_t destroy = NULL;
> >> + int create_flag = -1;
> >> + int err = -EBUSY;
> >>
> >> switch (conn->type) {
> >> case ACL_LINK:
> >> - return !hci_cmd_sync_dequeue_once(hdev,
> >> - hci_acl_create_conn_sync,
> >> - conn, NULL);
> >> + func = hci_acl_create_conn_sync;
> >> + create_flag = HCI_CONN_CREATE;
> >> + break;
> >> case LE_LINK:
> >> - return !hci_cmd_sync_dequeue_once(hdev, hci_le_create_conn_sync,
> >> - conn, create_le_conn_complete);
> >> + func = hci_le_create_conn_sync;
> >> + destroy = create_le_conn_complete;
> >> + create_flag = HCI_CONN_CREATE;
> >> + break;
> >> + case CIS_LINK:
> >> + /* LE Create CIS is shared by the whole CIG and cannot be
> >> + * dequeued per-connection; only cancel it in-flight below.
> >> + */
> >> + create_flag = HCI_CONN_CREATE_CIS;
> >
> > Instead of doing everything in the same function, it probably makes
> > more sense to add dedicated functions for each type, for example,
> > `hci_acl_cancel_create_conn_sync`, etc.
> >
>
> int hci_cancel_connect_sync(struct hci_dev *hdev, struct hci_conn *conn)
> {
> switch (conn->type) {
> case ACL_LINK:
> return hci_cancel_create_conn_sync(hdev, conn, HCI_CONN_CREATE,
> hci_acl_create_conn_sync,
> NULL);
> case LE_LINK:
> return hci_cancel_create_conn_sync(hdev, conn, HCI_CONN_CREATE,
> hci_le_create_conn_sync,
> create_le_conn_complete);
> case CIS_LINK:
> return hci_cancel_create_conn_sync(hdev, conn,
> HCI_CONN_CREATE_CIS, NULL,
> NULL);
> default:
> return -ENOENT;
> }
> }
>
> I would like to have something like this.
> hci_acl_cancel_create_conn_sync will have an unnecessary wrapper.
> What do you think?
No, just do what I said. Things like hci_cis_cancel_create_conn_sync
are actually quite different on their own. In fact, if we handle more
variants of conn->type the differences will actually become more
pronounced so let's not pretend they are similar.
> >> + break;
> >> + default:
> >> + return -ENOENT;
> >> }
> >>
> >> - return -ENOENT;
> >> + /* The create command is either still queued or in flight. Hold
> >> + * cmd_sync_work_lock across the test and the cancel: the worker takes
> >> + * this lock to dequeue every entry, so while it is held no other command
> >> + * can become pending, which keeps hci_cmd_sync_cancel() from racing with
> >> + * completion and cancelling an unrelated command.
> >> + */
> >> + mutex_lock(&hdev->cmd_sync_work_lock);
> >> +
> >> + /* The flag is set while the worker blocks on the connection complete
> >> + * event, so if it is set this connection owns the pending request.
> >> + */
> >> + if (create_flag >= 0 && test_bit(create_flag, &conn->flags)) {
> >> + hci_cmd_sync_cancel(hdev, ECANCELED);
> >> + goto unlock;
> >> + }
> >> +
> >> + /* Otherwise it may still be queued; dequeue it. A successful dequeue
> >> + * means it never started, so there is nothing to disconnect.
> >> + */
> >> + if (func) {
> >> + entry = _hci_cmd_sync_lookup_entry(hdev, func, conn, destroy);
> >> + if (entry) {
> >> + _hci_cmd_sync_cancel_entry(hdev, entry, -ECANCELED);
> >> + err = 0;
> >> + }
> >> + }
> >> +
> >> +unlock:
> >> + mutex_unlock(&hdev->cmd_sync_work_lock);
> >> + return err;
> >> }
> >>
> >> int hci_le_conn_update_sync(struct hci_dev *hdev, struct hci_conn *conn,
> >> --
> >> 2.54.0
> >>
> >
> >
> > --
> > Luiz Augusto von Dentz
>
> Best,
> Siwei
--
Luiz Augusto von Dentz
^ permalink raw reply
* [PATCH] Bluetooth: MGMT: Fix UAF of hci_conn_params in add_device_complete
From: Samuel Page @ 2026-06-15 15:09 UTC (permalink / raw)
To: Marcel Holtmann, Luiz Augusto von Dentz
Cc: linux-bluetooth, linux-kernel, Samuel Page, stable
add_device_complete() runs from the hci_cmd_sync_work kworker, which
holds only hci_req_sync_lock and *not* hci_dev_lock. It calls
hci_conn_params_lookup() and then dereferences the returned object
(params->flags) without taking hci_dev_lock:
params = hci_conn_params_lookup(hdev, &cp->addr.bdaddr,
le_addr_type(cp->addr.type));
...
device_flags_changed(NULL, hdev, &cp->addr.bdaddr,
cp->addr.type, hdev->conn_flags,
params ? params->flags : 0);
hci_conn_params_lookup() walks hdev->le_conn_params and is documented to
require hdev->lock. A concurrent MGMT_OP_REMOVE_DEVICE
(remove_device()), which does run under hci_dev_lock, can call
hci_conn_params_free() to list_del() and kfree() the very object the
lookup returned, so the subsequent params->flags read touches freed
memory [0].
Hold hci_dev_lock() across the hci_conn_params_lookup() and the read of
params->flags (and the matching event emission) so the lookup result
cannot be freed by a concurrent remove_device() before it is used,
honouring the locking contract of hci_conn_params_lookup().
[0]: (trailing page/memory-state dump trimmed)
BUG: KASAN: slab-use-after-free in add_device_complete+0x358/0x3d8 net/bluetooth/mgmt.c:7671
Read of size 1 at addr ffff000017ab26c1 by task kworker/u9:8/388
CPU: 1 UID: 0 PID: 388 Comm: kworker/u9:8 Not tainted 7.0.11 #20 PREEMPT
Hardware name: linux,dummy-virt (DT)
Workqueue: hci0 hci_cmd_sync_work
Call trace:
show_stack+0x2c/0x3c arch/arm64/kernel/stacktrace.c:499 (C)
__dump_stack lib/dump_stack.c:94 [inline]
dump_stack_lvl+0xb4/0xd4 lib/dump_stack.c:120
print_address_description mm/kasan/report.c:378 [inline]
print_report+0x118/0x5d8 mm/kasan/report.c:482
kasan_report+0xb0/0xf4 mm/kasan/report.c:595
__asan_report_load1_noabort+0x20/0x2c mm/kasan/report_generic.c:378
add_device_complete+0x358/0x3d8 net/bluetooth/mgmt.c:7671
hci_cmd_sync_work+0x14c/0x240 net/bluetooth/hci_sync.c:334
process_one_work+0x628/0xd38 kernel/workqueue.c:3289
process_scheduled_works kernel/workqueue.c:3372 [inline]
worker_thread+0x7a8/0xac0 kernel/workqueue.c:3453
kthread+0x39c/0x444 kernel/kthread.c:436
ret_from_fork+0x10/0x20 arch/arm64/kernel/entry.S:860
Allocated by task 3401:
kasan_save_stack+0x3c/0x64 mm/kasan/common.c:57
kasan_save_track+0x20/0x3c mm/kasan/common.c:78
kasan_save_alloc_info+0x40/0x54 mm/kasan/generic.c:570
poison_kmalloc_redzone mm/kasan/common.c:398 [inline]
__kasan_kmalloc+0xd4/0xd8 mm/kasan/common.c:415
kasan_kmalloc include/linux/kasan.h:263 [inline]
__kmalloc_cache_noprof+0x1b0/0x458 mm/slub.c:5385
kmalloc_noprof include/linux/slab.h:950 [inline]
kzalloc_noprof include/linux/slab.h:1188 [inline]
hci_conn_params_add+0x10c/0x4b0 net/bluetooth/hci_core.c:2279
hci_conn_params_set net/bluetooth/mgmt.c:5162 [inline]
add_device+0x5b4/0xa54 net/bluetooth/mgmt.c:7755
hci_mgmt_cmd net/bluetooth/hci_sock.c:1721 [inline]
hci_sock_sendmsg+0x10b4/0x1dd0 net/bluetooth/hci_sock.c:1841
sock_sendmsg_nosec net/socket.c:727 [inline]
__sock_sendmsg+0xe0/0x128 net/socket.c:742
sock_write_iter+0x250/0x390 net/socket.c:1195
new_sync_write fs/read_write.c:595 [inline]
vfs_write+0x66c/0xab0 fs/read_write.c:688
ksys_write+0x1fc/0x24c fs/read_write.c:740
__do_sys_write fs/read_write.c:751 [inline]
__se_sys_write fs/read_write.c:748 [inline]
__arm64_sys_write+0x70/0xa4 fs/read_write.c:748
__invoke_syscall arch/arm64/kernel/syscall.c:35 [inline]
invoke_syscall+0x84/0x2a8 arch/arm64/kernel/syscall.c:49
el0_svc_common.constprop.0+0xe4/0x294 arch/arm64/kernel/syscall.c:132
do_el0_svc+0x44/0x5c arch/arm64/kernel/syscall.c:151
el0_svc+0x38/0xac arch/arm64/kernel/entry-common.c:724
el0t_64_sync_handler+0xa0/0xe4 arch/arm64/kernel/entry-common.c:743
el0t_64_sync+0x198/0x19c arch/arm64/kernel/entry.S:596
Freed by task 3740:
kasan_save_stack+0x3c/0x64 mm/kasan/common.c:57
kasan_save_track+0x20/0x3c mm/kasan/common.c:78
kasan_save_free_info+0x4c/0x74 mm/kasan/generic.c:584
poison_slab_object mm/kasan/common.c:253 [inline]
__kasan_slab_free+0x88/0xb8 mm/kasan/common.c:285
kasan_slab_free include/linux/kasan.h:235 [inline]
slab_free_hook mm/slub.c:2685 [inline]
slab_free mm/slub.c:6170 [inline]
kfree+0x14c/0x458 mm/slub.c:6488
hci_conn_params_free+0x288/0x484 net/bluetooth/hci_core.c:2312
remove_device+0x4b0/0x968 net/bluetooth/mgmt.c:7919
hci_mgmt_cmd net/bluetooth/hci_sock.c:1721 [inline]
hci_sock_sendmsg+0x10b4/0x1dd0 net/bluetooth/hci_sock.c:1841
sock_sendmsg_nosec net/socket.c:727 [inline]
__sock_sendmsg+0xe0/0x128 net/socket.c:742
sock_write_iter+0x250/0x390 net/socket.c:1195
new_sync_write fs/read_write.c:595 [inline]
vfs_write+0x66c/0xab0 fs/read_write.c:688
ksys_write+0x1fc/0x24c fs/read_write.c:740
__do_sys_write fs/read_write.c:751 [inline]
__se_sys_write fs/read_write.c:748 [inline]
__arm64_sys_write+0x70/0xa4 fs/read_write.c:748
__invoke_syscall arch/arm64/kernel/syscall.c:35 [inline]
invoke_syscall+0x84/0x2a8 arch/arm64/kernel/syscall.c:49
el0_svc_common.constprop.0+0xe4/0x294 arch/arm64/kernel/syscall.c:132
do_el0_svc+0x44/0x5c arch/arm64/kernel/syscall.c:151
el0_svc+0x38/0xac arch/arm64/kernel/entry-common.c:724
el0t_64_sync_handler+0xa0/0xe4 arch/arm64/kernel/entry-common.c:743
el0t_64_sync+0x198/0x19c arch/arm64/kernel/entry.S:596
Fixes: 1e2e3044c1bc ("Bluetooth: MGMT: Fix MGMT_OP_ADD_DEVICE invalid device flags")
Cc: stable@vger.kernel.org
Assisted-by: Bynario AI
Signed-off-by: Samuel Page <sam@bynar.io>
---
net/bluetooth/mgmt.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index d23ca1dd0893..dc55763f9e58 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -7658,6 +7658,8 @@ static void add_device_complete(struct hci_dev *hdev, void *data, int err)
if (!err) {
struct hci_conn_params *params;
+ hci_dev_lock(hdev);
+
params = hci_conn_params_lookup(hdev, &cp->addr.bdaddr,
le_addr_type(cp->addr.type));
@@ -7666,6 +7668,7 @@ static void add_device_complete(struct hci_dev *hdev, void *data, int err)
device_flags_changed(NULL, hdev, &cp->addr.bdaddr,
cp->addr.type, hdev->conn_flags,
params ? params->flags : 0);
+ hci_dev_unlock(hdev);
}
mgmt_cmd_complete(cmd->sk, hdev->id, MGMT_OP_ADD_DEVICE,
base-commit: f70f7f2512c6b9113dc78f6a25361166afd1412e
--
2.54.0
^ permalink raw reply related
* Re: [PATCH v5 1/2] Bluetooth: hci_conn: Fix null ptr deref in hci_abort_conn()
From: Siwei Zhang @ 2026-06-15 15:06 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: Pauli Virtanen, XIAO WU, linux-bluetooth
In-Reply-To: <CABBYNZKRTpmnQ44UWH_0jFwQY9OOP5LAHE2+1ZZn-Ckic4wGZQ@mail.gmail.com>
Hi Luiz,
On Mon, Jun 15, 2026, at 10:09 AM, Luiz Augusto von Dentz wrote:
> Hi Siwei,
>
> On Mon, Jun 15, 2026 at 9:12 AM Siwei Zhang <oss@fourdim.xyz> wrote:
>>
>> hci_abort_conn() read hci_skb_event(hdev->sent_cmd) when a connection
>> was pending, but hdev->sent_cmd can be NULL while req_status is still
>> HCI_REQ_PEND, leading to a NULL pointer dereference and a general
>> protection fault from the hci_rx_work() receive path.
>>
>> Instead of inspecting hdev->sent_cmd, track the in-flight create
>> connection command with a new per-connection HCI_CONN_CREATE flag and
>> route all cancellation through hci_cancel_connect_sync(). The create
>> command is in exactly one of two states: still queued, or in flight.
>> hci_cancel_connect_sync() holds cmd_sync_work_lock across the whole
>> decision: the worker takes this lock to dequeue every entry, so while it
>> is held a queued command cannot start running and an in-flight command
>> cannot complete and let the next command become pending. This keeps the
>> flag test and hci_cmd_sync_cancel() atomic with respect to the worker,
>> so a queued command is simply dequeued, and an in-flight command owned
>> by this connection is cancelled without the risk of cancelling an
>> unrelated command that became pending in the meantime. CIS uses the same
>> path via the existing HCI_CONN_CREATE_CIS flag.
>>
>> hci_acl_create_conn_sync() and hci_le_create_conn_sync() clear
>> HCI_CONN_CREATE after the create command completes, but the command
>> status handler can free conn via hci_conn_del() (for example when the
>> controller rejects the connection) while the worker is still blocked on
>> the connection complete event. Hold a reference on conn across the
>> create command so the flag can be cleared without a use-after-free.
>>
>> Fixes: a13f316e90fd ("Bluetooth: hci_conn: Consolidate code for aborting connections")
>> Cc: stable@vger.kernel.org
>> Suggested-by: XIAO WU <xiaowu.417@qq.com>
>> Assisted-by: Claude:claude-opus-4-8
>> Signed-off-by: Siwei Zhang <oss@fourdim.xyz>
>> ---
>> include/net/bluetooth/hci_core.h | 1 +
>> net/bluetooth/hci_conn.c | 21 +------
>> net/bluetooth/hci_sync.c | 96 ++++++++++++++++++++++++++++----
>> 3 files changed, 88 insertions(+), 30 deletions(-)
>>
>> diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
>> index aa600fbf9a53..aa554c34f9ec 100644
>> --- a/include/net/bluetooth/hci_core.h
>> +++ b/include/net/bluetooth/hci_core.h
>> @@ -988,6 +988,7 @@ enum {
>> HCI_CONN_AUTH_FAILURE,
>> HCI_CONN_PER_ADV,
>> HCI_CONN_BIG_CREATED,
>> + HCI_CONN_CREATE,
>> HCI_CONN_CREATE_CIS,
>> HCI_CONN_CREATE_BIG_SYNC,
>> HCI_CONN_BIG_SYNC,
>> diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
>> index 54eabaa46960..eba4a548bef5 100644
>> --- a/net/bluetooth/hci_conn.c
>> +++ b/net/bluetooth/hci_conn.c
>> @@ -3181,26 +3181,11 @@ int hci_abort_conn(struct hci_conn *conn, u8 reason)
>>
>> conn->abort_reason = reason;
>>
>> - /* If the connection is pending check the command opcode since that
>> - * might be blocking on hci_cmd_sync_work while waiting its respective
>> - * event so we need to hci_cmd_sync_cancel to cancel it.
>> - *
>> - * hci_connect_le serializes the connection attempts so only one
>> - * connection can be in BT_CONNECT at time.
>> + /* Cancel the connect attempt. A return of 0 means the create command
>> + * was still queued and got dequeued, so there is nothing to disconnect.
>> */
>> - if (conn->state == BT_CONNECT && READ_ONCE(hdev->req_status) == HCI_REQ_PEND) {
>> - switch (hci_skb_event(hdev->sent_cmd)) {
>> - case HCI_EV_CONN_COMPLETE:
>> - case HCI_EV_LE_CONN_COMPLETE:
>> - case HCI_EV_LE_ENHANCED_CONN_COMPLETE:
>> - case HCI_EVT_LE_CIS_ESTABLISHED:
>> - hci_cmd_sync_cancel(hdev, ECANCELED);
>> - break;
>> - }
>> - /* Cancel connect attempt if still queued/pending */
>> - } else if (!hci_cancel_connect_sync(hdev, conn)) {
>> + if (!hci_cancel_connect_sync(hdev, conn))
>> return 0;
>> - }
>>
>> /* Run immediately if on cmd_sync_work since this may be called
>> * as a result to MGMT_OP_DISCONNECT/MGMT_OP_UNPAIR which does
>> diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
>> index df23245d6ccd..06b87e9cd999 100644
>> --- a/net/bluetooth/hci_sync.c
>> +++ b/net/bluetooth/hci_sync.c
>> @@ -6611,6 +6611,11 @@ static int hci_le_create_conn_sync(struct hci_dev *hdev, void *data)
>>
>> bt_dev_dbg(hdev, "conn %p", conn);
>>
>> + /* Hold a reference so conn stays valid for the HCI_CONN_CREATE
>> + * clear_bit() at done.
>> + */
>> + hci_conn_get(conn);
>> +
>> clear_bit(HCI_CONN_SCANNING, &conn->flags);
>> conn->state = BT_CONNECT;
>>
>> @@ -6623,6 +6628,7 @@ static int hci_le_create_conn_sync(struct hci_dev *hdev, void *data)
>> hdev->le_scan_type == LE_SCAN_ACTIVE &&
>> !hci_dev_test_flag(hdev, HCI_LE_SIMULTANEOUS_ROLES)) {
>> hci_conn_del(conn);
>> + hci_conn_put(conn);
>> return -EBUSY;
>> }
>>
>> @@ -6668,6 +6674,12 @@ static int hci_le_create_conn_sync(struct hci_dev *hdev, void *data)
>> &own_addr_type);
>> if (err)
>> goto done;
>> +
>> + /* Mark create connection in flight so hci_cancel_connect_sync() can
>> + * cancel it while blocking on the connection complete event.
>> + */
>> + set_bit(HCI_CONN_CREATE, &conn->flags);
>> +
>> /* Send command LE Extended Create Connection if supported */
>> if (use_ext_conn(hdev)) {
>> err = hci_le_ext_create_conn_sync(hdev, conn, own_addr_type);
>> @@ -6703,11 +6715,14 @@ static int hci_le_create_conn_sync(struct hci_dev *hdev, void *data)
>> conn->conn_timeout, NULL);
>>
>> done:
>> + clear_bit(HCI_CONN_CREATE, &conn->flags);
>> +
>> if (err == -ETIMEDOUT)
>> hci_le_connect_cancel_sync(hdev, conn, 0x00);
>>
>> /* Re-enable advertising after the connection attempt is finished. */
>> hci_resume_advertising_sync(hdev);
>> + hci_conn_put(conn);
>> return err;
>> }
>>
>> @@ -6982,10 +6997,25 @@ static int hci_acl_create_conn_sync(struct hci_dev *hdev, void *data)
>> else
>> cp.role_switch = 0x00;
>>
>> - return __hci_cmd_sync_status_sk(hdev, HCI_OP_CREATE_CONN,
>> - sizeof(cp), &cp,
>> - HCI_EV_CONN_COMPLETE,
>> - conn->conn_timeout, NULL);
>> + /* Hold a reference so conn stays valid for the HCI_CONN_CREATE
>> + * clear_bit() below.
>> + */
>> + hci_conn_get(conn);
>> +
>> + /* Mark create connection in flight so hci_cancel_connect_sync() can
>> + * cancel it while blocking on the connection complete event.
>> + */
>> + set_bit(HCI_CONN_CREATE, &conn->flags);
>> +
>> + err = __hci_cmd_sync_status_sk(hdev, HCI_OP_CREATE_CONN,
>> + sizeof(cp), &cp,
>> + HCI_EV_CONN_COMPLETE,
>> + conn->conn_timeout, NULL);
>> +
>> + clear_bit(HCI_CONN_CREATE, &conn->flags);
>> + hci_conn_put(conn);
>> +
>> + return err;
>> }
>>
>> int hci_connect_acl_sync(struct hci_dev *hdev, struct hci_conn *conn)
>> @@ -7039,20 +7069,62 @@ int hci_connect_le_sync(struct hci_dev *hdev, struct hci_conn *conn)
>>
>> int hci_cancel_connect_sync(struct hci_dev *hdev, struct hci_conn *conn)
>> {
>> - if (conn->state != BT_OPEN)
>> - return -EINVAL;
>> + struct hci_cmd_sync_work_entry *entry;
>> + hci_cmd_sync_work_func_t func = NULL;
>> + hci_cmd_sync_work_destroy_t destroy = NULL;
>> + int create_flag = -1;
>> + int err = -EBUSY;
>>
>> switch (conn->type) {
>> case ACL_LINK:
>> - return !hci_cmd_sync_dequeue_once(hdev,
>> - hci_acl_create_conn_sync,
>> - conn, NULL);
>> + func = hci_acl_create_conn_sync;
>> + create_flag = HCI_CONN_CREATE;
>> + break;
>> case LE_LINK:
>> - return !hci_cmd_sync_dequeue_once(hdev, hci_le_create_conn_sync,
>> - conn, create_le_conn_complete);
>> + func = hci_le_create_conn_sync;
>> + destroy = create_le_conn_complete;
>> + create_flag = HCI_CONN_CREATE;
>> + break;
>> + case CIS_LINK:
>> + /* LE Create CIS is shared by the whole CIG and cannot be
>> + * dequeued per-connection; only cancel it in-flight below.
>> + */
>> + create_flag = HCI_CONN_CREATE_CIS;
>
> Instead of doing everything in the same function, it probably makes
> more sense to add dedicated functions for each type, for example,
> `hci_acl_cancel_create_conn_sync`, etc.
>
int hci_cancel_connect_sync(struct hci_dev *hdev, struct hci_conn *conn)
{
switch (conn->type) {
case ACL_LINK:
return hci_cancel_create_conn_sync(hdev, conn, HCI_CONN_CREATE,
hci_acl_create_conn_sync,
NULL);
case LE_LINK:
return hci_cancel_create_conn_sync(hdev, conn, HCI_CONN_CREATE,
hci_le_create_conn_sync,
create_le_conn_complete);
case CIS_LINK:
return hci_cancel_create_conn_sync(hdev, conn,
HCI_CONN_CREATE_CIS, NULL,
NULL);
default:
return -ENOENT;
}
}
I would like to have something like this.
hci_acl_cancel_create_conn_sync will have an unnecessary wrapper.
What do you think?
>> + break;
>> + default:
>> + return -ENOENT;
>> }
>>
>> - return -ENOENT;
>> + /* The create command is either still queued or in flight. Hold
>> + * cmd_sync_work_lock across the test and the cancel: the worker takes
>> + * this lock to dequeue every entry, so while it is held no other command
>> + * can become pending, which keeps hci_cmd_sync_cancel() from racing with
>> + * completion and cancelling an unrelated command.
>> + */
>> + mutex_lock(&hdev->cmd_sync_work_lock);
>> +
>> + /* The flag is set while the worker blocks on the connection complete
>> + * event, so if it is set this connection owns the pending request.
>> + */
>> + if (create_flag >= 0 && test_bit(create_flag, &conn->flags)) {
>> + hci_cmd_sync_cancel(hdev, ECANCELED);
>> + goto unlock;
>> + }
>> +
>> + /* Otherwise it may still be queued; dequeue it. A successful dequeue
>> + * means it never started, so there is nothing to disconnect.
>> + */
>> + if (func) {
>> + entry = _hci_cmd_sync_lookup_entry(hdev, func, conn, destroy);
>> + if (entry) {
>> + _hci_cmd_sync_cancel_entry(hdev, entry, -ECANCELED);
>> + err = 0;
>> + }
>> + }
>> +
>> +unlock:
>> + mutex_unlock(&hdev->cmd_sync_work_lock);
>> + return err;
>> }
>>
>> int hci_le_conn_update_sync(struct hci_dev *hdev, struct hci_conn *conn,
>> --
>> 2.54.0
>>
>
>
> --
> Luiz Augusto von Dentz
Best,
Siwei
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox