From 5d07d77e75e0f02bc0a8f6029ffbc8b371fa804e Mon Sep 17 00:00:00 2001 From: Simon Kelley Date: Fri, 15 May 2015 18:13:06 +0100 Subject: [PATCH] Fix buffer overflow introduced in 2.73rc6. Fix off-by-one in code which checks for over-long domain names in received DNS packets. This enables buffer overflow attacks which can certainly crash dnsmasq and may allow for arbitrary code execution. The problem was introduced in commit b8f16556d, release 2.73rc6, so has not escaped into any stable release. Note that the off-by-one was in the label length determination, so the buffer can be overflowed by as many bytes as there are labels in the name - ie, many. Thanks to Ron Bowes, who used lcmatuf's afl-fuzz tool to find the problem. --- src/rfc1035.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/rfc1035.c b/src/rfc1035.c index 5e3f566..a95241f 100644 --- a/src/rfc1035.c +++ b/src/rfc1035.c @@ -94,8 +94,8 @@ int extract_name(struct dns_header *header, size_t plen, unsigned char **pp, count = 256; digs = ((count-1)>>2)+1; - /* output is \[x/siz]. which is digs+6/7/8 chars */ - namelen += digs+6; + /* output is \[x/siz]. which is digs+7/8/9 chars */ + namelen += digs+7; if (count > 9) namelen++; if (count > 99) @@ -125,8 +125,8 @@ int extract_name(struct dns_header *header, size_t plen, unsigned char **pp, } else { /* label_type = 0 -> label. */ - namelen += l; - if (namelen+1 >= MAXDNAME) + namelen += l + 1; /* include period */ + if (namelen >= MAXDNAME) return 0; if (!CHECK_LEN(header, p, plen, l)) return 0; -- 2.39.2