From: Martin Mirchev Date: Tue, 27 Oct 2026 06:17:35 +0000 (+0800) Subject: BUG/MINOR: connection: check the IP header length in NetScaler CIP X-Git-Tag: v3.5-dev10~11 X-Git-Url: https://git.kaiwu.me/?a=commitdiff_plain;h=f5359da6e387e18dc76d17e40df2c2c05ae91719;p=haproxy.git BUG/MINOR: connection: check the IP header length in NetScaler CIP conn_recv_netscaler_cip() takes the TCP ports at ip_hl * 4 bytes after the start of the IPv4 header without checking ip_hl nor that the announced header length covers them: - with ip_hl < 5 the ports are taken from the IPv4 header itself (e.g. ip_hl=0 gives source port 16384 from the version/IHL byte); - with a header length shorter than ip_hl * 4 + 4 (e.g. ip_hl=15 and a 40-byte header) they are taken from the payload or from bytes past the received data, which are leftovers of the previous use of the trash buffer, possibly from another connection. The same applies to IPv6 with a header length shorter than 44 bytes. The reads stay inside the trash buffer, so this is not a memory safety issue, but the session addresses end up with wrong ports. Let's reject such headers with CO_ER_CIP_BAD_PROTO. This should be backported to all stable versions. --- diff --git a/src/connection.c b/src/connection.c index 52fe22038..051efc22a 100644 --- a/src/connection.c +++ b/src/connection.c @@ -1784,6 +1784,14 @@ int conn_recv_netscaler_cip(struct connection *conn, int flag) conn->err_code = CO_ER_CIP_BAD_PROTO; goto fail; } + else if (hdr_ip4->ip_hl < 5 || + hdr_len < hdr_ip4->ip_hl * 4 + sizeof(struct my_tcphdr)) { + /* The IPv4 header length is invalid or the announced + * header is too short to contain the TCP ports. + */ + conn->err_code = CO_ER_CIP_BAD_PROTO; + goto fail; + } hdr_tcp = (struct my_tcphdr *)(line + (hdr_ip4->ip_hl * 4)); @@ -1815,6 +1823,11 @@ int conn_recv_netscaler_cip(struct connection *conn, int flag) conn->err_code = CO_ER_CIP_BAD_PROTO; goto fail; } + else if (hdr_len < sizeof(struct ip6_hdr) + sizeof(struct my_tcphdr)) { + /* The announced header is too short to contain the TCP ports */ + conn->err_code = CO_ER_CIP_BAD_PROTO; + goto fail; + } hdr_tcp = (struct my_tcphdr *)(line + sizeof(struct ip6_hdr));