From af76f2c88dbe1deb61f0443726ea8e9eee7d2eff Mon Sep 17 00:00:00 2001 From: Jun Ouyang Date: Tue, 24 Mar 2026 15:54:55 +0800 Subject: [PATCH 1/2] bugfix: clear wait timer in ngx_http_lua_pipe_proc_wait_cleanup to prevent SIGSEGV on QUIC connection close --- src/ngx_http_lua_pipe.c | 5 +++++ t/191-pipe-proc-quic-close-crash.t | 27 +++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/ngx_http_lua_pipe.c b/src/ngx_http_lua_pipe.c index 27e1c3b233..7b6d0457c8 100644 --- a/src/ngx_http_lua_pipe.c +++ b/src/ngx_http_lua_pipe.c @@ -2616,6 +2616,11 @@ ngx_http_lua_pipe_proc_wait_cleanup(void *data) wait_co_ctx->cleanup = NULL; if (proc->pipe == NULL) { + /* pipe_proc_destroy already ran (LIFO pool cleanup) and closed + * connections, but wait uses wait_co_ctx->sleep (a standalone event, + * not tied to any connection), so ngx_close_connection in + * pipe_proc_destroy cannot cancel it. Clear it here. */ + ngx_http_lua_pipe_clear_event(&wait_co_ctx->sleep); return; } diff --git a/t/191-pipe-proc-quic-close-crash.t b/t/191-pipe-proc-quic-close-crash.t index cb2f0da7f4..76d434f21b 100644 --- a/t/191-pipe-proc-quic-close-crash.t +++ b/t/191-pipe-proc-quic-close-crash.t @@ -99,3 +99,30 @@ GET /t --- curl_error eval: qr/\(28\)/ --- no_error_log [alert] + + +=== TEST 2: pipe wait timer must not fire after pool is freed on QUIC connection close +--- config + location = /t { + content_by_lua_block { + local proc = require("ngx.pipe").spawn({"sleep", "100"}) + -- set_timeouts(write_timeout, stdout_timeout, stderr_timeout, wait_timeout) + proc:set_timeouts(nil, nil, nil, 1000) -- 1 s wait timeout + + -- This call yields and arms a 1 s timer on wait_co_ctx->sleep. + -- Unlike stdout/stderr read timers (tied to a connection), + -- the wait timer is a standalone ngx_event_t, so + -- ngx_close_connection in pipe_proc_destroy cannot cancel it. + -- Without the fix in wait_cleanup, the timer fires after pool + -- is freed → SIGSEGV in ngx_http_lua_pipe_resume_wait_handler. + proc:wait() + } + } +--- request +GET /t +--- timeout: 0.5 +--- wait: 2 +--- ignore_response +--- curl_error eval: qr/\(28\)/ +--- no_error_log +[alert] From 4a3fdf27d12a0d7788531dc48c4602974c94a965 Mon Sep 17 00:00:00 2001 From: lijunlong Date: Tue, 24 Mar 2026 16:01:45 +0800 Subject: [PATCH 2/2] tests: format the test cases. --- t/191-pipe-proc-quic-close-crash.t | 1 + 1 file changed, 1 insertion(+) diff --git a/t/191-pipe-proc-quic-close-crash.t b/t/191-pipe-proc-quic-close-crash.t index 76d434f21b..5664662a5b 100644 --- a/t/191-pipe-proc-quic-close-crash.t +++ b/t/191-pipe-proc-quic-close-crash.t @@ -101,6 +101,7 @@ GET /t [alert] + === TEST 2: pipe wait timer must not fire after pool is freed on QUIC connection close --- config location = /t {