A reversed rhttp connection already has its mux installed when it
reaches session_accept_fd(). If an error occurs after setup (e.g. a
"tcp-request connection reject" rule, or conn_xprt_start() failing),
the error path calls session_free(), which destroys the mux and thus
releases the connection. Control then reaches out_free_conn, which
calls conn_release() on it a second time, causing a crash.
Stop after session_free() when the connection has a mux, since it's
already handled. The listener still needs explicit release.
This dates back to reverse-http's introduction in 3.0 (
12c40c25a,
"MEDIUM: rhttp: create session for active preconnect"). Must be
backported to 3.0.
Reported-by: Claude (ANT-2026-WNWQ4RGC)
/* SESS_FL_RELEASE_LI must not be set here as listener_release() is
* called manually for all errors.
*/
+ if (cli_conn->mux) {
+ /* This is a reverse connection; session_free() will destroy it
+ * and release cli_conn as well, that's why we cannot factor
+ * the session_free() call and exit early.
+ */
+ session_free(sess);
+ goto out_release_listener;
+ }
+
session_free(sess);
out_free_conn:
/* Mux is already initialized for active reversed connection. */
conn_release(cli_conn);
+ out_release_listener:
listener_release(l);
return ret;
}