* [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
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox