From 0c219be3dffa85b936048cc6b0ca45f3cf684d23 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Tue, 22 Aug 2017 12:01:26 +0200 Subject: [PATCH] BUG/MEDIUM: dns: fix accepted_payload_size parser to avoid integer overflow Since commit 9d8dbbc ("MINOR: dns: Maximum DNS udp payload set to 8192") it's possible to specify a packet size, but passing too large a size or a negative size is not detected and results in memset() being performed over a 2GB+ area upon receipt of the first DNS response, causing runtime crashes. We now check that the size is not smaller than the smallest packet which is the DNS header size (12 bytes). No backport is needed. --- include/types/dns.h | 2 +- src/cfgparse.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/types/dns.h b/include/types/dns.h index c7338c792..06e014c08 100644 --- a/include/types/dns.h +++ b/include/types/dns.h @@ -82,7 +82,7 @@ #define SRV_MAX_PREF_NET 5 /* DNS header size */ -#define DNS_HEADER_SIZE sizeof(struct dns_header) +#define DNS_HEADER_SIZE ((int)sizeof(struct dns_header)) /* DNS resolution pool size, per resolvers section */ #define DNS_DEFAULT_RESOLUTION_POOL_SIZE 64 diff --git a/src/cfgparse.c b/src/cfgparse.c index e69a4ab78..850160f6e 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -2304,9 +2304,9 @@ int cfg_parse_resolvers(const char *file, int linenum, char **args, int kwm) } i = atoi(args[1]); - if (i > DNS_MAX_UDP_MESSAGE) { - Alert("parsing [%s:%d] : '%s' size %d exceeds maximum allowed size %d.\n", - file, linenum, args[0], i, DNS_MAX_UDP_MESSAGE); + if (i < DNS_HEADER_SIZE || i > DNS_MAX_UDP_MESSAGE) { + Alert("parsing [%s:%d] : '%s' must be between %d and %d inclusive (was %s).\n", + file, linenum, args[0], DNS_HEADER_SIZE, DNS_MAX_UDP_MESSAGE, args[1]); err_code |= ERR_ALERT | ERR_FATAL; goto out; }