From 313d1ef88a11bb7f461d693001ba2a39fff6ed38 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Wed, 8 Jul 2026 16:54:28 +0200 Subject: [PATCH] watcher: Properly handle conflict during concurrent FD removal If an FD we intend to remove is currently busy in a callback, we wait on a condvar to retry later. If the FD is not the first in the list, `prev` will be set to the previous entry in the list. This is fine when no other threads are concurrently removing FDs, the same entry will be found on the next try and prev points to the same value again. However, if other threads also remove one or more FDs and the initial FD is now the first in the list `prev` should be NULL and not point to a removed entry. Fixes: b27663399b4b ("watcher: Avoid allocations due to enumerators") --- src/libstrongswan/processing/watcher.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstrongswan/processing/watcher.c b/src/libstrongswan/processing/watcher.c index fd1c2354c..7b2c2058b 100644 --- a/src/libstrongswan/processing/watcher.c +++ b/src/libstrongswan/processing/watcher.c @@ -561,12 +561,12 @@ METHOD(watcher_t, add, void, METHOD(watcher_t, remove_, void, private_watcher_t *this, int fd) { - entry_t *entry, *prev = NULL; watcher_event_t found = 0; this->mutex->lock(this->mutex); while (TRUE) { + entry_t *entry, *prev = NULL; bool is_in_callback = FALSE; entry = this->fds;