]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: httpclient: always detach the caller before self-killing
authorWilly Tarreau <w@1wt.eu>
Thu, 1 Sep 2022 18:40:26 +0000 (20:40 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 2 Sep 2022 09:19:07 +0000 (11:19 +0200)
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.

src/http_client.c

index 3fffdbf13bbb9e56d94047937ad081908a4644bb..8bc65553fc7a13a2e1f7911f26b3d4fd1cf18ea1 100644 (file)
@@ -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);
        }