From: Willy Tarreau Date: Thu, 1 Sep 2022 18:40:26 +0000 (+0200) Subject: BUG/MEDIUM: httpclient: always detach the caller before self-killing X-Git-Tag: v2.7-dev5~18 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b48292068bee8a54ed33a9e809c56ddcc566396c;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: httpclient: always detach the caller before self-killing If the caller dies before the server responds, the httpclient can crash in hc_cli_res_end_cb() when unregistering because it dereferences hc->caller which was already freed during the caller's unregistration. The easiest way to reproduce it is by sending twice the following request on the same CLI connection in expert mode, with httpterm running on local port 8000: httpclient GET http://127.0.0.1:8000/?t=600 Note the 600ms delay that's larger than socat's default 500. The code checks for a NULL everywhere hc->caller is used, but the NULL was forgotten in this specific case. It must be placed in the second half of httpclient_stop_and_destroy() which is responsible for signaling the client that the caller leaves. This must be backported to 2.6. --- diff --git a/src/http_client.c b/src/http_client.c index 3fffdbf13b..8bc65553fc 100644 --- a/src/http_client.c +++ b/src/http_client.c @@ -567,8 +567,10 @@ void httpclient_stop_and_destroy(struct httpclient *hc) if (hc->flags & HTTPCLIENT_FS_ENDED || !(hc->flags & HTTPCLIENT_FS_STARTED)) { httpclient_destroy(hc); } else { - /* if the client wasn't stopped, ask for a stop and destroy */ + /* if the client wasn't stopped, ask for a stop and destroy */ hc->flags |= (HTTPCLIENT_FA_AUTOKILL | HTTPCLIENT_FA_STOP); + /* the calling applet doesn't exist anymore */ + hc->caller = NULL; if (hc->appctx) appctx_wakeup(hc->appctx); }