Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH v3] Bluetooth: L2CAP: Fix UAF in channel timeout by holding conn ref
From: Luiz Augusto von Dentz @ 2026-06-09 19:32 UTC (permalink / raw)
  To: linux-bluetooth

From: Marco Elver <elver@google.com>

l2cap_chan_timeout() runs asynchronously and accesses chan->conn. If
the connection is torn down while the timer is running or pending,
chan->conn can be freed, leading to a use-after-free when the timer
worker attempts to lock conn->lock:

| BUG: KASAN: slab-use-after-free in instrument_atomic_read_write include/linux/instrumented.h:112 [inline]
| BUG: KASAN: slab-use-after-free in atomic_long_try_cmpxchg_acquire include/linux/atomic/atomic-instrumented.h:4456 [inline]
| BUG: KASAN: slab-use-after-free in __mutex_trylock_fast kernel/locking/mutex.c:161 [inline]
| BUG: KASAN: slab-use-after-free in mutex_lock+0x4f/0xa0 kernel/locking/mutex.c:318
| Write of size 8 at addr ffff8881298d9550 by task kworker/2:1/83
|
| CPU: 2 UID: 0 PID: 83 Comm: kworker/2:1 Not tainted 7.1.0-rc6-next-20260601-dirty #6 PREEMPT(full)
| Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-debian-1.17.0-1 04/01/2014
| Workqueue: events l2cap_chan_timeout
| Call Trace:
|  <TASK>
|  instrument_atomic_read_write include/linux/instrumented.h:112 [inline]
|  atomic_long_try_cmpxchg_acquire include/linux/atomic/atomic-instrumented.h:4456 [inline]
|  __mutex_trylock_fast kernel/locking/mutex.c:161 [inline]
|  mutex_lock+0x4f/0xa0 kernel/locking/mutex.c:318
|  l2cap_chan_timeout+0x5d/0x1b0 net/bluetooth/l2cap_core.c:422
|  process_one_work kernel/workqueue.c:3326 [inline]
|  process_scheduled_works+0x7c8/0xfb0 kernel/workqueue.c:3409
|  worker_thread+0x8a9/0xcf0 kernel/workqueue.c:3490
|  kthread+0x346/0x430 kernel/kthread.c:436
|  ret_from_fork+0x1a3/0x470 arch/x86/kernel/process.c:158
|  ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
|  </TASK>
|
| Allocated by task 320:
|  l2cap_conn_add+0xa7/0x820 net/bluetooth/l2cap_core.c:7075
|  l2cap_connect_cfm+0xdb/0xd70 net/bluetooth/l2cap_core.c:7452
|  hci_connect_cfm include/net/bluetooth/hci_core.h:2139 [inline]
|  hci_remote_features_evt+0x52f/0x9f0 net/bluetooth/hci_event.c:3760
|  hci_event_func net/bluetooth/hci_event.c:7796 [inline]
|  hci_event_packet+0x561/0xa70 net/bluetooth/hci_event.c:7847
|  hci_rx_work+0x370/0x890 net/bluetooth/hci_core.c:4040
|  process_one_work kernel/workqueue.c:3326 [inline]
|  process_scheduled_works+0x7c8/0xfb0 kernel/workqueue.c:3409
|  worker_thread+0x8a9/0xcf0 kernel/workqueue.c:3490
|  kthread+0x346/0x430 kernel/kthread.c:436
|  ret_from_fork+0x1a3/0x470 arch/x86/kernel/process.c:158
|  ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
|
| Freed by task 322:
|  hci_disconn_cfm include/net/bluetooth/hci_core.h:2154 [inline]
|  hci_conn_hash_flush+0x101/0x1f0 net/bluetooth/hci_conn.c:2736
|  hci_dev_close_sync+0x889/0xde0 net/bluetooth/hci_sync.c:5405
|  hci_dev_do_close net/bluetooth/hci_core.c:502 [inline]
|  hci_unregister_dev+0x1f7/0x370 net/bluetooth/hci_core.c:2679
|  vhci_release+0x12a/0x180 drivers/bluetooth/hci_vhci.c:690
|  __fput+0x369/0x890 fs/file_table.c:510
|  task_work_run+0x160/0x1d0 kernel/task_work.c:233
|  get_signal+0xf5b/0x1120 kernel/signal.c:2810
|  arch_do_signal_or_restart+0x4d/0x600 arch/x86/kernel/signal.c:337
|  __exit_to_user_mode_loop kernel/entry/common.c:64 [inline]
|  exit_to_user_mode_loop+0x85/0x510 kernel/entry/common.c:98
|  do_syscall_64+0x263/0x3d0 arch/x86/entry/syscall_64.c:100
|  entry_SYSCALL_64_after_hwframe+0x77/0x7f
|
| The buggy address belongs to the object at ffff8881298d9400
|  which belongs to the cache kmalloc-512 of size 512
| The buggy address is located 336 bytes inside of
|  freed 512-byte region [ffff8881298d9400, ffff8881298d9600)

Fix it by having chan->conn hold a reference to l2cap_conn (via
l2cap_conn_get) when the channel is added to the connection, and
releasing it in the channel destructor. This ensures the l2cap_conn
remains alive as long as the channel exists.

A new FLAG_DEL channel flag is introduced to indicate that the channel
has been deleted from its connection. l2cap_chan_del() atomically sets
this flag using test_and_set_bit() instead of setting chan->conn to
NULL. All asynchronous workers (l2cap_chan_timeout, l2cap_ack_timeout,
l2cap_monitor_timeout, l2cap_retrans_timeout) and l2cap_chan_send()
check FLAG_DEL to determine whether the channel has been torn down,
rather than testing chan->conn for NULL.

Fixes: 75780ca4c6a8 ("Bluetooth: L2CAP: use chan timer to close channels in cleanup_listen()")
Cc: <stable@vger.kernel.org>
Cc: Siwei Zhang <oss@fourdim.xyz>
Cc: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Assisted-by: Gemini:gemini-3.1-pro-preview
Reported-by: https://sashiko.dev/#/patchset/20260521021249.3258069-1-oss%40fourdim.xyz
Signed-off-by: Marco Elver <elver@google.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
 include/net/bluetooth/l2cap.h |  1 +
 net/bluetooth/l2cap_core.c    | 34 ++++++++++++++++++++--------------
 2 files changed, 21 insertions(+), 14 deletions(-)

diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 790935950a0c..1640cc9bf83a 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -745,6 +745,7 @@ enum {
 	FLAG_ECRED_CONN_REQ_SENT,
 	FLAG_PENDING_SECURITY,
 	FLAG_HOLD_HCI_CONN,
+	FLAG_DEL,
 };
 
 /* Lock nesting levels for L2CAP channels. We need these because lockdep
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 863fc4b8a55e..a97d492473e2 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -408,7 +408,7 @@ static void l2cap_chan_timeout(struct work_struct *work)
 
 	BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
 
-	if (!conn) {
+	if (test_bit(FLAG_DEL, &chan->flags)) {
 		l2cap_chan_put(chan);
 		return;
 	}
@@ -419,6 +419,9 @@ static void l2cap_chan_timeout(struct work_struct *work)
 	 */
 	l2cap_chan_lock(chan);
 
+	if (test_bit(FLAG_DEL, &chan->flags))
+		goto unlock;
+
 	if (chan->state == BT_CONNECTED || chan->state == BT_CONFIG)
 		reason = ECONNREFUSED;
 	else if (chan->state == BT_CONNECT &&
@@ -431,10 +434,10 @@ static void l2cap_chan_timeout(struct work_struct *work)
 
 	chan->ops->close(chan);
 
+unlock:
 	l2cap_chan_unlock(chan);
-	l2cap_chan_put(chan);
-
 	mutex_unlock(&conn->lock);
+	l2cap_chan_put(chan);
 }
 
 struct l2cap_chan *l2cap_chan_create(void)
@@ -487,6 +490,9 @@ static void l2cap_chan_destroy(struct kref *kref)
 	list_del(&chan->global_l);
 	write_unlock(&chan_list_lock);
 
+	if (chan->conn)
+		l2cap_conn_put(chan->conn);
+
 	kfree(chan);
 }
 
@@ -590,7 +596,7 @@ void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
 
 	conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
 
-	chan->conn = conn;
+	chan->conn = l2cap_conn_get(conn);
 
 	switch (chan->chan_type) {
 	case L2CAP_CHAN_CONN_ORIENTED:
@@ -645,30 +651,26 @@ void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
 
 void l2cap_chan_del(struct l2cap_chan *chan, int err)
 {
-	struct l2cap_conn *conn = chan->conn;
-
 	__clear_chan_timer(chan);
 
-	BT_DBG("chan %p, conn %p, err %d, state %s", chan, conn, err,
+	BT_DBG("chan %p, err %d, state %s", chan, err,
 	       state_to_string(chan->state));
 
 	chan->ops->teardown(chan, err);
 
-	if (conn) {
+	if (!test_and_set_bit(FLAG_DEL, &chan->flags)) {
 		/* Delete from channel list */
 		list_del(&chan->list);
 
 		l2cap_chan_put(chan);
 
-		chan->conn = NULL;
-
 		/* Reference was only held for non-fixed channels or
 		 * fixed channels that explicitly requested it using the
 		 * FLAG_HOLD_HCI_CONN flag.
 		 */
 		if (chan->chan_type != L2CAP_CHAN_FIXED ||
 		    test_bit(FLAG_HOLD_HCI_CONN, &chan->flags))
-			hci_conn_drop(conn->hcon);
+			hci_conn_drop(chan->conn->hcon);
 	}
 
 	if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
@@ -1900,7 +1902,7 @@ static void l2cap_monitor_timeout(struct work_struct *work)
 
 	l2cap_chan_lock(chan);
 
-	if (!chan->conn) {
+	if (test_bit(FLAG_DEL, &chan->flags)) {
 		l2cap_chan_unlock(chan);
 		l2cap_chan_put(chan);
 		return;
@@ -1921,7 +1923,7 @@ static void l2cap_retrans_timeout(struct work_struct *work)
 
 	l2cap_chan_lock(chan);
 
-	if (!chan->conn) {
+	if (test_bit(FLAG_DEL, &chan->flags)) {
 		l2cap_chan_unlock(chan);
 		l2cap_chan_put(chan);
 		return;
@@ -2562,7 +2564,7 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
 	int err;
 	struct sk_buff_head seg_queue;
 
-	if (!chan->conn)
+	if (test_bit(FLAG_DEL, &chan->flags))
 		return -ENOTCONN;
 
 	/* Connectionless channel */
@@ -3157,12 +3159,16 @@ static void l2cap_ack_timeout(struct work_struct *work)
 
 	l2cap_chan_lock(chan);
 
+	if (test_bit(FLAG_DEL, &chan->flags))
+		goto unlock;
+
 	frames_to_ack = __seq_offset(chan, chan->buffer_seq,
 				     chan->last_acked_seq);
 
 	if (frames_to_ack)
 		l2cap_send_rr_or_rnr(chan, 0);
 
+unlock:
 	l2cap_chan_unlock(chan);
 	l2cap_chan_put(chan);
 }
-- 
2.54.0


^ permalink raw reply related

* RE: [BlueZ] shared/vcp: Fix duplicate VCS registration in bt_vcp_add_db
From: bluez.test.bot @ 2026-06-09 19:32 UTC (permalink / raw)
  To: linux-bluetooth, simon.mikuda
In-Reply-To: <20260609181351.3787741-1-simon.mikuda@streamunlimited.com>

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

---Test result---

Test Summary:
CheckPatch                    PASS      0.27 seconds
GitLint                       PASS      0.19 seconds
BuildEll                      PASS      20.02 seconds
BluezMake                     PASS      641.79 seconds
MakeCheck                     PASS      0.94 seconds
MakeDistcheck                 PASS      244.57 seconds
CheckValgrind                 PASS      220.97 seconds
CheckSmatch                   PASS      345.87 seconds
bluezmakeextell               PASS      181.21 seconds
IncrementalBuild              PASS      645.43 seconds
ScanBuild                     PASS      1023.19 seconds



https://github.com/bluez/bluez/pull/2205

---
Regards,
Linux Bluetooth


^ permalink raw reply

* RE: [BlueZ,1/2] media: Add Mute property to MediaTransport1
From: bluez.test.bot @ 2026-06-09 19:30 UTC (permalink / raw)
  To: linux-bluetooth, simon.mikuda
In-Reply-To: <20260609181108.3787224-1-simon.mikuda@streamunlimited.com>

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

---Test result---

Test Summary:
CheckPatch                    PASS      1.16 seconds
GitLint                       PASS      0.64 seconds
BuildEll                      PASS      20.17 seconds
BluezMake                     PASS      613.44 seconds
MakeCheck                     PASS      19.16 seconds
MakeDistcheck                 PASS      235.40 seconds
CheckValgrind                 PASS      276.40 seconds
CheckSmatch                   PASS      326.72 seconds
bluezmakeextell               PASS      165.83 seconds
IncrementalBuild              PASS      625.23 seconds
ScanBuild                     PASS      947.04 seconds



https://github.com/bluez/bluez/pull/2204

---
Regards,
Linux Bluetooth


^ permalink raw reply

* RE: [Bug,221629] New: Bluetooth l2cap: ident leak in l2cap_chan_le_send_credits() stalls BLE CoC
From: bluez.test.bot @ 2026-06-09 19:04 UTC (permalink / raw)
  To: linux-bluetooth, bugzilla-daemon
In-Reply-To: <bug-221629-62941@https.bugzilla.kernel.org/>

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

This is an automated email and please do not reply to this email.

Dear Submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
While preparing the CI tests, the patches you submitted couldn't be applied to the current HEAD of the repository.

----- Output -----

error: corrupt patch at line 21
hint: Use 'git am --show-current-patch' to see the failed patch

Please resolve the issue and submit the patches again.


---
Regards,
Linux Bluetooth


^ permalink raw reply

* [PATCH BlueZ v2 4/4] bearer: Check btd_opts.mode on btd_bearer_new
From: Luiz Augusto von Dentz @ 2026-06-09 18:53 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <20260609185313.155105-1-luiz.dentz@gmail.com>

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

Only create the bearer interface if the corresponding transport is
enabled. Return NULL if BREDR bearer is requested in LE-only mode or
LE bearer in BREDR-only mode, so the D-Bus interface is never
registered for unsupported bearers.
---
 src/bearer.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/src/bearer.c b/src/bearer.c
index 02267c711431..ac3a22030770 100644
--- a/src/bearer.c
+++ b/src/bearer.c
@@ -34,6 +34,7 @@
 
 #include "log.h"
 #include "error.h"
+#include "btd.h"
 #include "adapter.h"
 #include "device.h"
 #include "profile.h"
@@ -278,6 +279,19 @@ struct btd_bearer *btd_bearer_new(struct btd_device *device, uint8_t type)
 {
 	struct btd_bearer *bearer;
 
+	switch (btd_opts.mode) {
+	case BT_MODE_LE:
+		if (type == BDADDR_BREDR)
+			return NULL;
+		break;
+	case BT_MODE_BREDR:
+		if (type != BDADDR_BREDR)
+			return NULL;
+		break;
+	case BT_MODE_DUAL:
+		break;
+	}
+
 	bearer = new0(struct btd_bearer, 1);
 	bearer->device = device;
 	bearer->type = type;
-- 
2.54.0


^ permalink raw reply related

* [PATCH BlueZ v2 3/4] plugins: Check btd_profile_register return value
From: Luiz Augusto von Dentz @ 2026-06-09 18:53 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <20260609185313.155105-1-luiz.dentz@gmail.com>

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

Ensure all plugin init functions check the return value of
btd_profile_register. If registration fails (e.g. bearer not enabled),
the plugin init propagates the error instead of continuing with an
unregistered profile.
---
 profiles/audio/a2dp.c      | 14 ++++++++++++--
 profiles/audio/avrcp.c     | 13 +++++++++++--
 profiles/audio/hfp-hf.c    |  4 +---
 profiles/audio/micp.c      |  7 ++++++-
 profiles/input/manager.c   |  4 +---
 profiles/network/manager.c |  5 ++++-
 src/gatt-database.c        |  4 +++-
 7 files changed, 38 insertions(+), 13 deletions(-)

diff --git a/profiles/audio/a2dp.c b/profiles/audio/a2dp.c
index c7e0fc75c09e..a5e002784c02 100644
--- a/profiles/audio/a2dp.c
+++ b/profiles/audio/a2dp.c
@@ -3798,9 +3798,19 @@ static struct btd_adapter_driver media_driver = {
 
 static int a2dp_init(void)
 {
+	int err;
+
 	btd_register_adapter_driver(&media_driver);
-	btd_profile_register(&a2dp_source_profile);
-	btd_profile_register(&a2dp_sink_profile);
+
+	err = btd_profile_register(&a2dp_source_profile);
+	if (err)
+		return err;
+
+	err = btd_profile_register(&a2dp_sink_profile);
+	if (err) {
+		btd_profile_unregister(&a2dp_source_profile);
+		return err;
+	}
 
 	return 0;
 }
diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index b6823753fe68..f63acd47091a 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
@@ -4987,8 +4987,17 @@ static struct btd_profile avrcp_controller_profile = {
 
 static int avrcp_init(void)
 {
-	btd_profile_register(&avrcp_controller_profile);
-	btd_profile_register(&avrcp_target_profile);
+	int err;
+
+	err = btd_profile_register(&avrcp_controller_profile);
+	if (err)
+		return err;
+
+	err = btd_profile_register(&avrcp_target_profile);
+	if (err) {
+		btd_profile_unregister(&avrcp_controller_profile);
+		return err;
+	}
 
 	populate_default_features();
 
diff --git a/profiles/audio/hfp-hf.c b/profiles/audio/hfp-hf.c
index c91b16426898..8de2d7a62d68 100644
--- a/profiles/audio/hfp-hf.c
+++ b/profiles/audio/hfp-hf.c
@@ -507,9 +507,7 @@ static struct btd_profile hfp_hf_profile = {
 
 static int hfp_init(void)
 {
-	btd_profile_register(&hfp_hf_profile);
-
-	return 0;
+	return btd_profile_register(&hfp_hf_profile);
 }
 
 static void hfp_exit(void)
diff --git a/profiles/audio/micp.c b/profiles/audio/micp.c
index 475f32daf75c..3d39ef5e147f 100644
--- a/profiles/audio/micp.c
+++ b/profiles/audio/micp.c
@@ -318,12 +318,17 @@ static unsigned int micp_id;
 
 static int micp_init(void)
 {
+	int err;
+
 	if (!(g_dbus_get_flags() & G_DBUS_FLAG_ENABLE_EXPERIMENTAL)) {
 		DBG("D-Bus experimental not enabled");
 		return -ENOTSUP;
 	}
 
-	btd_profile_register(&micp_profile);
+	err = btd_profile_register(&micp_profile);
+	if (err)
+		return err;
+
 	micp_id = bt_micp_register(micp_attached, micp_detached, NULL);
 
 	return 0;
diff --git a/profiles/input/manager.c b/profiles/input/manager.c
index 0fcd6728c2fc..1fd82d82f500 100644
--- a/profiles/input/manager.c
+++ b/profiles/input/manager.c
@@ -118,12 +118,10 @@ static int input_init(void)
 
 	}
 
-	btd_profile_register(&input_profile);
-
 	if (config)
 		g_key_file_free(config);
 
-	return 0;
+	return btd_profile_register(&input_profile);
 }
 
 static void input_exit(void)
diff --git a/profiles/network/manager.c b/profiles/network/manager.c
index 693547d45fbc..a5f28a99ebfd 100644
--- a/profiles/network/manager.c
+++ b/profiles/network/manager.c
@@ -180,7 +180,10 @@ static int network_init(void)
 	if (server_init(conf_security) < 0)
 		return -1;
 
-	btd_profile_register(&panu_profile);
+	err = btd_profile_register(&panu_profile);
+	if (err)
+		return err;
+
 	btd_profile_register(&gn_profile);
 	btd_profile_register(&nap_profile);
 
diff --git a/src/gatt-database.c b/src/gatt-database.c
index 680a52952b16..30e25b6f41ca 100644
--- a/src/gatt-database.c
+++ b/src/gatt-database.c
@@ -3624,7 +3624,9 @@ static void add_profile(void *data, void *user_data)
 {
 	struct btd_adapter *adapter = user_data;
 
-	btd_profile_register(data);
+	if (btd_profile_register(data))
+		return;
+
 	adapter_add_profile(adapter, data);
 }
 
-- 
2.54.0


^ permalink raw reply related

* [PATCH BlueZ v2 2/4] profile: Check if bearer is enabled on registration
From: Luiz Augusto von Dentz @ 2026-06-09 18:53 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <20260609185313.155105-1-luiz.dentz@gmail.com>

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

btd_profile_register now verifies that the profile's bearer type is
compatible with btd_opts.mode before registering. If the required bearer
is not enabled (e.g. LE-only profile when mode is BR/EDR, or BR/EDR-only
profile when mode is LE), registration is rejected with -ENOTSUP.
---
 src/profile.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/src/profile.c b/src/profile.c
index 65df0f7a0969..97fffe9b4d5c 100644
--- a/src/profile.c
+++ b/src/profile.c
@@ -36,6 +36,7 @@
 #include "dbus-common.h"
 #include "sdp-client.h"
 #include "sdp-xml.h"
+#include "btd.h"
 #include "adapter.h"
 #include "device.h"
 #include "profile.h"
@@ -802,6 +803,14 @@ struct btd_profile *btd_profile_find_remote_uuid(const char *uuid)
 
 int btd_profile_register(struct btd_profile *profile)
 {
+	if ((profile->bearer == BTD_PROFILE_BEARER_LE &&
+				btd_opts.mode == BT_MODE_BREDR) ||
+			(profile->bearer == BTD_PROFILE_BEARER_BREDR &&
+				btd_opts.mode == BT_MODE_LE)) {
+		DBG("Bearer not enabled");
+		return -ENOTSUP;
+	}
+
 	if (profile->experimental && !(g_dbus_get_flags() &
 					G_DBUS_FLAG_ENABLE_EXPERIMENTAL)) {
 		DBG("D-Bus experimental not enabled");
-- 
2.54.0


^ permalink raw reply related

* [PATCH BlueZ v2 1/4] btio: Handle EOPNOTSUPP from accept() to prevent busy loop
From: Luiz Augusto von Dentz @ 2026-06-09 18:53 UTC (permalink / raw)
  To: linux-bluetooth

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

When accept() returns EOPNOTSUPP on an L2CAP SEQPACKET server socket
(e.g. AVCTP browsing channel, PSM 0x1b), the error is permanent and
retrying will never succeed. Previously, only EBADFD was treated as
fatal, causing server_cb to return TRUE for EOPNOTSUPP. Since the fd
remains readable, this creates an infinite busy loop that hangs
bluetoothd.

Treat EOPNOTSUPP the same as EBADFD by returning FALSE to remove the
GLib IO watch and stop the loop.
---
 btio/btio.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/btio/btio.c b/btio/btio.c
index 39d4411f790b..4c69d60350f8 100644
--- a/btio/btio.c
+++ b/btio/btio.c
@@ -274,7 +274,7 @@ static gboolean server_cb(GIOChannel *io, GIOCondition cond,
 
 	cli_sock = accept(srv_sock, NULL, NULL);
 	if (cli_sock < 0) {
-		if (errno == EBADFD)
+		if (errno == EBADFD || errno == EOPNOTSUPP)
 			return FALSE;
 		return TRUE;
 	}
-- 
2.54.0


^ permalink raw reply related

* [bluez/bluez] 45183e: shared/vcp: Fix duplicate VCS registration in bt_v...
From: Šimon Mikuda @ 2026-06-09 18:35 UTC (permalink / raw)
  To: linux-bluetooth

  Branch: refs/heads/1108772
  Home:   https://github.com/bluez/bluez
  Commit: 45183e49cd6de5e6ded958abce96a1889144d2fb
      https://github.com/bluez/bluez/commit/45183e49cd6de5e6ded958abce96a1889144d2fb
  Author: Simon Mikuda <simon.mikuda@streamunlimited.com>
  Date:   2026-06-09 (Tue, 09 Jun 2026)

  Changed paths:
    M src/shared/vcp.c

  Log Message:
  -----------
  shared/vcp: Fix duplicate VCS registration in bt_vcp_add_db

bt_vcp_add_db() called vcp_db_new() unconditionally, registering a
second VCS instance when bt_vcp_new() (e.g. a remote client session)
had already created a vdb for the same gatt_db. Guard the db as
bt_tmap_add_db()/bt_gmap_add_db() do, since VCS permits only one
instance per device.

Fixes PTS test VCS/SR/SGGIT/SER/BV-01-C.



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

^ permalink raw reply

* [bluez/bluez] 1fd31c: media: Add Mute property to MediaTransport1
From: Šimon Mikuda @ 2026-06-09 18:35 UTC (permalink / raw)
  To: linux-bluetooth

  Branch: refs/heads/1108770
  Home:   https://github.com/bluez/bluez
  Commit: 1fd31cca12a6e9a34e93ec3d1fc1814ffce2a0e4
      https://github.com/bluez/bluez/commit/1fd31cca12a6e9a34e93ec3d1fc1814ffce2a0e4
  Author: Simon Mikuda <simon.mikuda@streamunlimited.com>
  Date:   2026-06-09 (Tue, 09 Jun 2026)

  Changed paths:
    M doc/org.bluez.MediaTransport.rst
    M profiles/audio/transport.c
    M profiles/audio/vcp.c
    M profiles/audio/vcp.h
    M src/shared/vcp.c
    M src/shared/vcp.h

  Log Message:
  -----------
  media: Add Mute property to MediaTransport1

Boolean, optional, readwrite. Only present for LE Audio (BAP) unicast
transports backed by VCS. A2DP has no mute concept in AVRCP.

bt_vcp_set_mute() writes VCS Control Point Mute/Unmute for a client
session, or updates Volume State for a server session.
bt_vcp_get_mute() returns the cached value updated by Volume State
notifications.


  Commit: c01f9bd015cbe527b9f30a6338fb393da034e782
      https://github.com/bluez/bluez/commit/c01f9bd015cbe527b9f30a6338fb393da034e782
  Author: Simon Mikuda <simon.mikuda@streamunlimited.com>
  Date:   2026-06-09 (Tue, 09 Jun 2026)

  Changed paths:
    M client/player.c

  Log Message:
  -----------
  client/player: Add transport.mute command

Mirrors transport.volume. Accepts on/off, yes/no, 1/0.


Compare: https://github.com/bluez/bluez/compare/1fd31cca12a6%5E...c01f9bd015cb

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

^ permalink raw reply

* [bluez/bluez] 7ecb11: btio: Handle EOPNOTSUPP from accept() to prevent b...
From: Luiz Augusto von Dentz @ 2026-06-09 18:35 UTC (permalink / raw)
  To: linux-bluetooth

  Branch: refs/heads/1108736
  Home:   https://github.com/bluez/bluez
  Commit: 7ecb11301c829a12cc274ed2a0f7c89c63354a87
      https://github.com/bluez/bluez/commit/7ecb11301c829a12cc274ed2a0f7c89c63354a87
  Author: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
  Date:   2026-06-09 (Tue, 09 Jun 2026)

  Changed paths:
    M btio/btio.c

  Log Message:
  -----------
  btio: Handle EOPNOTSUPP from accept() to prevent busy loop

When accept() returns EOPNOTSUPP on an L2CAP SEQPACKET server socket
(e.g. AVCTP browsing channel, PSM 0x1b), the error is permanent and
retrying will never succeed. Previously, only EBADFD was treated as
fatal, causing server_cb to return TRUE for EOPNOTSUPP. Since the fd
remains readable, this creates an infinite busy loop that hangs
bluetoothd.

Treat EOPNOTSUPP the same as EBADFD by returning FALSE to remove the
GLib IO watch and stop the loop.


  Commit: c3e01f6ca296d8d8a22fd0fde7a2a59ec21ea0bc
      https://github.com/bluez/bluez/commit/c3e01f6ca296d8d8a22fd0fde7a2a59ec21ea0bc
  Author: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
  Date:   2026-06-09 (Tue, 09 Jun 2026)

  Changed paths:
    M src/profile.c

  Log Message:
  -----------
  profile: Check if bearer is enabled on registration

btd_profile_register now verifies that the profile's bearer type is
compatible with btd_opts.mode before registering. If the required bearer
is not enabled (e.g. LE-only profile when mode is BR/EDR, or BR/EDR-only
profile when mode is LE), registration is rejected with -ENOTSUP.


  Commit: a900f8944421290ab80fead5908f8eec0f164053
      https://github.com/bluez/bluez/commit/a900f8944421290ab80fead5908f8eec0f164053
  Author: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
  Date:   2026-06-09 (Tue, 09 Jun 2026)

  Changed paths:
    M profiles/audio/a2dp.c
    M profiles/audio/avrcp.c
    M profiles/audio/hfp-hf.c
    M profiles/audio/micp.c
    M profiles/input/manager.c
    M profiles/network/manager.c
    M src/gatt-database.c

  Log Message:
  -----------
  plugins: Check btd_profile_register return value

Ensure all plugin init functions check the return value of
btd_profile_register. If registration fails (e.g. bearer not enabled),
the plugin init propagates the error instead of continuing with an
unregistered profile.


  Commit: 2f53c2749db24ab84461c02ba7a2b52f6b2269d4
      https://github.com/bluez/bluez/commit/2f53c2749db24ab84461c02ba7a2b52f6b2269d4
  Author: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
  Date:   2026-06-09 (Tue, 09 Jun 2026)

  Changed paths:
    M src/bearer.c

  Log Message:
  -----------
  bearer: Check btd_opts.mode on btd_bearer_new

Only create the bearer interface if the corresponding transport is
enabled. Return NULL if BREDR bearer is requested in LE-only mode or
LE bearer in BREDR-only mode, so the D-Bus interface is never
registered for unsupported bearers.


Compare: https://github.com/bluez/bluez/compare/7ecb11301c82%5E...2f53c2749db2

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

^ permalink raw reply

* [Bug 221629] Bluetooth l2cap: ident leak in l2cap_chan_le_send_credits() stalls BLE CoC
From: bugzilla-daemon @ 2026-06-09 18:17 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <bug-221629-62941@https.bugzilla.kernel.org/>

https://bugzilla.kernel.org/show_bug.cgi?id=221629

--- Comment #2 from Florian Evers (florian-evers@gmx.de) ---
Hi Luiz,

I considered playing through that process of subscribing, checking out the
Kernel repo, in ordere to create a patch... and decided to write an issue in
your bug tracker.

Please... if you don't insist that I create a proper stand-alone patch... my
two cents: "just add it" :-)

Thank you very much. with kind regards,
Florian

-- 
You may reply to this email to add a comment.

You are receiving this mail because:
You are the assignee for the bug.

^ permalink raw reply

* [PATCH BlueZ] shared/vcp: Fix duplicate VCS registration in bt_vcp_add_db
From: Simon Mikuda @ 2026-06-09 18:13 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Simon Mikuda

bt_vcp_add_db() called vcp_db_new() unconditionally, registering a
second VCS instance when bt_vcp_new() (e.g. a remote client session)
had already created a vdb for the same gatt_db. Guard the db as
bt_tmap_add_db()/bt_gmap_add_db() do, since VCS permits only one
instance per device.

Fixes PTS test VCS/SR/SGGIT/SER/BV-01-C.
---
 src/shared/vcp.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/shared/vcp.c b/src/shared/vcp.c
index c7f74956e..f05684cfb 100644
--- a/src/shared/vcp.c
+++ b/src/shared/vcp.c
@@ -1939,6 +1939,9 @@ static struct bt_vcp_db *vcp_get_db(struct gatt_db *db)
 
 void bt_vcp_add_db(struct gatt_db *db)
 {
+	if (!db || queue_find(vcp_db, vcp_db_match, db))
+		return;
+
 	vcp_db_new(db);
 }
 
-- 
2.43.0


^ permalink raw reply related

* [PATCH BlueZ 1/2] media: Add Mute property to MediaTransport1
From: Simon Mikuda @ 2026-06-09 18:11 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Simon Mikuda

Boolean, optional, readwrite. Only present for LE Audio (BAP) unicast
transports backed by VCS. A2DP has no mute concept in AVRCP.

bt_vcp_set_mute() writes VCS Control Point Mute/Unmute for a client
session, or updates Volume State for a server session.
bt_vcp_get_mute() returns the cached value updated by Volume State
notifications.
---
 doc/org.bluez.MediaTransport.rst |  6 +++
 profiles/audio/transport.c       | 75 ++++++++++++++++++++++++++++
 profiles/audio/vcp.c             | 20 ++++++++
 profiles/audio/vcp.h             | 12 +++++
 src/shared/vcp.c                 | 86 ++++++++++++++++++++++++++++++++
 src/shared/vcp.h                 |  3 ++
 6 files changed, 202 insertions(+)

diff --git a/doc/org.bluez.MediaTransport.rst b/doc/org.bluez.MediaTransport.rst
index e50ec3f20..33d468325 100644
--- a/doc/org.bluez.MediaTransport.rst
+++ b/doc/org.bluez.MediaTransport.rst
@@ -160,6 +160,12 @@ Examples:
 
 :bluetoothctl: > transport.volume <transport> [value]
 
+boolean Mute [readwrite, optional]
+``````````````````````````````````
+
+Indicates mute state of the transport, only present for LE Audio (BAP)
+transports backed by VCS.
+
 object Endpoint [readonly, optional, experimental]
 ``````````````````````````````````````````````````
 
diff --git a/profiles/audio/transport.c b/profiles/audio/transport.c
index 4b9d26c5e..6b7dd9360 100644
--- a/profiles/audio/transport.c
+++ b/profiles/audio/transport.c
@@ -1191,6 +1191,64 @@ static void set_volume(const GDBusPropertyTable *property,
 	g_dbus_pending_property_success(id);
 }
 
+static int transport_bap_get_mute(struct media_transport *transport);
+static int transport_bap_set_mute(struct media_transport *transport,
+								bool mute);
+
+static gboolean mute_exists(const GDBusPropertyTable *property, void *data)
+{
+	struct media_transport *transport = data;
+
+	return transport_bap_get_mute(transport) >= 0;
+}
+
+static gboolean get_mute(const GDBusPropertyTable *property,
+					DBusMessageIter *iter, void *data)
+{
+	struct media_transport *transport = data;
+	dbus_bool_t mute;
+	int ret;
+
+	ret = transport_bap_get_mute(transport);
+	if (ret < 0)
+		return FALSE;
+
+	mute = ret;
+
+	dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &mute);
+
+	return TRUE;
+}
+
+static void set_mute(const GDBusPropertyTable *property,
+			DBusMessageIter *iter, GDBusPendingPropertySet id,
+			void *data)
+{
+	struct media_transport *transport = data;
+	dbus_bool_t mute;
+	int err;
+
+	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_BOOLEAN) {
+		g_dbus_pending_property_error(id,
+				ERROR_INTERFACE ".InvalidArguments",
+				"Expected BOOLEAN");
+		return;
+	}
+
+	dbus_message_iter_get_basic(iter, &mute);
+
+	err = transport_bap_set_mute(transport, mute);
+	if (err) {
+		error("Unable to set mute: %s (%d)", strerror(-err), err);
+		g_dbus_pending_property_error(id, ERROR_INTERFACE ".Failed",
+						"Internal error %s (%d)",
+						strerror(-err), err);
+		return;
+	}
+
+	g_dbus_pending_property_success(id);
+}
+
 static gboolean endpoint_exists(const GDBusPropertyTable *property, void *data)
 {
 	struct media_transport *transport = data;
@@ -1544,6 +1602,7 @@ static const GDBusPropertyTable transport_bap_uc_properties[] = {
 	{ "Metadata", "ay", get_metadata, set_metadata },
 	{ "Links", "ao", get_links, NULL, links_exists },
 	{ "Volume", "q", get_volume, set_volume, volume_exists },
+	{ "Mute", "b", get_mute, set_mute, mute_exists },
 	{ }
 };
 
@@ -2428,6 +2487,22 @@ static int transport_bap_set_volume(struct media_transport *transport,
 		return -ENOTSUP; /* TODO: MICP */
 }
 
+static int transport_bap_get_mute(struct media_transport *transport)
+{
+	if (transport_bap_is_playback(transport))
+		return bt_audio_vcp_get_mute(transport->device);
+	else
+		return -ENOTSUP; /* TODO: MICP */
+}
+
+static int transport_bap_set_mute(struct media_transport *transport, bool mute)
+{
+	if (transport_bap_is_playback(transport))
+		return bt_audio_vcp_set_mute(transport->device, mute);
+	else
+		return -ENOTSUP; /* TODO: MICP */
+}
+
 static void transport_bap_destroy(void *data)
 {
 	struct bap_transport *bap = data;
diff --git a/profiles/audio/vcp.c b/profiles/audio/vcp.c
index 00ee2b64b..7adac4dd5 100644
--- a/profiles/audio/vcp.c
+++ b/profiles/audio/vcp.c
@@ -185,6 +185,26 @@ int bt_audio_vcp_set_volume(struct btd_device *device, uint8_t volume)
 	return -ENODEV;
 }
 
+int bt_audio_vcp_get_mute(struct btd_device *device)
+{
+	struct vcp_data *data = queue_find(sessions, match_device, device);
+
+	if (data)
+		return bt_vcp_get_mute(data->vcp);
+
+	return -ENODEV;
+}
+
+int bt_audio_vcp_set_mute(struct btd_device *device, bool mute)
+{
+	struct vcp_data *data = queue_find(sessions, match_device, device);
+
+	if (data)
+		return bt_vcp_set_mute(data->vcp, mute) ? 0 : -EIO;
+
+	return -ENODEV;
+}
+
 static void vcp_remote_client_detached(struct bt_vcp *vcp, void *user_data)
 {
 	struct vcp_data *data;
diff --git a/profiles/audio/vcp.h b/profiles/audio/vcp.h
index b538cebf0..35ffc09f8 100644
--- a/profiles/audio/vcp.h
+++ b/profiles/audio/vcp.h
@@ -12,6 +12,8 @@
 
 int bt_audio_vcp_get_volume(struct btd_device *device);
 int bt_audio_vcp_set_volume(struct btd_device *device, uint8_t volume);
+int bt_audio_vcp_get_mute(struct btd_device *device);
+int bt_audio_vcp_set_mute(struct btd_device *device, bool mute);
 
 #else
 
@@ -26,4 +28,14 @@ static inline int bt_audio_vcp_set_volume(struct btd_device *device,
 	return -ENODEV;
 }
 
+static inline int bt_audio_vcp_get_mute(struct btd_device *device)
+{
+	return -ENODEV;
+}
+
+static inline int bt_audio_vcp_set_mute(struct btd_device *device, bool mute)
+{
+	return -ENODEV;
+}
+
 #endif
diff --git a/src/shared/vcp.c b/src/shared/vcp.c
index c7f74956e..49eff8d02 100644
--- a/src/shared/vcp.c
+++ b/src/shared/vcp.c
@@ -216,6 +216,7 @@ struct bt_vcp {
 
 	uint8_t volume;
 	uint8_t volume_counter;
+	uint8_t mute;
 
 	struct bt_vcp_client_op pending_op;
 
@@ -861,6 +862,9 @@ static uint8_t vcs_mute(struct bt_vcs *vcs, struct bt_vcp *vcp,
 	vstate->mute = 0x01;
 	vstate->counter = -~vstate->counter; /*Increment Change Counter*/
 
+	gatt_db_attribute_notify(vdb->vcs->vs, (void *)vstate,
+				 sizeof(struct vol_state),
+				 bt_vcp_get_att(vcp));
 	return 0;
 }
 
@@ -2076,6 +2080,7 @@ static void vcp_vstate_notify(struct bt_vcp *vcp, uint16_t value_handle,
 
 	vcp->volume = vstate->vol_set;
 	vcp->volume_counter = vstate->counter;
+	vcp->mute = vstate->mute;
 
 	if (vcp->volume_changed)
 		vcp->volume_changed(vcp, vcp->volume);
@@ -2207,6 +2212,86 @@ uint8_t bt_vcp_get_volume(struct bt_vcp *vcp)
 	return vcp->volume;
 }
 
+static void vcp_mute_cp_sent(bool success, uint8_t err, void *user_data)
+{
+	struct bt_vcp *vcp = user_data;
+
+	if (!success)
+		DBG(vcp, "setting mute failed: error 0x%x", err);
+}
+
+static bool vcp_set_mute_client(struct bt_vcp *vcp, uint8_t mute)
+{
+	struct bt_vcs_param req;
+	uint16_t value_handle;
+	struct bt_vcs *vcs = vcp_get_vcs(vcp);
+
+	if (!vcs || !vcs->vol_cp) {
+		DBG(vcp, "error: vol_cp characteristic not available");
+		return false;
+	}
+
+	if (!gatt_db_attribute_get_char_data(vcs->vol_cp, NULL, &value_handle,
+							NULL, NULL, NULL)) {
+		DBG(vcp, "error: vol_cp characteristic not available");
+		return false;
+	}
+
+	if (vcp->mute == mute)
+		return true;
+
+	req.op = mute ? BT_VCS_MUTE : BT_VCS_UNMUTE;
+	req.change_counter = vcp->volume_counter;
+
+	if (!bt_gatt_client_write_value(vcp->client, value_handle, (void *)&req,
+					sizeof(req), vcp_mute_cp_sent, vcp,
+					NULL)) {
+		DBG(vcp, "error writing mute");
+		return false;
+	}
+
+	return true;
+}
+
+static bool vcp_set_mute_server(struct bt_vcp *vcp, uint8_t mute)
+{
+	struct bt_vcp_db *vdb = vcp_get_vdb(vcp);
+	struct vol_state *vstate;
+
+	vcp->mute = mute;
+
+	if (!vdb) {
+		DBG(vcp, "error: VDB not available");
+		return false;
+	}
+
+	vstate = vdb_get_vstate(vdb);
+	if (!vstate) {
+		DBG(vcp, "error: VSTATE not available");
+		return false;
+	}
+
+	vstate->mute = mute;
+	vstate->counter = -~vstate->counter; /*Increment Change Counter*/
+
+	gatt_db_attribute_notify(vdb->vcs->vs, (void *) vstate,
+			sizeof(struct vol_state), bt_vcp_get_att(vcp));
+	return true;
+}
+
+bool bt_vcp_set_mute(struct bt_vcp *vcp, uint8_t mute)
+{
+	if (vcp->client)
+		return vcp_set_mute_client(vcp, mute);
+	else
+		return vcp_set_mute_server(vcp, mute);
+}
+
+uint8_t bt_vcp_get_mute(struct bt_vcp *vcp)
+{
+	return vcp->mute;
+}
+
 static void vcp_voffset_state_notify(struct bt_vcp *vcp, uint16_t value_handle,
 				const uint8_t *value, uint16_t length,
 				void *user_data)
@@ -2320,6 +2405,7 @@ static void read_vol_state(struct bt_vcp *vcp, bool success, uint8_t att_ecode,
 
 	vcp->volume = vs->vol_set;
 	vcp->volume_counter = vs->counter;
+	vcp->mute = vs->mute;
 }
 
 static void read_vol_offset_state(struct bt_vcp *vcp, bool success,
diff --git a/src/shared/vcp.h b/src/shared/vcp.h
index e031beafd..807d2bdbe 100644
--- a/src/shared/vcp.h
+++ b/src/shared/vcp.h
@@ -42,6 +42,9 @@ void bt_vcp_detach(struct bt_vcp *vcp);
 uint8_t bt_vcp_get_volume(struct bt_vcp *vcp);
 bool bt_vcp_set_volume(struct bt_vcp *vcp, uint8_t volume);
 
+uint8_t bt_vcp_get_mute(struct bt_vcp *vcp);
+bool bt_vcp_set_mute(struct bt_vcp *vcp, uint8_t mute);
+
 bool bt_vcp_set_debug(struct bt_vcp *vcp, bt_vcp_debug_func_t cb,
 			void *user_data, bt_vcp_destroy_func_t destroy);
 
-- 
2.43.0


^ permalink raw reply related

* [PATCH BlueZ 2/2] client/player: Add transport.mute command
From: Simon Mikuda @ 2026-06-09 18:11 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Simon Mikuda
In-Reply-To: <20260609181108.3787224-1-simon.mikuda@streamunlimited.com>

Mirrors transport.volume. Accepts on/off, yes/no, 1/0.
---
 client/player.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/client/player.c b/client/player.c
index c5e4beef0..2c3008221 100644
--- a/client/player.c
+++ b/client/player.c
@@ -6070,6 +6070,54 @@ static void cmd_volume_transport(int argc, char *argv[])
 	}
 }
 
+static void mute_callback(const DBusError *error, void *user_data)
+{
+	if (dbus_error_is_set(error)) {
+		bt_shell_printf("Failed to set Mute: %s\n", error->name);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
+	}
+
+	bt_shell_printf("Changing Mute succeeded\n");
+
+	return bt_shell_noninteractive_quit(EXIT_SUCCESS);
+}
+
+static void cmd_mute_transport(int argc, char *argv[])
+{
+	GDBusProxy *proxy;
+	dbus_bool_t mute;
+
+	proxy = g_dbus_proxy_lookup(transports, NULL, argv[1],
+					BLUEZ_MEDIA_TRANSPORT_INTERFACE);
+	if (!proxy) {
+		bt_shell_printf("Transport %s not found\n", argv[1]);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
+	}
+
+	if (argc == 2) {
+		print_property(proxy, "Mute");
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
+	}
+
+	if (!strcasecmp(argv[2], "on") || !strcasecmp(argv[2], "yes") ||
+				!strcmp(argv[2], "1"))
+		mute = TRUE;
+	else if (!strcasecmp(argv[2], "off") || !strcasecmp(argv[2], "no") ||
+				!strcmp(argv[2], "0"))
+		mute = FALSE;
+	else {
+		bt_shell_printf("Invalid argument: %s\n", argv[2]);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
+	}
+
+	if (!g_dbus_proxy_set_property_basic(proxy, "Mute", DBUS_TYPE_BOOLEAN,
+						&mute, mute_callback,
+						NULL, NULL)) {
+		bt_shell_printf("Failed to set mute\n");
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
+	}
+}
+
 static void set_metadata_cb(const DBusError *error, void *user_data)
 {
 	if (dbus_error_is_set(error)) {
@@ -6188,6 +6236,9 @@ static const struct bt_shell_menu transport_menu = {
 	{ "volume",      "<transport> [value]",	cmd_volume_transport,
 						"Get/Set transport volume",
 						transport_generator },
+	{ "mute",        "<transport> [on/off]", cmd_mute_transport,
+						"Get/Set transport mute",
+						transport_generator },
 	{ "select",      "<transport> [transport1...]", cmd_select_transport,
 						"Select Transport",
 						transport_generator },
-- 
2.43.0


^ permalink raw reply related

* [Bug 221629] Bluetooth l2cap: ident leak in l2cap_chan_le_send_credits() stalls BLE CoC
From: bugzilla-daemon @ 2026-06-09 18:09 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <bug-221629-62941@https.bugzilla.kernel.org/>

https://bugzilla.kernel.org/show_bug.cgi?id=221629

Luiz Von Dentz (luiz.dentz@gmail.com) changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |luiz.dentz@gmail.com

--- Comment #1 from Luiz Von Dentz (luiz.dentz@gmail.com) ---
Looks good, any chance to sent a proper patch to linux-bluetooth mailing list?
Or I should fix it myself?

-- 
You may reply to this email to add a comment.

You are receiving this mail because:
You are the assignee for the bug.

^ permalink raw reply

* [Bug 221629] Bluetooth l2cap: ident leak in l2cap_chan_le_send_credits() stalls BLE CoC
From: bugzilla-daemon @ 2026-06-09 17:59 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <bug-221629-62941@https.bugzilla.kernel.org/>

https://bugzilla.kernel.org/show_bug.cgi?id=221629

Florian Evers (florian-evers@gmx.de) changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
     Kernel Version|                            |7.0.10

-- 
You may reply to this email to add a comment.

You are receiving this mail because:
You are the assignee for the bug.

^ permalink raw reply

* [Bug 221629] Bluetooth l2cap: ident leak in l2cap_chan_le_send_credits() stalls BLE CoC
From: bugzilla-daemon @ 2026-06-09 17:58 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <bug-221629-62941@https.bugzilla.kernel.org/>

https://bugzilla.kernel.org/show_bug.cgi?id=221629

Florian Evers (florian-evers@gmx.de) changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           See Also|                            |https://bugzilla.kernel.org
                   |                            |/show_bug.cgi?id=221592

-- 
You may reply to this email to add a comment.

You are receiving this mail because:
You are the assignee for the bug.

^ permalink raw reply

* [Bug 221629] New: Bluetooth l2cap: ident leak in l2cap_chan_le_send_credits() stalls BLE CoC
From: bugzilla-daemon @ 2026-06-09 17:58 UTC (permalink / raw)
  To: linux-bluetooth

https://bugzilla.kernel.org/show_bug.cgi?id=221629

            Bug ID: 221629
           Summary: Bluetooth l2cap: ident leak in
                    l2cap_chan_le_send_credits() stalls BLE CoC
           Product: Drivers
           Version: 2.5
          Hardware: All
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P3
         Component: Bluetooth
          Assignee: linux-bluetooth@vger.kernel.org
          Reporter: florian-evers@gmx.de
        Regression: No

Hi,

I have found a resource leak in l2cap_chan_le_send_credits() that causes
permanent stalls of BLE L2CAP Connection-Oriented Channels under sustained
traffic. Here, I couple two Linux computers using a long-lasting L2CAP CoC
channel and transmit data in both directions, but the stream freezes after a
few seconds with dmesg warnings.


Root Cause:
-----------
l2cap_chan_le_send_credits() allocates an ident via l2cap_get_ident(conn)
(which does ida_alloc_range on conn->tx_ida), then sends L2CAP_LE_CREDITS.

However, L2CAP_LE_CREDITS is a unidirectional signaling command; the remote
never sends a response.
The normal ident-free path (l2cap_put_ident via l2cap_le_sig_cmd) is only
triggered when a response opcode arrives.
Since no response exists for this opcode, the ident is never freed.

The kernel itself documents this as unexpected at line 950-954:

    /* If all idents are in use, log an error, this is
     * extremely unlikely to happen and would indicate a bug
     * in the code that idents are not being freed properly.
     */

Failure Chain:
--------------
1. Each received SDU triggers credit replenishment at
l2cap_chan_le_send_credits()
2. Each call leaks one ident slot from the 255-slot tx_ida pool
3. After 255 credits sent, ida_alloc_range returns -ENOSPC
4. l2cap_get_ident() returns 0, logs "Unable to allocate ident: -28"
5. No further credit updates can be sent
6. Remote's TX credit window drains to zero resulting in a permanent write
stall


My assumption: why it was never found yet
-----------
- This issue only affects the RECEIVING side (which must send credit updates).
  The sending side never calls l2cap_chan_le_send_credits().
- The pool has 255 slots, so it takes 255 SDUs to exhaust, and short test
sessions may never trigger it.
- Classic Bluetooth L2CAP uses a separate ident range (1-128) with
request/response pairs, so it is not affected.


How to Reproduce:
-----------------
Any sustained unidirectional BLE L2CAP CoC data stream where Linux is the
receiver is affected.
Transfer >255 SDUs (e.g., a 200 KB file at MPS=512 triggers ~400 credit
updates). After exhaustion, dmesg shows:

    Bluetooth: Unable to allocate ident: -28

and all signaling on that connection stops permanently. The stream freezes.

I have that issue on a self-compiled kernel 7.0.10-gentoo.


Proposed  Fix:
--------------
The ident can be freed immediately after l2cap_send_cmd(), since no response
will ever reference it:

--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -6652,6 +6652,18 @@
 chan->ident = l2cap_get_ident(conn);

 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CREDITS, sizeof(pkt), &pkt);
+
+/* L2CAP_LE_CREDITS is a one-way indication: the remote never sends a
+ * response, so l2cap_put_ident() is never called for this ident.
+ * Free it immediately to prevent exhausting the 255-slot tx_ida pool
+ * under sustained CoC traffic (e.g. hours-long bulk data streams).
+ * Pool exhaustion causes credit updates to stop being sent, which
+ * drains the remote TX credit window to zero and permanently stalls
+ * all data transfer in both directions.
+ */
+if (chan->ident)
+ida_free(&conn->tx_ida, chan->ident);
+chan->ident = 0;
 }

This fix has been running here for 1-2 weeks without any issues. Data is
flowing now without any dmesg warnings or stalls.

Kind regards,
Florian Evers

-- 
You may reply to this email to add a comment.

You are receiving this mail because:
You are the assignee for the bug.

^ permalink raw reply

* RE: "cleanup" variable attribute follow-up
From: bluez.test.bot @ 2026-06-09 17:30 UTC (permalink / raw)
  To: linux-bluetooth, hadess
In-Reply-To: <20260609135837.476561-2-hadess@hadess.net>

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

---Test result---

Test Summary:
CheckPatch                    FAIL      2.51 seconds
GitLint                       PASS      1.73 seconds
BuildEll                      PASS      16.19 seconds
BluezMake                     PASS      498.81 seconds
MakeCheck                     PASS      18.30 seconds
MakeDistcheck                 PASS      189.35 seconds
CheckValgrind                 PASS      217.95 seconds
CheckSmatch                   WARNING   253.71 seconds
bluezmakeextell               PASS      131.42 seconds
IncrementalBuild              PASS      985.31 seconds
ScanBuild                     PASS      733.50 seconds

Details
##############################
Test: CheckPatch - FAIL
Desc: Run checkpatch.pl script
Output:
[BlueZ,1/6] shared/util: Fix warnings when cleaning up NULL pointers
WARNING:LONG_LINE: line length of 94 exceeds 80 columns
#74: FILE: src/shared/util.h:130:
+	static inline void cleanup_##type (type **_ptr) { if (*_ptr != NULL) (func) (*_ptr); }

WARNING:SPACING: space prohibited between function name and open parenthesis '('
#74: FILE: src/shared/util.h:130:
+	static inline void cleanup_##type (type **_ptr) { if (*_ptr != NULL) (func) (*_ptr); }

ERROR:SPACING: need consistent spacing around '*' (ctx:WxO)
#74: FILE: src/shared/util.h:130:
+	static inline void cleanup_##type (type **_ptr) { if (*_ptr != NULL) (func) (*_ptr); }
 	                                        ^

ERROR:TRAILING_STATEMENTS: trailing statements should be on next line
#74: FILE: src/shared/util.h:130:
+	static inline void cleanup_##type (type **_ptr) { if (*_ptr != NULL) (func) (*_ptr); }

/github/workspace/src/patch/14619750.patch total: 2 errors, 2 warnings, 8 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/14619750.patch has style problems, please review.

NOTE: Ignored message types: COMMIT_MESSAGE COMPLEX_MACRO CONST_STRUCT FILE_PATH_CHANGES MISSING_SIGN_OFF PREFER_PACKED SPDX_LICENSE_TAG SPLIT_STRING SSCANF_TO_KSTRTO

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


[BlueZ,4/6] main: Use _cleanup_() to simplify configuration parsing
ERROR:SPACING: need consistent spacing around '*' (ctx:WxV)
#90: FILE: src/main.c:265:
+	_cleanup_type_(GError) GError *err = NULL;
 	                              ^

ERROR:SPACING: need consistent spacing around '*' (ctx:WxV)
#114: FILE: src/main.c:447:
+	_cleanup_type_(GError) GError *err = NULL;
 	                              ^

ERROR:SPACING: need consistent spacing around '*' (ctx:WxV)
#210: FILE: src/main.c:895:
+	_cleanup_type_(GError) GError *err = NULL;
 	                              ^

ERROR:SPACING: need consistent spacing around '*' (ctx:WxV)
#415: FILE: src/main.c:1214:
+	_cleanup_type_(GError) GError *err = NULL;
 	                              ^

ERROR:SPACING: need consistent spacing around '*' (ctx:WxV)
#507: FILE: src/main.c:1577:
+	_cleanup_type_(GError) GError *err = NULL;
 	                              ^

/github/workspace/src/patch/14619699.patch total: 5 errors, 0 warnings, 420 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/14619699.patch has style problems, please review.

NOTE: Ignored message types: COMMIT_MESSAGE COMPLEX_MACRO CONST_STRUCT FILE_PATH_CHANGES MISSING_SIGN_OFF PREFER_PACKED SPDX_LICENSE_TAG SPLIT_STRING SSCANF_TO_KSTRTO

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


##############################
Test: CheckSmatch - WARNING
Desc: Run smatch tool with source
Output:
src/main.c: note: in included file (through src/device.h):


https://github.com/bluez/bluez/pull/2201

---
Regards,
Linux Bluetooth


^ permalink raw reply

* RE: Initial Channel Sounding Support for
From: bluez.test.bot @ 2026-06-09 17:18 UTC (permalink / raw)
  To: linux-bluetooth, naga.akella
In-Reply-To: <20260609154502.3430147-2-naga.akella@oss.qualcomm.com>

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

---Test result---

Test Summary:
CheckPatch                    PASS      1.30 seconds
GitLint                       PASS      0.61 seconds
BuildEll                      PASS      20.02 seconds
BluezMake                     PASS      654.18 seconds
CheckSmatch                   PASS      348.80 seconds
bluezmakeextell               PASS      181.08 seconds
IncrementalBuild              FAIL      653.81 seconds
ScanBuild                     FAIL      491.92 seconds

Details
##############################
Test: IncrementalBuild - FAIL
Desc: Incremental build with the patches in the series
Output:

tools/mgmt-tester.c: In function ‘main’:
tools/mgmt-tester.c:12990:5: note: variable tracking size limit exceeded with ‘-fvar-tracking-assignments’, retrying without
12990 | int main(int argc, char *argv[])
      |     ^~~~
unit/test-avdtp.c: In function ‘main’:
unit/test-avdtp.c:766:5: note: variable tracking size limit exceeded with ‘-fvar-tracking-assignments’, retrying without
  766 | int main(int argc, char *argv[])
      |     ^~~~
unit/test-avrcp.c: In function ‘main’:
unit/test-avrcp.c:989:5: note: variable tracking size limit exceeded with ‘-fvar-tracking-assignments’, retrying without
  989 | int main(int argc, char *argv[])
      |     ^~~~
profiles/ranging/rap.c: In function ‘rap_accept’:
profiles/ranging/rap.c:421:4: error: too few arguments to function ‘bt_rap_set_conn_handle’
  421 |    bt_rap_set_conn_handle(data->hci_sm,
      |    ^~~~~~~~~~~~~~~~~~~~~~
In file included from profiles/ranging/rap.c:35:
./src/shared/rap.h:215:6: note: declared here
  215 | bool bt_rap_set_conn_handle(void *hci_sm, struct bt_rap *rap, uint16_t handle,
      |      ^~~~~~~~~~~~~~~~~~~~~~
make[1]: *** [Makefile:8993: profiles/ranging/bluetoothd-rap.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:4172: all] Error 2
[BlueZ,v2,1/2] shared: rap: Check role before sending CS Sec Enable cmd

tools/mgmt-tester.c: In function ‘main’:
tools/mgmt-tester.c:12990:5: note: variable tracking size limit exceeded with ‘-fvar-tracking-assignments’, retrying without
12990 | int main(int argc, char *argv[])
      |     ^~~~
unit/test-avdtp.c: In function ‘main’:
unit/test-avdtp.c:766:5: note: variable tracking size limit exceeded with ‘-fvar-tracking-assignments’, retrying without
  766 | int main(int argc, char *argv[])
      |     ^~~~
unit/test-avrcp.c: In function ‘main’:
unit/test-avrcp.c:989:5: note: variable tracking size limit exceeded with ‘-fvar-tracking-assignments’, retrying without
  989 | int main(int argc, char *argv[])
      |     ^~~~
profiles/ranging/rap.c: In function ‘rap_accept’:
profiles/ranging/rap.c:421:4: error: too few arguments to function ‘bt_rap_set_conn_handle’
  421 |    bt_rap_set_conn_handle(data->hci_sm,
      |    ^~~~~~~~~~~~~~~~~~~~~~
In file included from profiles/ranging/rap.c:35:
./src/shared/rap.h:215:6: note: declared here
  215 | bool bt_rap_set_conn_handle(void *hci_sm, struct bt_rap *rap, uint16_t handle,
      |      ^~~~~~~~~~~~~~~~~~~~~~
make[1]: *** [Makefile:8993: profiles/ranging/bluetoothd-rap.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:4172: all] Error 2
##############################
Test: ScanBuild - FAIL
Desc: Run Scan Build
Output:

src/shared/gatt-client.c:447:21: warning: Use of memory after it is freed
        gatt_db_unregister(op->client->db, op->db_id);
                           ^~~~~~~~~~
src/shared/gatt-client.c:692:2: warning: Use of memory after it is freed
        discovery_op_complete(op, false, att_ecode);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:992:2: warning: Use of memory after it is freed
        discovery_op_complete(op, success, att_ecode);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1098:2: warning: Use of memory after it is freed
        discovery_op_complete(op, success, att_ecode);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1292:2: warning: Use of memory after it is freed
        discovery_op_complete(op, success, att_ecode);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1357:2: warning: Use of memory after it is freed
        discovery_op_complete(op, success, att_ecode);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1632:6: warning: Use of memory after it is freed
        if (read_db_hash(op)) {
            ^~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1637:2: warning: Use of memory after it is freed
        discover_all(op);
        ^~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1693:56: warning: Use of memory after it is freed
        notify_data->chrc->ccc_write_id = notify_data->att_id = att_id;
                                          ~~~~~~~~~~~~~~~~~~~ ^
src/shared/gatt-client.c:2146:6: warning: Use of memory after it is freed
        if (read_db_hash(op)) {
            ^~~~~~~~~~~~~~~~
src/shared/gatt-client.c:2154:8: warning: Use of memory after it is freed
                                                        discovery_op_ref(op),
                                                        ^~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:3332:2: warning: Use of memory after it is freed
        complete_write_long_op(req, success, 0, false);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:3354:2: warning: Use of memory after it is freed
        request_unref(req);
        ^~~~~~~~~~~~~~~~~~
13 warnings generated.
src/shared/bap.c:1534:8: warning: Use of memory after it is freed
        bap = bt_bap_ref_safe(bap);
              ^~~~~~~~~~~~~~~~~~~~
src/shared/bap.c:2345:20: warning: Use of memory after it is freed
        return queue_find(stream->bap->streams, NULL, stream);
                          ^~~~~~~~~~~~~~~~~~~~
2 warnings generated.
src/shared/gatt-client.c:447:21: warning: Use of memory after it is freed
        gatt_db_unregister(op->client->db, op->db_id);
                           ^~~~~~~~~~
src/shared/gatt-client.c:692:2: warning: Use of memory after it is freed
        discovery_op_complete(op, false, att_ecode);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:992:2: warning: Use of memory after it is freed
        discovery_op_complete(op, success, att_ecode);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1098:2: warning: Use of memory after it is freed
        discovery_op_complete(op, success, att_ecode);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1292:2: warning: Use of memory after it is freed
        discovery_op_complete(op, success, att_ecode);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1357:2: warning: Use of memory after it is freed
        discovery_op_complete(op, success, att_ecode);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1632:6: warning: Use of memory after it is freed
        if (read_db_hash(op)) {
            ^~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1637:2: warning: Use of memory after it is freed
        discover_all(op);
        ^~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1693:56: warning: Use of memory after it is freed
        notify_data->chrc->ccc_write_id = notify_data->att_id = att_id;
                                          ~~~~~~~~~~~~~~~~~~~ ^
src/shared/gatt-client.c:2146:6: warning: Use of memory after it is freed
        if (read_db_hash(op)) {
            ^~~~~~~~~~~~~~~~
src/shared/gatt-client.c:2154:8: warning: Use of memory after it is freed
                                                        discovery_op_ref(op),
                                                        ^~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:3332:2: warning: Use of memory after it is freed
        complete_write_long_op(req, success, 0, false);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:3354:2: warning: Use of memory after it is freed
        request_unref(req);
        ^~~~~~~~~~~~~~~~~~
13 warnings generated.
tools/hciattach.c:817:7: warning: Although the value stored to 'n' is used in the enclosing expression, the value is never actually read from 'n'
        if ((n = read_hci_event(fd, resp, 10)) < 0) {
             ^   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/hciattach.c:865:7: warning: Although the value stored to 'n' is used in the enclosing expression, the value is never actually read from 'n'
        if ((n = read_hci_event(fd, resp, 4)) < 0) {
             ^   ~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/hciattach.c:887:8: warning: Although the value stored to 'n' is used in the enclosing expression, the value is never actually read from 'n'
                if ((n = read_hci_event(fd, resp, 10)) < 0) {
                     ^   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/hciattach.c:909:7: warning: Although the value stored to 'n' is used in the enclosing expression, the value is never actually read from 'n'
        if ((n = read_hci_event(fd, resp, 4)) < 0) {
             ^   ~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/hciattach.c:930:7: warning: Although the value stored to 'n' is used in the enclosing expression, the value is never actually read from 'n'
        if ((n = read_hci_event(fd, resp, 4)) < 0) {
             ^   ~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/hciattach.c:974:7: warning: Although the value stored to 'n' is used in the enclosing expression, the value is never actually read from 'n'
        if ((n = read_hci_event(fd, resp, 6)) < 0) {
             ^   ~~~~~~~~~~~~~~~~~~~~~~~~~~~
6 warnings generated.
src/shared/bap.c:1534:8: warning: Use of memory after it is freed
        bap = bt_bap_ref_safe(bap);
              ^~~~~~~~~~~~~~~~~~~~
src/shared/bap.c:2345:20: warning: Use of memory after it is freed
        return queue_find(stream->bap->streams, NULL, stream);
                          ^~~~~~~~~~~~~~~~~~~~
2 warnings generated.
src/oui.c:50:2: warning: Value stored to 'hwdb' is never read
        hwdb = udev_hwdb_unref(hwdb);
        ^      ~~~~~~~~~~~~~~~~~~~~~
src/oui.c:53:2: warning: Value stored to 'udev' is never read
        udev = udev_unref(udev);
        ^      ~~~~~~~~~~~~~~~~
2 warnings generated.
tools/rfcomm.c:234:3: warning: Value stored to 'i' is never read
                i = execvp(cmdargv[0], cmdargv);
                ^   ~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/rfcomm.c:234:7: warning: Null pointer passed to 1st parameter expecting 'nonnull'
                i = execvp(cmdargv[0], cmdargv);
                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/rfcomm.c:354:8: warning: Although the value stored to 'fd' is used in the enclosing expression, the value is never actually read from 'fd'
                if ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) {
                     ^    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/rfcomm.c:497:14: warning: Assigned value is garbage or undefined
        req.channel = raddr.rc_channel;
                    ^ ~~~~~~~~~~~~~~~~
tools/rfcomm.c:515:8: warning: Although the value stored to 'fd' is used in the enclosing expression, the value is never actually read from 'fd'
                if ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) {
                     ^    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 warnings generated.
tools/ciptool.c:351:7: warning: 5th function call argument is an uninitialized value
        sk = do_connect(ctl, dev_id, &src, &dst, psm, (1 << CMTP_LOOPBACK));
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
src/sdp-xml.c:126:10: warning: Assigned value is garbage or undefined
                buf[1] = data[i + 1];
                       ^ ~~~~~~~~~~~
src/sdp-xml.c:306:11: warning: Assigned value is garbage or undefined
                        buf[1] = data[i + 1];
                               ^ ~~~~~~~~~~~
src/sdp-xml.c:344:11: warning: Assigned value is garbage or undefined
                        buf[1] = data[i + 1];
                               ^ ~~~~~~~~~~~
3 warnings generated.
tools/sdptool.c:941:26: warning: Result of 'malloc' is converted to a pointer of type 'uint32_t', which is incompatible with sizeof operand type 'int'
                        uint32_t *value_int = malloc(sizeof(int));
                        ~~~~~~~~~~            ^~~~~~ ~~~~~~~~~~~
tools/sdptool.c:980:4: warning: 1st function call argument is an uninitialized value
                        free(allocArray[i]);
                        ^~~~~~~~~~~~~~~~~~~
tools/sdptool.c:3777:2: warning: Potential leak of memory pointed to by 'si.name'
        return add_service(0, &si);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~
tools/sdptool.c:4112:4: warning: Potential leak of memory pointed to by 'context.svc'
                        return -1;
                        ^~~~~~~~~
4 warnings generated.
tools/avtest.c:243:5: warning: Value stored to 'len' is never read
                                len = write(sk, buf, 3);
                                ^     ~~~~~~~~~~~~~~~~~
tools/avtest.c:253:5: warning: Value stored to 'len' is never read
                                len = write(sk, buf, 4);
                                ^     ~~~~~~~~~~~~~~~~~
tools/avtest.c:262:5: warning: Value stored to 'len' is never read
                                len = write(sk, buf, 3);
                                ^     ~~~~~~~~~~~~~~~~~
tools/avtest.c:276:5: warning: Value stored to 'len' is never read
                                len = write(sk, buf,
                                ^     ~~~~~~~~~~~~~~
tools/avtest.c:283:5: warning: Value stored to 'len' is never read
                                len = write(sk, buf,
                                ^     ~~~~~~~~~~~~~~
tools/avtest.c:290:5: warning: Value stored to 'len' is never read
                                len = write(sk, buf,
                                ^     ~~~~~~~~~~~~~~
tools/avtest.c:297:5: warning: Value stored to 'len' is never read
                                len = write(sk, buf,
                                ^     ~~~~~~~~~~~~~~
tools/avtest.c:309:5: warning: Value stored to 'len' is never read
                                len = write(sk, buf, 4);
                                ^     ~~~~~~~~~~~~~~~~~
tools/avtest.c:313:5: warning: Value stored to 'len' is never read
                                len = write(sk, buf, 2);
                                ^     ~~~~~~~~~~~~~~~~~
tools/avtest.c:322:5: warning: Value stored to 'len' is never read
                                len = write(sk, buf, 3);
                                ^     ~~~~~~~~~~~~~~~~~
tools/avtest.c:326:5: warning: Value stored to 'len' is never read
                                len = write(sk, buf, 2);
                                ^     ~~~~~~~~~~~~~~~~~
tools/avtest.c:335:5: warning: Value stored to 'len' is never read
                                len = write(sk, buf, 3);
                                ^     ~~~~~~~~~~~~~~~~~
tools/avtest.c:342:5: warning: Value stored to 'len' is never read
                                len = write(sk, buf, 2);
                                ^     ~~~~~~~~~~~~~~~~~
tools/avtest.c:364:5: warning: Value stored to 'len' is never read
                                len = write(sk, buf, 4);
                                ^     ~~~~~~~~~~~~~~~~~
tools/avtest.c:368:5: warning: Value stored to 'len' is never read
                                len = write(sk, buf, 2);
                                ^     ~~~~~~~~~~~~~~~~~
tools/avtest.c:377:5: warning: Value stored to 'len' is never read
                                len = write(sk, buf, 3);
                                ^     ~~~~~~~~~~~~~~~~~
tools/avtest.c:381:5: warning: Value stored to 'len' is never read
                                len = write(sk, buf, 2);
                                ^     ~~~~~~~~~~~~~~~~~
tools/avtest.c:394:5: warning: Value stored to 'len' is never read
                                len = write(sk, buf, 4);
                                ^     ~~~~~~~~~~~~~~~~~
tools/avtest.c:398:5: warning: Value stored to 'len' is never read
                                len = write(sk, buf, 2);
                                ^     ~~~~~~~~~~~~~~~~~
tools/avtest.c:405:4: warning: Value stored to 'len' is never read
                        len = write(sk, buf, 2);
                        ^     ~~~~~~~~~~~~~~~~~
tools/avtest.c:415:4: warning: Value stored to 'len' is never read
                        len = write(sk, buf, 2);
                        ^     ~~~~~~~~~~~~~~~~~
tools/avtest.c:580:3: warning: Value stored to 'len' is never read
                len = write(sk, buf, 2);
                ^     ~~~~~~~~~~~~~~~~~
tools/avtest.c:588:3: warning: Value stored to 'len' is never read
                len = write(sk, buf, invalid ? 2 : 3);
                ^     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/avtest.c:602:3: warning: Value stored to 'len' is never read
                len = write(sk, buf, 4 + media_transport_size);
                ^     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/avtest.c:615:3: warning: Value stored to 'len' is never read
                len = write(sk, buf, 3);
                ^     ~~~~~~~~~~~~~~~~~
tools/avtest.c:625:3: warning: Value stored to 'len' is never read
                len = write(sk, buf, 3);
                ^     ~~~~~~~~~~~~~~~~~
tools/avtest.c:637:3: warning: Value stored to 'len' is never read
                len = write(sk, buf, 3);
                ^     ~~~~~~~~~~~~~~~~~
tools/avtest.c:652:3: warning: Value stored to 'len' is never read
                len = write(sk, buf, 3);
                ^     ~~~~~~~~~~~~~~~~~
tools/avtest.c:664:3: warning: Value stored to 'len' is never read
                len = write(sk, buf, 3);
                ^     ~~~~~~~~~~~~~~~~~
tools/avtest.c:673:3: warning: Value stored to 'len' is never read
                len = write(sk, buf, 3);
                ^     ~~~~~~~~~~~~~~~~~
tools/avtest.c:680:3: warning: Value stored to 'len' is never read
                len = write(sk, buf, 2);
                ^     ~~~~~~~~~~~~~~~~~
tools/avtest.c:716:2: warning: Value stored to 'len' is never read
        len = write(sk, buf, AVCTP_HEADER_LENGTH + sizeof(play_pressed));
        ^     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
32 warnings generated.
tools/btproxy.c:836:15: warning: Null pointer passed to 1st parameter expecting 'nonnull'
                        tcp_port = atoi(optarg);
                                   ^~~~~~~~~~~~
tools/btproxy.c:839:8: warning: Null pointer passed to 1st parameter expecting 'nonnull'
                        if (strlen(optarg) > 3 && !strncmp(optarg, "hci", 3))
                            ^~~~~~~~~~~~~~
2 warnings generated.
tools/create-image.c:76:3: warning: Value stored to 'fd' is never read
                fd = -1;
                ^    ~~
tools/create-image.c:84:3: warning: Value stored to 'fd' is never read
                fd = -1;
                ^    ~~
tools/create-image.c:92:3: warning: Value stored to 'fd' is never read
                fd = -1;
                ^    ~~
tools/create-image.c:105:2: warning: Value stored to 'fd' is never read
        fd = -1;
        ^    ~~
4 warnings generated.
tools/check-selftest.c:42:3: warning: Value stored to 'ptr' is never read
                ptr = fgets(result, sizeof(result), fp);
                ^     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
tools/btgatt-client.c:1822:2: warning: Value stored to 'argv' is never read
        argv += optind;
        ^       ~~~~~~
1 warning generated.
tools/btgatt-server.c:1204:2: warning: Value stored to 'argv' is never read
        argv -= optind;
        ^       ~~~~~~
1 warning generated.
tools/gatt-service.c:294:2: warning: 2nd function call argument is an uninitialized value
        chr_write(chr, value, len);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
tools/obex-server-tool.c:133:13: warning: Null pointer passed to 1st parameter expecting 'nonnull'
        data->fd = open(name, O_WRONLY | O_CREAT | O_NOCTTY, 0600);
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/obex-server-tool.c:192:13: warning: Null pointer passed to 1st parameter expecting 'nonnull'
        data->fd = open(name, O_RDONLY | O_NOCTTY, 0);
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 warnings generated.
tools/test-runner.c:1370:2: warning: Address of stack memory associated with local variable 'kernel_path' is still referred to by the global variable 'kernel_image' upon returning to the caller.  This will be a dangling reference
        return EXIT_SUCCESS;
        ^~~~~~~~~~~~~~~~~~~
1 warning generated.
client/btpclient/btpclientctl.c:402:3: warning: Value stored to 'bit' is never read
                bit = 0;
                ^     ~
client/btpclient/btpclientctl.c:1655:2: warning: Null pointer passed to 2nd parameter expecting 'nonnull'
        memcpy(cp->data, ad_data, ad_len);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 warnings generated.
src/sdp-client.c:353:14: warning: Access to field 'cb' results in a dereference of a null pointer
        (*ctxt)->cb = cb;
        ~~~~~~~~~~~~^~~~
1 warning generated.
src/sdpd-request.c:209:13: warning: Result of 'malloc' is converted to a pointer of type 'char', which is incompatible with sizeof operand type 'uint16_t'
                                pElem = malloc(sizeof(uint16_t));
                                        ^~~~~~ ~~~~~~~~~~~~~~~~
src/sdpd-request.c:237:13: warning: Result of 'malloc' is converted to a pointer of type 'char', which is incompatible with sizeof operand type 'uint32_t'
                                pElem = malloc(sizeof(uint32_t));
                                        ^~~~~~ ~~~~~~~~~~~~~~~~
2 warnings generated.
src/gatt-database.c:1171:10: warning: Value stored to 'bits' during its initialization is never read
        uint8_t bits[] = { BT_GATT_CHRC_CLI_FEAT_ROBUST_CACHING,
                ^~~~     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
src/gatt-client.c:1569:2: warning: Use of memory after it is freed
        notify_client_unref(client);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
unit/avrcp-lib.c:1968:3: warning: 1st function call argument is an uninitialized value
                g_free(text[i]);
                ^~~~~~~~~~~~~~~
1 warning generated.
unit/avdtp.c:756:25: warning: Use of memory after it is freed
                session->prio_queue = g_slist_remove(session->prio_queue, req);
                                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
unit/avdtp.c:763:24: warning: Use of memory after it is freed
                session->req_queue = g_slist_remove(session->req_queue, req);
                                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 warnings generated.
unit/test-util.c:33:8: warning: Potential leak of memory pointed to by 'p1'
        p2[0] = 1;
        ~~~~~~^~~
unit/test-util.c:36:3: warning: Potential leak of memory pointed to by 'p2'
                _cleanup_free_ uint8_t *data = NULL;
                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
./src/shared/util.h:134:24: note: expanded from macro '_cleanup_free_'
#define _cleanup_free_ _cleanup_(freep)
                       ^
./src/shared/util.h:132:22: note: expanded from macro '_cleanup_'
#define _cleanup_(f) __attribute__((cleanup(f)))
                     ^
unit/test-util.c:42:3: warning: Potential leak of memory pointed to by 'data'
                assert(is_null_too == NULL);
                ^~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/assert.h:108:11: note: expanded from macro 'assert'
  ((void) sizeof ((expr) ? 1 : 0), __extension__ ({                     \
          ^~~~~~~~~~~~~~~~~~~~~~~
unit/test-util.c:50:2: warning: Potential leak of memory pointed to by 'data'
        assert(is_null == NULL);
        ^~~~~~~~~~~~~~~~~~~~~~~
/usr/include/assert.h:108:11: note: expanded from macro 'assert'
  ((void) sizeof ((expr) ? 1 : 0), __extension__ ({                     \
          ^~~~~~~~~~~~~~~~~~~~~~~
4 warnings generated.
profiles/audio/avdtp.c:895:25: warning: Use of memory after it is freed
                session->prio_queue = g_slist_remove(session->prio_queue, req);
                                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
profiles/audio/avdtp.c:902:24: warning: Use of memory after it is freed
                session->req_queue = g_slist_remove(session->req_queue, req);
                                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 warnings generated.
profiles/audio/a2dp.c:442:8: warning: Use of memory after it is freed
                if (!cb->resume_cb)
                     ^~~~~~~~~~~~~
profiles/audio/a2dp.c:3354:20: warning: Access to field 'starting' results in a dereference of a null pointer (loaded from variable 'stream')
                stream->starting = TRUE;
                ~~~~~~           ^
profiles/audio/a2dp.c:3357:8: warning: Access to field 'suspending' results in a dereference of a null pointer (loaded from variable 'stream')
                if (!stream->suspending && stream->suspend_timer) {
                     ^~~~~~~~~~~~~~~~~~
profiles/audio/a2dp.c:3417:22: warning: Access to field 'suspending' results in a dereference of a null pointer (loaded from variable 'stream')
                stream->suspending = TRUE;
                ~~~~~~             ^
4 warnings generated.
profiles/audio/avrcp.c:1968:2: warning: Value stored to 'operands' is never read
        operands += sizeof(*pdu);
        ^           ~~~~~~~~~~~~
1 warning generated.
attrib/gatt.c:970:2: warning: Potential leak of memory pointed to by 'long_write'
        return prepare_write(long_write);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
src/sdpd-request.c:209:13: warning: Result of 'malloc' is converted to a pointer of type 'char', which is incompatible with sizeof operand type 'uint16_t'
                                pElem = malloc(sizeof(uint16_t));
                                        ^~~~~~ ~~~~~~~~~~~~~~~~
src/sdpd-request.c:237:13: warning: Result of 'malloc' is converted to a pointer of type 'char', which is incompatible with sizeof operand type 'uint32_t'
                                pElem = malloc(sizeof(uint32_t));
                                        ^~~~~~ ~~~~~~~~~~~~~~~~
2 warnings generated.
src/sdp-client.c:353:14: warning: Access to field 'cb' results in a dereference of a null pointer
        (*ctxt)->cb = cb;
        ~~~~~~~~~~~~^~~~
1 warning generated.
src/gatt-database.c:1171:10: warning: Value stored to 'bits' during its initialization is never read
        uint8_t bits[] = { BT_GATT_CHRC_CLI_FEAT_ROBUST_CACHING,
                ^~~~     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
src/sdp-xml.c:126:10: warning: Assigned value is garbage or undefined
                buf[1] = data[i + 1];
                       ^ ~~~~~~~~~~~
src/sdp-xml.c:306:11: warning: Assigned value is garbage or undefined
                        buf[1] = data[i + 1];
                               ^ ~~~~~~~~~~~
src/sdp-xml.c:344:11: warning: Assigned value is garbage or undefined
                        buf[1] = data[i + 1];
                               ^ ~~~~~~~~~~~
3 warnings generated.
src/gatt-client.c:1569:2: warning: Use of memory after it is freed
        notify_client_unref(client);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
gobex/gobex-header.c:95:2: warning: Null pointer passed to 2nd parameter expecting 'nonnull'
        memcpy(to, from, count);
        ^~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
gobex/gobex-transfer.c:423:7: warning: Use of memory after it is freed
        if (!g_slist_find(transfers, transfer))
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
mesh/main.c:162:3: warning: Value stored to 'optarg' is never read
                optarg += strlen("auto");
                ^         ~~~~~~~~~~~~~~
1 warning generated.
lib/bluetooth/hci.c:93:4: warning: Value stored to 'ptr' is never read
                        ptr += sprintf(ptr, "%s", m->str);
                        ^      ~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
client/player.c:2363:8: warning: Null pointer passed to 2nd parameter expecting 'nonnull'
                if (!strcmp(ep->path, pattern))
                     ^~~~~~~~~~~~~~~~~~~~~~~~~
client/player.c:3640:16: warning: Null pointer passed to 1st parameter expecting 'nonnull'
        codec->name = strdup(name);
                      ^~~~~~~~~~~~
2 warnings generated.
gdbus/watch.c:226:3: warning: Attempt to free released memory
                g_free(l->data);
                ^~~~~~~~~~~~~~~
1 warning generated.
lib/bluetooth/sdp.c:509:17: warning: Dereference of undefined pointer value
                uint8_t dtd = *(uint8_t *) dtds[i];
                              ^~~~~~~~~~~~~~~~~~~~
lib/bluetooth/sdp.c:539:17: warning: Dereference of undefined pointer value
                uint8_t dtd = *(uint8_t *) dtds[i];
                              ^~~~~~~~~~~~~~~~~~~~
lib/bluetooth/sdp.c:1891:26: warning: Potential leak of memory pointed to by 'ap'
        for (; pdlist; pdlist = pdlist->next) {
                                ^~~~~~
lib/bluetooth/sdp.c:1905:6: warning: Potential leak of memory pointed to by 'pds'
                ap = sdp_list_append(ap, pds);
                ~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
lib/bluetooth/sdp.c:1950:10: warning: Potential leak of memory pointed to by 'u'
                        *seqp = sdp_list_append(*seqp, u);
                        ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
lib/bluetooth/sdp.c:2055:4: warning: Potential leak of memory pointed to by 'lang'
                        sdp_list_free(*langSeq, free);
                        ^~~~~~~~~~~~~
lib/bluetooth/sdp.c:2144:9: warning: Potential leak of memory pointed to by 'profDesc'
        return 0;
               ^
lib/bluetooth/sdp.c:3276:8: warning: Potential leak of memory pointed to by 'pSvcRec'
                pSeq = sdp_list_append(pSeq, pSvcRec);
                ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
lib/bluetooth/sdp.c:3277:9: warning: Potential leak of memory pointed to by 'pSeq'
                pdata += sizeof(uint32_t);
                ~~~~~~^~~~~~~~~~~~~~~~~~~
lib/bluetooth/sdp.c:4613:13: warning: Potential leak of memory pointed to by 'rec_list'
                        } while (scanned < attr_list_len && pdata_len > 0);
                                 ^~~~~~~
lib/bluetooth/sdp.c:4909:40: warning: Potential leak of memory pointed to by 'tseq'
        for (d = sdpdata->val.dataseq; d; d = d->next) {
                                              ^
lib/bluetooth/sdp.c:4945:8: warning: Potential leak of memory pointed to by 'subseq'
                tseq = sdp_list_append(tseq, subseq);
                ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
12 warnings generated.
src/shared/gatt-client.c:447:21: warning: Use of memory after it is freed
        gatt_db_unregister(op->client->db, op->db_id);
                           ^~~~~~~~~~
src/shared/gatt-client.c:692:2: warning: Use of memory after it is freed
        discovery_op_complete(op, false, att_ecode);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:992:2: warning: Use of memory after it is freed
        discovery_op_complete(op, success, att_ecode);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1098:2: warning: Use of memory after it is freed
        discovery_op_complete(op, success, att_ecode);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1292:2: warning: Use of memory after it is freed
        discovery_op_complete(op, success, att_ecode);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1357:2: warning: Use of memory after it is freed
        discovery_op_complete(op, success, att_ecode);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1632:6: warning: Use of memory after it is freed
        if (read_db_hash(op)) {
            ^~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1637:2: warning: Use of memory after it is freed
        discover_all(op);
        ^~~~~~~~~~~~~~~~
src/shared/gatt-client.c:1693:56: warning: Use of memory after it is freed
        notify_data->chrc->ccc_write_id = notify_data->att_id = att_id;
                                          ~~~~~~~~~~~~~~~~~~~ ^
src/shared/gatt-client.c:2146:6: warning: Use of memory after it is freed
        if (read_db_hash(op)) {
            ^~~~~~~~~~~~~~~~
src/shared/gatt-client.c:2154:8: warning: Use of memory after it is freed
                                                        discovery_op_ref(op),
                                                        ^~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:3332:2: warning: Use of memory after it is freed
        complete_write_long_op(req, success, 0, false);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/shared/gatt-client.c:3354:2: warning: Use of memory after it is freed
        request_unref(req);
        ^~~~~~~~~~~~~~~~~~
13 warnings generated.
src/shared/bap.c:1534:8: warning: Use of memory after it is freed
        bap = bt_bap_ref_safe(bap);
              ^~~~~~~~~~~~~~~~~~~~
src/shared/bap.c:2345:20: warning: Use of memory after it is freed
        return queue_find(stream->bap->streams, NULL, stream);
                          ^~~~~~~~~~~~~~~~~~~~
2 warnings generated.
monitor/l2cap.c:1676:4: warning: Value stored to 'data' is never read
                        data += len;
                        ^       ~~~
monitor/l2cap.c:1677:4: warning: Value stored to 'size' is never read
                        size -= len;
                        ^       ~~~
2 warnings generated.
monitor/hwdb.c:59:2: warning: Value stored to 'hwdb' is never read
        hwdb = udev_hwdb_unref(hwdb);
        ^      ~~~~~~~~~~~~~~~~~~~~~
monitor/hwdb.c:64:2: warning: Value stored to 'udev' is never read
        udev = udev_unref(udev);
        ^      ~~~~~~~~~~~~~~~~
monitor/hwdb.c:106:2: warning: Value stored to 'hwdb' is never read
        hwdb = udev_hwdb_unref(hwdb);
        ^      ~~~~~~~~~~~~~~~~~~~~~
monitor/hwdb.c:111:2: warning: Value stored to 'udev' is never read
        udev = udev_unref(udev);
        ^      ~~~~~~~~~~~~~~~~
4 warnings generated.
tools/bluemoon.c:1102:8: warning: Null pointer passed to 1st parameter expecting 'nonnull'
                        if (strlen(optarg) > 3 && !strncmp(optarg, "hci", 3))
                            ^~~~~~~~~~~~~~
1 warning generated.
tools/meshctl.c:326:19: warning: Access to field 'mesh_devices' results in a dereference of a null pointer (loaded from variable 'default_ctrl')
        g_list_free_full(default_ctrl->mesh_devices, g_free);
                         ^~~~~~~~~~~~~~~~~~~~~~~~~~
tools/meshctl.c:762:2: warning: 2nd function call argument is an uninitialized value
        bt_shell_printf("Attempting to disconnect from %s\n", addr);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/meshctl.c:1957:2: warning: Value stored to 'len' is never read
        len = len + extra + strlen("local_node.json");
        ^     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3 warnings generated.
In file included from tools/mesh-gatt/crypto.c:32:
./src/shared/util.h:291:9: warning: 1st function call argument is an uninitialized value
        return be32_to_cpu(get_unaligned((const uint32_t *) ptr));
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./src/shared/util.h:41:26: note: expanded from macro 'be32_to_cpu'
#define be32_to_cpu(val) bswap_32(val)
                         ^~~~~~~~~~~~~
/usr/include/byteswap.h:34:21: note: expanded from macro 'bswap_32'
#define bswap_32(x) __bswap_32 (x)
                    ^~~~~~~~~~~~~~
In file included from tools/mesh-gatt/crypto.c:32:
./src/shared/util.h:301:9: warning: 1st function call argument is an uninitialized value
        return be64_to_cpu(get_unaligned((const uint64_t *) ptr));
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./src/shared/util.h:42:26: note: expanded from macro 'be64_to_cpu'
#define be64_to_cpu(val) bswap_64(val)
                         ^~~~~~~~~~~~~
/usr/include/byteswap.h:37:21: note: expanded from macro 'bswap_64'
#define bswap_64(x) __bswap_64 (x)
                    ^~~~~~~~~~~~~~
2 warnings generated.
ell/util.c:853:8: warning: The left operand of '>' is a garbage value
        if (x > UINT8_MAX)
            ~ ^
ell/util.c:871:8: warning: The left operand of '>' is a garbage value
        if (x > UINT16_MAX)
            ~ ^
2 warnings generated.
ell/pem.c:131:8: warning: Dereference of null pointer (loaded from variable 'eol')
                        if (*eol == '\r' || *eol == '\n')
                            ^~~~
ell/pem.c:166:18: warning: Dereference of null pointer (loaded from variable 'eol')
                if (buf_len && *eol == '\r' && *buf_ptr == '\n') {
                               ^~~~
ell/pem.c:166:34: warning: Dereference of null pointer (loaded from variable 'buf_ptr')
                if (buf_len && *eol == '\r' && *buf_ptr == '\n') {
                                               ^~~~~~~~
ell/pem.c:304:11: warning: 1st function call argument is an uninitialized value
        result = pem_load_buffer(file.data, file.st.st_size,
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ell/pem.c:469:9: warning: 1st function call argument is an uninitialized value
        list = l_pem_load_certificate_list_from_data(file.data,
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 warnings generated.
ell/cert.c:645:41: warning: Access to field 'asn1_len' results in a dereference of a null pointer (loaded from variable 'cert')
        key = l_key_new(L_KEY_RSA, cert->asn1, cert->asn1_len);
                                               ^~~~~~~~~~~~~~
1 warning generated.
ell/gvariant-util.c:143:18: warning: The left operand of '>' is a garbage value
                        if (alignment > max_alignment)
                            ~~~~~~~~~ ^
ell/gvariant-util.c:456:5: warning: Dereference of null pointer
                        !children[0].fixed_size) {
                         ^~~~~~~~~~~~~~~~~~~~~~
2 warnings generated.
emulator/serial.c:150:2: warning: Assigned value is garbage or undefined
        enum btdev_type uninitialized_var(type);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
emulator/serial.c:150:36: warning: Value stored to 'type' during its initialization is never read
        enum btdev_type uninitialized_var(type);
                                          ^~~~
emulator/serial.c:36:30: note: expanded from macro 'uninitialized_var'
#define uninitialized_var(x) x = x
                             ^   ~
emulator/serial.c:213:2: warning: Assigned value is garbage or undefined
        enum btdev_type uninitialized_var(dev_type);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
emulator/serial.c:213:36: warning: Value stored to 'dev_type' during its initialization is never read
        enum btdev_type uninitialized_var(dev_type);
                                          ^~~~~~~~
emulator/serial.c:36:30: note: expanded from macro 'uninitialized_var'
#define uninitialized_var(x) x = x
                             ^   ~
4 warnings generated.
ell/ecc-external.c:77:11: warning: Assigned value is garbage or undefined
                dest[i] = src[i];
                        ^ ~~~~~~
ell/ecc-external.c:160:18: warning: The right operand of '-' is a garbage value
                diff = left[i] - right[i] - borrow;
                               ^ ~~~~~~~~
ell/ecc-external.c:227:14: warning: 2nd function call argument is an uninitialized value
                        product = mul_64_64(left[i], right[k - i]);
                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ell/ecc-external.c:408:9: warning: Assigned value is garbage or undefined
        tmp[1] = product[3];
               ^ ~~~~~~~~~~
ell/ecc-external.c:435:22: warning: The left operand of '&' is a garbage value
        tmp[1] = product[3] & 0xffffffff00000000ull;
                 ~~~~~~~~~~ ^
ell/ecc-external.c:483:22: warning: The left operand of '&' is a garbage value
        tmp[1] = product[5] & 0xffffffff00000000ull;
                 ~~~~~~~~~~ ^
ell/ecc-external.c:688:28: warning: The left operand of '>>' is a garbage value
                tmp[i] = (product[8 + i] >> 9) | (product[9 + i] << 55);
                          ~~~~~~~~~~~~~~ ^
7 warnings generated.
emulator/server.c:230:2: warning: Assigned value is garbage or undefined
        enum btdev_type uninitialized_var(type);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
emulator/server.c:230:36: warning: Value stored to 'type' during its initialization is never read
        enum btdev_type uninitialized_var(type);
                                          ^~~~
emulator/server.c:36:30: note: expanded from macro 'uninitialized_var'
#define uninitialized_var(x) x = x
                             ^   ~
2 warnings generated.
emulator/b1ee.c:258:3: warning: Potential leak of memory pointed to by 'server_port'
                int opt;
                ^~~~~~~
emulator/b1ee.c:258:3: warning: Potential leak of memory pointed to by 'sniffer_port'
                int opt;
                ^~~~~~~
emulator/b1ee.c:289:2: warning: Value stored to 'argc' is never read
        argc = argc - optind;
        ^      ~~~~~~~~~~~~~
3 warnings generated.
gobex/gobex-header.c:95:2: warning: Null pointer passed to 2nd parameter expecting 'nonnull'
        memcpy(to, from, count);
        ^~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
gobex/gobex-transfer.c:423:7: warning: Use of memory after it is freed
        if (!g_slist_find(transfers, transfer))
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
attrib/gatt.c:970:2: warning: Potential leak of memory pointed to by 'long_write'
        return prepare_write(long_write);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
emulator/btdev.c:6662:20: warning: Access to field 'link' results in a dereference of a null pointer (loaded from variable 'acl')
                le_past_received(acl->link, pa);
                                 ^~~~~~~~~
emulator/btdev.c:6762:25: warning: Access to field 'link' results in a dereference of a null pointer (loaded from variable 'acl')
                le_past_info_received(acl->link, ea);
                                      ^~~~~~~~~
2 warnings generated.
profiles/ranging/rap.c: In function ‘rap_accept’:
profiles/ranging/rap.c:421:4: error: too few arguments to function ‘bt_rap_set_conn_handle’
  421 |    bt_rap_set_conn_handle(data->hci_sm,
      |    ^~~~~~~~~~~~~~~~~~~~~~
In file included from profiles/ranging/rap.c:35:
./src/shared/rap.h:215:6: note: declared here
  215 | bool bt_rap_set_conn_handle(void *hci_sm, struct bt_rap *rap, uint16_t handle,
      |      ^~~~~~~~~~~~~~~~~~~~~~
make[1]: *** [Makefile:8993: profiles/ranging/bluetoothd-rap.o] Error 1
make[1]: *** Waiting for unfinished jobs....
profiles/audio/media.c:1112:7: warning: Use of memory after it is freed
                if (req->cb != pac_select_cb) {
                    ^~~~~~~
1 warning generated.
make: *** [Makefile:4172: all] Error 2


https://github.com/bluez/bluez/pull/2202

---
Regards,
Linux Bluetooth


^ permalink raw reply

* RE: [v1] Bluetooth: btintel_pcie: Separate coredump work from RX work
From: bluez.test.bot @ 2026-06-09 16:52 UTC (permalink / raw)
  To: linux-bluetooth, kiran.k
In-Reply-To: <20260609154617.218747-1-kiran.k@intel.com>

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

This is an automated email and please do not reply to this email.

Dear Submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
While preparing the CI tests, the patches you submitted couldn't be applied to the current HEAD of the repository.

----- Output -----

error: patch failed: drivers/bluetooth/btintel_pcie.c:1426
error: drivers/bluetooth/btintel_pcie.c: patch does not apply
hint: Use 'git am --show-current-patch' to see the failed patch

Please resolve the issue and submit the patches again.


---
Regards,
Linux Bluetooth


^ permalink raw reply

* [PATCH BlueZ v1 4/4] bearer: Check btd_opts.mode on btd_bearer_new
From: Luiz Augusto von Dentz @ 2026-06-09 16:50 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <20260609165057.90837-1-luiz.dentz@gmail.com>

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

Only create the bearer interface if the corresponding transport is
enabled. Return NULL if BREDR bearer is requested in LE-only mode or
LE bearer in BREDR-only mode, so the D-Bus interface is never
registered for unsupported bearers.
---
 src/bearer.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/bearer.c b/src/bearer.c
index 02267c711431..299eba6e8ab8 100644
--- a/src/bearer.c
+++ b/src/bearer.c
@@ -34,6 +34,7 @@
 
 #include "log.h"
 #include "error.h"
+#include "btd.h"
 #include "adapter.h"
 #include "device.h"
 #include "profile.h"
@@ -278,6 +279,10 @@ struct btd_bearer *btd_bearer_new(struct btd_device *device, uint8_t type)
 {
 	struct btd_bearer *bearer;
 
+	if ((type == BDADDR_BREDR && btd_opts.mode == BT_MODE_LE) ||
+			(type != BDADDR_BREDR && btd_opts.mode == BT_MODE_BREDR))
+		return NULL;
+
 	bearer = new0(struct btd_bearer, 1);
 	bearer->device = device;
 	bearer->type = type;
-- 
2.54.0


^ permalink raw reply related

* [PATCH BlueZ v1 3/4] plugins: Check btd_profile_register return value
From: Luiz Augusto von Dentz @ 2026-06-09 16:50 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <20260609165057.90837-1-luiz.dentz@gmail.com>

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

Ensure all plugin init functions check the return value of
btd_profile_register. If registration fails (e.g. bearer not enabled),
the plugin init propagates the error instead of continuing with an
unregistered profile.
---
 profiles/audio/a2dp.c      | 14 ++++++++++++--
 profiles/audio/avrcp.c     | 13 +++++++++++--
 profiles/audio/hfp-hf.c    |  4 +---
 profiles/audio/micp.c      |  7 ++++++-
 profiles/input/manager.c   |  4 +---
 profiles/network/manager.c |  5 ++++-
 src/gatt-database.c        |  4 +++-
 7 files changed, 38 insertions(+), 13 deletions(-)

diff --git a/profiles/audio/a2dp.c b/profiles/audio/a2dp.c
index c7e0fc75c09e..a5e002784c02 100644
--- a/profiles/audio/a2dp.c
+++ b/profiles/audio/a2dp.c
@@ -3798,9 +3798,19 @@ static struct btd_adapter_driver media_driver = {
 
 static int a2dp_init(void)
 {
+	int err;
+
 	btd_register_adapter_driver(&media_driver);
-	btd_profile_register(&a2dp_source_profile);
-	btd_profile_register(&a2dp_sink_profile);
+
+	err = btd_profile_register(&a2dp_source_profile);
+	if (err)
+		return err;
+
+	err = btd_profile_register(&a2dp_sink_profile);
+	if (err) {
+		btd_profile_unregister(&a2dp_source_profile);
+		return err;
+	}
 
 	return 0;
 }
diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index b6823753fe68..f63acd47091a 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
@@ -4987,8 +4987,17 @@ static struct btd_profile avrcp_controller_profile = {
 
 static int avrcp_init(void)
 {
-	btd_profile_register(&avrcp_controller_profile);
-	btd_profile_register(&avrcp_target_profile);
+	int err;
+
+	err = btd_profile_register(&avrcp_controller_profile);
+	if (err)
+		return err;
+
+	err = btd_profile_register(&avrcp_target_profile);
+	if (err) {
+		btd_profile_unregister(&avrcp_controller_profile);
+		return err;
+	}
 
 	populate_default_features();
 
diff --git a/profiles/audio/hfp-hf.c b/profiles/audio/hfp-hf.c
index c91b16426898..8de2d7a62d68 100644
--- a/profiles/audio/hfp-hf.c
+++ b/profiles/audio/hfp-hf.c
@@ -507,9 +507,7 @@ static struct btd_profile hfp_hf_profile = {
 
 static int hfp_init(void)
 {
-	btd_profile_register(&hfp_hf_profile);
-
-	return 0;
+	return btd_profile_register(&hfp_hf_profile);
 }
 
 static void hfp_exit(void)
diff --git a/profiles/audio/micp.c b/profiles/audio/micp.c
index 475f32daf75c..3d39ef5e147f 100644
--- a/profiles/audio/micp.c
+++ b/profiles/audio/micp.c
@@ -318,12 +318,17 @@ static unsigned int micp_id;
 
 static int micp_init(void)
 {
+	int err;
+
 	if (!(g_dbus_get_flags() & G_DBUS_FLAG_ENABLE_EXPERIMENTAL)) {
 		DBG("D-Bus experimental not enabled");
 		return -ENOTSUP;
 	}
 
-	btd_profile_register(&micp_profile);
+	err = btd_profile_register(&micp_profile);
+	if (err)
+		return err;
+
 	micp_id = bt_micp_register(micp_attached, micp_detached, NULL);
 
 	return 0;
diff --git a/profiles/input/manager.c b/profiles/input/manager.c
index 0fcd6728c2fc..1fd82d82f500 100644
--- a/profiles/input/manager.c
+++ b/profiles/input/manager.c
@@ -118,12 +118,10 @@ static int input_init(void)
 
 	}
 
-	btd_profile_register(&input_profile);
-
 	if (config)
 		g_key_file_free(config);
 
-	return 0;
+	return btd_profile_register(&input_profile);
 }
 
 static void input_exit(void)
diff --git a/profiles/network/manager.c b/profiles/network/manager.c
index 693547d45fbc..a5f28a99ebfd 100644
--- a/profiles/network/manager.c
+++ b/profiles/network/manager.c
@@ -180,7 +180,10 @@ static int network_init(void)
 	if (server_init(conf_security) < 0)
 		return -1;
 
-	btd_profile_register(&panu_profile);
+	err = btd_profile_register(&panu_profile);
+	if (err)
+		return err;
+
 	btd_profile_register(&gn_profile);
 	btd_profile_register(&nap_profile);
 
diff --git a/src/gatt-database.c b/src/gatt-database.c
index 680a52952b16..30e25b6f41ca 100644
--- a/src/gatt-database.c
+++ b/src/gatt-database.c
@@ -3624,7 +3624,9 @@ static void add_profile(void *data, void *user_data)
 {
 	struct btd_adapter *adapter = user_data;
 
-	btd_profile_register(data);
+	if (btd_profile_register(data))
+		return;
+
 	adapter_add_profile(adapter, data);
 }
 
-- 
2.54.0


^ permalink raw reply related

* [PATCH BlueZ v1 2/4] profile: Check if bearer is enabled on registration
From: Luiz Augusto von Dentz @ 2026-06-09 16:50 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <20260609165057.90837-1-luiz.dentz@gmail.com>

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

btd_profile_register now verifies that the profile's bearer type is
compatible with btd_opts.mode before registering. If the required bearer
is not enabled (e.g. LE-only profile when mode is BR/EDR, or BR/EDR-only
profile when mode is LE), registration is rejected with -ENOTSUP.
---
 src/profile.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/src/profile.c b/src/profile.c
index 65df0f7a0969..97fffe9b4d5c 100644
--- a/src/profile.c
+++ b/src/profile.c
@@ -36,6 +36,7 @@
 #include "dbus-common.h"
 #include "sdp-client.h"
 #include "sdp-xml.h"
+#include "btd.h"
 #include "adapter.h"
 #include "device.h"
 #include "profile.h"
@@ -802,6 +803,14 @@ struct btd_profile *btd_profile_find_remote_uuid(const char *uuid)
 
 int btd_profile_register(struct btd_profile *profile)
 {
+	if ((profile->bearer == BTD_PROFILE_BEARER_LE &&
+				btd_opts.mode == BT_MODE_BREDR) ||
+			(profile->bearer == BTD_PROFILE_BEARER_BREDR &&
+				btd_opts.mode == BT_MODE_LE)) {
+		DBG("Bearer not enabled");
+		return -ENOTSUP;
+	}
+
 	if (profile->experimental && !(g_dbus_get_flags() &
 					G_DBUS_FLAG_ENABLE_EXPERIMENTAL)) {
 		DBG("D-Bus experimental not enabled");
-- 
2.54.0


^ permalink raw reply related


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