Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH BlueZ 1/2] shared: mainloop: Skip removed mainloop events
@ 2026-09-27 17:49 Pauli Virtanen
  2026-09-27 17:49 ` [PATCH BlueZ 2/2] unit: test-mainloop: add basic mainloop test Pauli Virtanen
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Pauli Virtanen @ 2026-09-27 17:49 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Pauli Virtanen

mainloop_remove_fd() on an fd that occurs in the same epoll_wait batch
as the current callback, causes ASan crash.

Several callsites do this, crash is sporadic since it requires suitable
timing.

Fix by adding registration ID in each event and dispatching only if that
registration is still active.

Fixes random btvirt crashes.

Log:
ERROR: AddressSanitizer: heap-use-after-free on address 0x7b7576be3f18
READ of size 8 at 0x7b7576be3f18 thread T0
    #0 0x5637f7b4014f in mainloop_run src/shared/mainloop.c:104
    #1 0x5637f7b41f79 in mainloop_run_with_signal src/shared/mainloop-notify.c:196
    #2 0x5637f7aa598b in main emulator/main.c:310
freed by thread T0 here:
    #0 0x7f45788ee4cf in free.part.0 (/lib64/libasan.so.8+0xee4cf)
    #1 0x5637f7b40d05 in mainloop_remove_fd src/shared/mainloop.c:213
previously allocated by thread T0 here:
    #0 0x7f45788ef24f in calloc (/lib64/libasan.so.8+0xef24f)
    #1 0x5637f7b4034b in mainloop_add_fd src/shared/mainloop.c:142

Assisted-by: opencode:gpt-6-sol
---

Notes:
    Triaged with LLM, patches cleaned up manually.

 src/shared/mainloop.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/src/shared/mainloop.c b/src/shared/mainloop.c
index 9a2e1eee6..b3ec0f2b1 100644
--- a/src/shared/mainloop.c
+++ b/src/shared/mainloop.c
@@ -35,9 +35,11 @@
 static int epoll_fd;
 static int epoll_terminate;
 static int exit_status = EXIT_SUCCESS;
+static uint64_t next_id;
 
 struct mainloop_data {
 	int fd;
+	uint64_t id;
 	uint32_t events;
 	mainloop_event_func callback;
 	mainloop_destroy_func destroy;
@@ -99,7 +101,13 @@ int mainloop_run(void)
 			continue;
 
 		for (n = 0; n < nfds; n++) {
-			struct mainloop_data *data = events[n].data.ptr;
+			uint64_t id = events[n].data.u64;
+			int fd = id % MAX_MAINLOOP_ENTRIES;
+			struct mainloop_data *data = mainloop_list[fd];
+
+			/* Another callback may have removed it */
+			if (!data || data->id != id)
+				continue;
 
 			data->callback(data->fd, events[n].events,
 							data->user_data);
@@ -145,6 +153,7 @@ int mainloop_add_fd(int fd, uint32_t events, mainloop_event_func callback,
 
 	memset(data, 0, sizeof(*data));
 	data->fd = fd;
+	data->id = ++next_id * MAX_MAINLOOP_ENTRIES + fd;
 	data->events = events;
 	data->callback = callback;
 	data->destroy = destroy;
@@ -152,7 +161,7 @@ int mainloop_add_fd(int fd, uint32_t events, mainloop_event_func callback,
 
 	memset(&ev, 0, sizeof(ev));
 	ev.events = events;
-	ev.data.ptr = data;
+	ev.data.u64 = data->id;
 
 	err = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, data->fd, &ev);
 	if (err < 0) {
@@ -180,7 +189,7 @@ int mainloop_modify_fd(int fd, uint32_t events)
 
 	memset(&ev, 0, sizeof(ev));
 	ev.events = events;
-	ev.data.ptr = data;
+	ev.data.u64 = data->id;
 
 	err = epoll_ctl(epoll_fd, EPOLL_CTL_MOD, data->fd, &ev);
 	if (err < 0)
-- 
2.55.0


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

end of thread, other threads:[~2026-09-28 17:51 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-27 17:49 [PATCH BlueZ 1/2] shared: mainloop: Skip removed mainloop events Pauli Virtanen
2026-09-27 17:49 ` [PATCH BlueZ 2/2] unit: test-mainloop: add basic mainloop test Pauli Virtanen
2026-09-27 21:14 ` [BlueZ,1/2] shared: mainloop: Skip removed mainloop events bluez.test.bot
2026-09-28 17:50 ` [PATCH BlueZ 1/2] " 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