From 53ee8967430df5d56181dcb315f38ec8aae2ae0e Mon Sep 17 00:00:00 2001 From: Marek Majkowski Date: Wed, 20 May 2020 14:41:10 +0100 Subject: [PATCH] Fix crash reproted via hackerone. In new_connection we didn't validate if proxy-protocol header had correct number of items. Classic out-of-bounds. --- Makefile | 2 +- cloudflare-ip-ranges.txt | 2 +- src/main.c | 12 ++++++++---- src/mmproxy.h | 2 +- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 1f91906..d0af69b 100644 --- a/Makefile +++ b/Makefile @@ -56,4 +56,4 @@ format: .PHONY: cloudflare-ip-ranges.txt cloudflare-ip-ranges.txt: - curl -s https://www.cloudflare.com/ips-v4 https://www.cloudflare.com/ips-v6 > cloudflare-ip-ranges.txt + curl -s https://www.cloudflare.com/ips-v4 https://www.cloudflare.com/ips-v6 | sort > cloudflare-ip-ranges.txt diff --git a/cloudflare-ip-ranges.txt b/cloudflare-ip-ranges.txt index e287ffa..ae864dd 100644 --- a/cloudflare-ip-ranges.txt +++ b/cloudflare-ip-ranges.txt @@ -17,5 +17,5 @@ 2405:b500::/32 2606:4700::/32 2803:f800::/32 -2c0f:f248::/32 2a06:98c0::/29 +2c0f:f248::/32 diff --git a/src/main.c b/src/main.c index 1c99da4..d9474d9 100644 --- a/src/main.c +++ b/src/main.c @@ -80,8 +80,9 @@ coroutine void new_connection(int cd, struct state *state) return; } - /* Chop buf on \r\n. */ + const char **words = NULL; + /* Chop buf on \r\n. */ char *nl = memchr(buf, '\n', rbytes); if (nl == NULL) { goto parseerror; @@ -95,7 +96,10 @@ coroutine void new_connection(int cd, struct state *state) buf[nbytes - 1] = '\0'; buf[nbytes] = '\0'; - const char **words = parse_argv(buf, ' '); + words = parse_argv(buf, ' '); + if (argv_len(words) != 6) { + goto parseerror; + } if (strcasecmp(words[0], "PROXY") != 0) { goto parseerror; } @@ -123,8 +127,6 @@ coroutine void new_connection(int cd, struct state *state) goto parseerror; } - free(words); - char rstr[IPADDR_MAXSTRLEN + 7]; ipaddrstr_port(remote_addr, rstr); @@ -166,6 +168,7 @@ coroutine void new_connection(int cd, struct state *state) free(ch); disconnected: + free(words); fdclean(cd); close(cd); fdclean(rs); @@ -176,6 +179,7 @@ coroutine void new_connection(int cd, struct state *state) parseerror: printf("[?] %s broke with bad proxy-protocol header\n", lstr); + free(words); fdclean(cd); close(cd); return; diff --git a/src/mmproxy.h b/src/mmproxy.h index b1a8c80..066d938 100644 --- a/src/mmproxy.h +++ b/src/mmproxy.h @@ -49,6 +49,7 @@ int check_ip_rule(int ipv6, uint32_t mark, uint32_t table); int check_ip_route(int ipv6, uint32_t table); int set_nofile_max(); int read_subnets(const char *fname, network **ptr_networks, int *ptr_networks_len); +unsigned argv_len(const char **argv); /* net.c */ ipaddr ipaddr_parse(const char *addr, int noport); @@ -66,7 +67,6 @@ int net_find_match(network *networks, int networks_len, ipaddr addr); int ipport(ipaddr addr); - #ifndef IP_TRANSPARENT # define IP_TRANSPARENT 19 #endif