]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: connection: sanitize PPv2 header length before parsing address information
authorKOVACS Krisztian <hidden@balabit.com>
Wed, 19 Nov 2014 09:53:20 +0000 (10:53 +0100)
committerWilly Tarreau <w@1wt.eu>
Fri, 21 Nov 2014 06:45:17 +0000 (07:45 +0100)
Previously, if hdr_v2->len was less than the length of the protocol
specific address information we could have read after the end of the
buffer and initialize the sockaddr structure with junk.

Signed-off-by: KOVACS Krisztian <hidden@balabit.com>
[WT: this is only tagged medium since proxy protocol is only used from
 trusted sources]

This must be backported to 1.5.

src/connection.c

index 3af6d9afd7e9dda8f768b3158c8ed855c2fb15cf..b9f5c42b44e620207fc1b0a860ccff0ffb67d8bf 100644 (file)
@@ -424,6 +424,9 @@ int conn_recv_proxy(struct connection *conn, int flag)
        case 0x01: /* PROXY command */
                switch (hdr_v2->fam) {
                case 0x11:  /* TCPv4 */
+                       if (ntohs(hdr_v2->len) < PP2_ADDR_LEN_INET)
+                               goto bad_header;
+
                        ((struct sockaddr_in *)&conn->addr.from)->sin_family = AF_INET;
                        ((struct sockaddr_in *)&conn->addr.from)->sin_addr.s_addr = hdr_v2->addr.ip4.src_addr;
                        ((struct sockaddr_in *)&conn->addr.from)->sin_port = hdr_v2->addr.ip4.src_port;
@@ -433,6 +436,9 @@ int conn_recv_proxy(struct connection *conn, int flag)
                        conn->flags |= CO_FL_ADDR_FROM_SET | CO_FL_ADDR_TO_SET;
                        break;
                case 0x21:  /* TCPv6 */
+                       if (ntohs(hdr_v2->len) < PP2_ADDR_LEN_INET6)
+                               goto bad_header;
+
                        ((struct sockaddr_in6 *)&conn->addr.from)->sin6_family = AF_INET6;
                        memcpy(&((struct sockaddr_in6 *)&conn->addr.from)->sin6_addr, hdr_v2->addr.ip6.src_addr, 16);
                        ((struct sockaddr_in6 *)&conn->addr.from)->sin6_port = hdr_v2->addr.ip6.src_port;