mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 18:28:25 +00:00
Fix crash in DNSSEC code when attempting to verify large RRs.
This commit is contained in:
@@ -19,6 +19,9 @@ version 2.73
|
|||||||
the answers given by --interface-name. Note that reverse queries
|
the answers given by --interface-name. Note that reverse queries
|
||||||
(ie looking for names, given addresses) are not affected.
|
(ie looking for names, given addresses) are not affected.
|
||||||
Thanks to Michael Gorbach for the suggestion.
|
Thanks to Michael Gorbach for the suggestion.
|
||||||
|
|
||||||
|
Fix crash in DNSSEC code with long RRs. Thanks to Marco Davids
|
||||||
|
for the bug report.
|
||||||
|
|
||||||
|
|
||||||
version 2.72
|
version 2.72
|
||||||
|
|||||||
27
src/dnssec.c
27
src/dnssec.c
@@ -456,16 +456,27 @@ static u16 *get_desc(int type)
|
|||||||
|
|
||||||
/* Return bytes of canonicalised rdata, when the return value is zero, the remaining
|
/* Return bytes of canonicalised rdata, when the return value is zero, the remaining
|
||||||
data, pointed to by *p, should be used raw. */
|
data, pointed to by *p, should be used raw. */
|
||||||
static int get_rdata(struct dns_header *header, size_t plen, unsigned char *end, char *buff,
|
static int get_rdata(struct dns_header *header, size_t plen, unsigned char *end, char *buff, int bufflen,
|
||||||
unsigned char **p, u16 **desc)
|
unsigned char **p, u16 **desc)
|
||||||
{
|
{
|
||||||
int d = **desc;
|
int d = **desc;
|
||||||
|
|
||||||
(*desc)++;
|
|
||||||
|
|
||||||
/* No more data needs mangling */
|
/* No more data needs mangling */
|
||||||
if (d == (u16)-1)
|
if (d == (u16)-1)
|
||||||
return 0;
|
{
|
||||||
|
/* If there's more data than we have space for, just return what fits,
|
||||||
|
we'll get called again for more chunks */
|
||||||
|
if (end - *p > bufflen)
|
||||||
|
{
|
||||||
|
memcpy(buff, *p, bufflen);
|
||||||
|
*p += bufflen;
|
||||||
|
return bufflen;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
(*desc)++;
|
||||||
|
|
||||||
if (d == 0 && extract_name(header, plen, p, buff, 1, 0))
|
if (d == 0 && extract_name(header, plen, p, buff, 1, 0))
|
||||||
/* domain-name, canonicalise */
|
/* domain-name, canonicalise */
|
||||||
@@ -560,7 +571,7 @@ static void sort_rrset(struct dns_header *header, size_t plen, u16 *rr_desc, int
|
|||||||
if (left1 != 0)
|
if (left1 != 0)
|
||||||
memmove(buff1, buff1 + len1 - left1, left1);
|
memmove(buff1, buff1 + len1 - left1, left1);
|
||||||
|
|
||||||
if ((len1 = get_rdata(header, plen, end1, buff1 + left1, &p1, &dp1)) == 0)
|
if ((len1 = get_rdata(header, plen, end1, buff1 + left1, MAXDNAME - left1, &p1, &dp1)) == 0)
|
||||||
{
|
{
|
||||||
quit = 1;
|
quit = 1;
|
||||||
len1 = end1 - p1;
|
len1 = end1 - p1;
|
||||||
@@ -571,7 +582,7 @@ static void sort_rrset(struct dns_header *header, size_t plen, u16 *rr_desc, int
|
|||||||
if (left2 != 0)
|
if (left2 != 0)
|
||||||
memmove(buff2, buff2 + len2 - left2, left2);
|
memmove(buff2, buff2 + len2 - left2, left2);
|
||||||
|
|
||||||
if ((len2 = get_rdata(header, plen, end2, buff2 + left2, &p2, &dp2)) == 0)
|
if ((len2 = get_rdata(header, plen, end2, buff2 + left2, MAXDNAME - left2, &p2, &dp2)) == 0)
|
||||||
{
|
{
|
||||||
quit = 1;
|
quit = 1;
|
||||||
len2 = end2 - p2;
|
len2 = end2 - p2;
|
||||||
@@ -808,7 +819,7 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
|
|||||||
/* canonicalise rdata and calculate length of same, use name buffer as workspace */
|
/* canonicalise rdata and calculate length of same, use name buffer as workspace */
|
||||||
cp = p;
|
cp = p;
|
||||||
dp = rr_desc;
|
dp = rr_desc;
|
||||||
for (len = 0; (seg = get_rdata(header, plen, end, name, &cp, &dp)) != 0; len += seg);
|
for (len = 0; (seg = get_rdata(header, plen, end, name, MAXDNAME, &cp, &dp)) != 0; len += seg);
|
||||||
len += end - cp;
|
len += end - cp;
|
||||||
len = htons(len);
|
len = htons(len);
|
||||||
hash->update(ctx, 2, (unsigned char *)&len);
|
hash->update(ctx, 2, (unsigned char *)&len);
|
||||||
@@ -816,7 +827,7 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
|
|||||||
/* Now canonicalise again and digest. */
|
/* Now canonicalise again and digest. */
|
||||||
cp = p;
|
cp = p;
|
||||||
dp = rr_desc;
|
dp = rr_desc;
|
||||||
while ((seg = get_rdata(header, plen, end, name, &cp, &dp)))
|
while ((seg = get_rdata(header, plen, end, name, MAXDNAME, &cp, &dp)))
|
||||||
hash->update(ctx, seg, (unsigned char *)name);
|
hash->update(ctx, seg, (unsigned char *)name);
|
||||||
if (cp != end)
|
if (cp != end)
|
||||||
hash->update(ctx, end - cp, cp);
|
hash->update(ctx, end - cp, cp);
|
||||||
|
|||||||
Reference in New Issue
Block a user