From: Amaury Denoyelle Date: Thu, 15 Dec 2022 08:18:25 +0000 (+0100) Subject: BUG/MEDIUM: h3: fix cookie header parsing X-Git-Tag: v2.8-dev1~121 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=19942e3859cb5b81fb99448a648f213806fb0bee;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: h3: fix cookie header parsing Cookie header are treated specifically to merge multiple occurences in a single HTX header. This is treated in a if-block condition inside the 'while (1)' loop for headers parsing. The length value of ist representing cookie header is set to -1 by http_cookie_register(). The problem is that then a continue statement is used but without incrementing 'hdr_idx' to pass on the next header. This issue was revealed by the introduction of commit : commit d6fb7a0e0f3a79afa1f4b6fc7b62053c3955dc4a BUG/MEDIUM: h3: reject request with invalid header name Before the aformentionned patch, the bug was hidden : on the next while iteration, all isteq() invocations won't match with cookie header length now set to -1. htx_add_header() fails silently because length is invalid. hdr_idx is finally incremented which allows parsing to proceed normally with the next header. Now, a cookie header with length -1 do not pass the test on header name conformance introduced by the above patch. Thus, a spurrious RESET_STREAM is emitted. This behavior has been reported on the mailing list by Shawn Heisey who found out that browsers disabled H3 usage due to the RESET_STREAM received. Big thanks to him for his testing on the master branch. This issue is simply resolved by incrementing hdr_idx before continue statement. It could have been detected earlier if htx_add_header() return value was checked. This will be the subject of a dedicated commit outside of the backport scope. This must be backported up to 2.6. --- diff --git a/src/h3.c b/src/h3.c index d24b3de5f4..10d19e2cd5 100644 --- a/src/h3.c +++ b/src/h3.c @@ -544,6 +544,7 @@ static ssize_t h3_headers_to_htx(struct qcs *qcs, const struct buffer *buf, if (isteq(list[hdr_idx].n, ist("cookie"))) { http_cookie_register(list, hdr_idx, &cookie, &last_cookie); + ++hdr_idx; continue; } else if (isteq(list[hdr_idx].n, ist("content-length"))) {