From: Christopher Faulet Date: Thu, 8 Oct 2026 10:22:10 +0000 (+0200) Subject: MEDIUM: stream: Hold a reference on the frontend during stream_free() X-Git-Tag: v3.5-dev9~47 X-Git-Url: https://git.kaiwu.me/?a=commitdiff_plain;h=c8f0eb83f2876fe9156d36061cde56d27a155bd0;p=haproxy.git MEDIUM: stream: Hold a reference on the frontend during stream_free() The frontend of a stream is dereferenced until the end of stream_free(), in particular to flush the maximum amount of pools when the proxy is stopping. But when the stream connectors are destroyed, a client applet attached to the stream is released there, and it may free its internal frontend (created owned by the applet), leaving the end of the function with a dangling frontend. Take a reference on the frontend before releasing the stream connector and drop it at the very end of stream_free(), after the last dereference of the frontend. For the frontends that are never released during the lifetime of the process, this is a balanced pair of reference counter updates. This will be needed by the next commits, adding a destroy callback to the applet ops, called when an applet context is destroyed, which may release the frontend of its applet stream. --- diff --git a/src/stream.c b/src/stream.c index c04571df0..4c425230f 100644 --- a/src/stream.c +++ b/src/stream.c @@ -738,6 +738,15 @@ void stream_free(struct stream *s) pool_free(h->pool, s->res_cap[h->index]); pool_free(fe->rsp_cap_pool, s->res_cap); } + + /* Hold a reference on the frontend for the rest of the stream + * teardown. The stream connectors are destroyed below. An + * client applet attached to the stream will be released there, + * and it may free an internal frontend (created and owned by an + * applet), leaving the end of the function with a dangling + * frontend. The reference is dropped at the very end. + */ + proxy_take(fe); } /* Cleanup all variable contexts. */ @@ -799,6 +808,8 @@ void stream_free(struct stream *s) pool_flush(fe->req_cap_pool); pool_flush(fe->rsp_cap_pool); } + + proxy_drop(fe); }