From efd3aa93412648cf923bf3d2e171c0b84e9d7a69 Mon Sep 17 00:00:00 2001 From: KOVACS Krisztian Date: Wed, 19 Nov 2014 10:53:20 +0100 Subject: [PATCH] BUG/MEDIUM: connection: sanitize PPv2 header length before parsing address information 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 [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 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/connection.c b/src/connection.c index 3af6d9afd..b9f5c42b4 100644 --- a/src/connection.c +++ b/src/connection.c @@ -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;