From: Willy Tarreau Date: Thu, 6 Aug 2026 07:27:02 +0000 (+0200) Subject: BUG/MINOR: connection: reserve the whole CRC32C TLV before saving its pointer X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2d74dd7e9eb76dc50513f2b12f513e215de1bea4;p=thirdparty%2Fhaproxy.git BUG/MINOR: connection: reserve the whole CRC32C TLV before saving its pointer make_proxy_line_v2() saves a pointer to the CRC32C TLV value so the checksum can be appended once the whole header is known. It only checked for 3 bytes (the TLV header) instead of the 7 needed for the full TLV, so with 3 to 6 bytes left, make_tlv() emitted nothing and returned 0, yet tlv_crc32c_p was still set, and the final write_u32() wrote 4 bytes up to 3 bytes past the end of the header buffer. Not only this theoretically only affects servers using "send-proxy-v2" with "proxy-v2-options crc32c" combined with "set-proxy-v2-tlv-fmt" TLVs, but in addition in practice the proxy protocol is designed to be way shorter than a regular buffer, and the only practical way to reach that is to purposely write a config to demonstrate this, so it cannot happen. This has been there since crc32c support was added in 1.9 by commit 4399c75f6 ("MINOR: proxy-v2-options: add crc32c"). It should be backported to all stable versions. Reported-by: Claude (ANT-2026-H10QWEV6) --- diff --git a/src/connection.c b/src/connection.c index bda892066..9ebbff286 100644 --- a/src/connection.c +++ b/src/connection.c @@ -2357,7 +2357,8 @@ static int make_proxy_line_v2(char *buf, int buf_len, struct server *srv, struct if (srv->pp_opts & SRV_PP_V2_CRC32C) { uint32_t zero_crc32c = 0; - if ((buf_len - ret) < sizeof(struct tlv)) + /* make sure the whole TLV fits, not just its header */ + if ((buf_len - ret) < sizeof(struct tlv) + sizeof(zero_crc32c)) return 0; tlv_crc32c_p = (void *)((struct tlv *)&buf[ret])->value; ret += make_tlv(&buf[ret], (buf_len - ret), PP2_TYPE_CRC32C, sizeof(zero_crc32c), (const char *)&zero_crc32c);