Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH BlueZ v1] adapter: remove the devices from the list before freeing them
@ 2026-09-18 21:59 Luiz Augusto von Dentz
  2026-09-18 23:23 ` [BlueZ,v1] " bluez.test.bot
  2026-09-21 14:30 ` [PATCH BlueZ v1] " patchwork-bot+bluetooth
  0 siblings, 2 replies; 3+ messages in thread
From: Luiz Augusto von Dentz @ 2026-09-18 21:59 UTC (permalink / raw)
  To: linux-bluetooth

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

The devices of an adapter are freed one by one when it is removed, but
the list keeps pointing at them until every one of them is gone, so it
refers to freed devices while the remaining ones are being removed.

Freeing a device looks devices up though, e.g. cleaning up its GATT
server reports the disconnection, which searches the list for the
device it belongs to, and the search reads the devices already freed:

  ERROR: AddressSanitizer: heap-use-after-free
    in bacmp lib/bluetooth/bluetooth.h:438
    in device_addr_type_cmp src/device.c:5657
    in btd_adapter_find_device src/adapter.c:1055
    in att_disconnected src/gatt-database.c:335
    in gatt_server_cleanup src/device.c:842
    in device_free src/device.c:918

Take each device out of the list before removing it, so only the ones
still to be removed are ever found.

This needs more than one device on the adapter to show up, which the
test of a coordinated set is the first to leave behind.

Assisted-by: opencode:claude-opus-5
---
 src/adapter.c | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index 717db2ea9bfe..50b4dc6d724e 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -7293,7 +7293,6 @@ static struct btd_adapter *btd_adapter_new(uint16_t index)
 
 static void adapter_remove(struct btd_adapter *adapter)
 {
-	GSList *l;
 	struct gatt_db *db;
 	struct btd_ranging_provider_manager *ranging_manager;
 
@@ -7302,13 +7301,19 @@ static void adapter_remove(struct btd_adapter *adapter)
 	g_slist_free(adapter->connect_list);
 	adapter->connect_list = NULL;
 
-	for (l = adapter->devices; l; l = l->next) {
-		device_removed_drivers(adapter, l->data);
-		device_remove(l->data, FALSE);
-	}
+	while (adapter->devices) {
+		struct btd_device *device = adapter->devices->data;
 
-	g_slist_free(adapter->devices);
-	adapter->devices = NULL;
+		/* Take the device out of the list before removing it, as
+		 * freeing it looks devices up, e.g. when cleaning up its
+		 * GATT server, and the ones already freed would still be
+		 * found.
+		 */
+		adapter->devices = g_slist_remove(adapter->devices, device);
+
+		device_removed_drivers(adapter, device);
+		device_remove(device, FALSE);
+	}
 
 	g_slist_free(adapter->discovery_found);
 	adapter->discovery_found = NULL;
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-09-21 14:31 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-18 21:59 [PATCH BlueZ v1] adapter: remove the devices from the list before freeing them Luiz Augusto von Dentz
2026-09-18 23:23 ` [BlueZ,v1] " bluez.test.bot
2026-09-21 14:30 ` [PATCH BlueZ v1] " patchwork-bot+bluetooth

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