]> git.ipfire.org Git - people/ms/dnsmasq.git/commitdiff
Fix buffer overflow introduced in 2.73rc6.
authorSimon Kelley <simon@thekelleys.org.uk>
Fri, 15 May 2015 17:13:06 +0000 (18:13 +0100)
committerSimon Kelley <simon@thekelleys.org.uk>
Fri, 15 May 2015 17:13:06 +0000 (18:13 +0100)
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

index 5e3f566fdbc522f60f067880c70788b18f3b2523..a95241f83523c0c5c1c31da79991bcbfbf879ff8 100644 (file)
@@ -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<hex>/siz]. which is digs+6/7/8 chars */
-         namelen += digs+6;
+         /* output is \[x<hex>/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;