]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[Fix] Fix subprocess cleanup race in spawn_process SIGCHLD handler
authorVsevolod Stakhov <vsevolod@rspamd.com>
Tue, 24 Feb 2026 11:37:27 +0000 (11:37 +0000)
committerVsevolod Stakhov <vsevolod@rspamd.com>
Tue, 24 Feb 2026 11:37:27 +0000 (11:37 +0000)
When the I/O handler finishes reading the subprocess reply before
SIGCHLD arrives, neither handler would call rspamd_lua_cbdata_free:
the I/O handler skips cleanup because dead=FALSE, and the SIGCHLD
handler skips cleanup because replied=TRUE. This leaves the subprocess
in the main process workers table, causing shutdown to wait for a
child that has already exited.

Fix by always calling rspamd_lua_cbdata_free in the SIGCHLD handler
when replied=TRUE, since the I/O handler has already finished and
deferred cleanup to us.

src/lua/lua_worker.c

index 969b8eb7ce338a849f39064914efd5f45fcffebd..f1ce45bed0a5478b50186bb33d9f4dc7a21c7753 100644 (file)
@@ -636,8 +636,11 @@ rspamd_lua_cld_handler(struct rspamd_worker_signal_handler *sigh, void *ud)
                                                                        "Worker has died without reply", NULL, 0);
                rspamd_lua_cbdata_free(cbdata);
        }
-       /* If replied is TRUE, the I/O handler is processing the callback.
-        * It will call rspamd_lua_cbdata_free() when done. */
+       else {
+               /* I/O handler already processed the reply but couldn't clean up
+                * because the child wasn't dead yet at that point. Clean up now. */
+               rspamd_lua_cbdata_free(cbdata);
+       }
 
        /* We are done with this SIGCHLD */
        return FALSE;