mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 10:18:25 +00:00
Implement RFC6672 para 5.3.2. check for DNAME.
Also fix overflow checking of NSEC type maps.
This commit is contained in:
49
src/dnssec.c
49
src/dnssec.c
@@ -1254,6 +1254,7 @@ static int prove_non_existence_nsec(struct dns_header *header, size_t plen, unsi
|
|||||||
p += 8; /* class, type, TTL */
|
p += 8; /* class, type, TTL */
|
||||||
GETSHORT(rdlen, p);
|
GETSHORT(rdlen, p);
|
||||||
psave = p;
|
psave = p;
|
||||||
|
|
||||||
if (!extract_name(header, plen, &p, workspace2, EXTR_NAME_EXTRACT, 0))
|
if (!extract_name(header, plen, &p, workspace2, EXTR_NAME_EXTRACT, 0))
|
||||||
return DNSSEC_FAIL_BADPACKET;
|
return DNSSEC_FAIL_BADPACKET;
|
||||||
|
|
||||||
@@ -1276,7 +1277,22 @@ static int prove_non_existence_nsec(struct dns_header *header, size_t plen, unsi
|
|||||||
workspace1--;
|
workspace1--;
|
||||||
*workspace1 = '*';
|
*workspace1 = '*';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rdlen -= p - psave;
|
||||||
|
/* rdlen is now length of type map, and p points to it
|
||||||
|
packet checked to be as long as rdlen implies in prove_non_existence() */
|
||||||
|
|
||||||
|
/* check that the first typemap is complete. */
|
||||||
|
if (rdlen < 2 || rdlen < p[1] + 2)
|
||||||
|
return DNSSEC_FAIL_BADPACKET;
|
||||||
|
|
||||||
|
/* RFC 6672 5.3.4.1. */
|
||||||
|
#define DNAME_OFFSET (T_DNAME >> 3)
|
||||||
|
#define DNAME_MASK (0x80 >> (T_DNAME & 0x07))
|
||||||
|
if (p[0] == 0 && (p[1] >= DNAME_OFFSET + 1) && (p[2 + DNAME_OFFSET] & DNAME_MASK) != 0 &&
|
||||||
|
hostname_issubdomain(name, workspace1) == 1)
|
||||||
|
return DNSSEC_FAIL_NONSEC;
|
||||||
|
|
||||||
rc = hostname_cmp(workspace1, name);
|
rc = hostname_cmp(workspace1, name);
|
||||||
|
|
||||||
if (rc == 0)
|
if (rc == 0)
|
||||||
@@ -1287,16 +1303,12 @@ static int prove_non_existence_nsec(struct dns_header *header, size_t plen, unsi
|
|||||||
|
|
||||||
/* NSEC with the same name as the RR we're testing, check
|
/* NSEC with the same name as the RR we're testing, check
|
||||||
that the type in question doesn't appear in the type map */
|
that the type in question doesn't appear in the type map */
|
||||||
rdlen -= p - psave;
|
if (p[0] == 0 && p[1] >= 1)
|
||||||
/* rdlen is now length of type map, and p points to it
|
|
||||||
packet checked to be as long as rdlen implies in prove_non_existence() */
|
|
||||||
|
|
||||||
/* If we can prove that there's no NS record, return that information. */
|
|
||||||
if (nons && rdlen >= 2 && p[0] == 0 && (p[2] & (0x80 >> T_NS)) != 0)
|
|
||||||
*nons = 0;
|
|
||||||
|
|
||||||
if (rdlen >= 2 && p[0] == 0)
|
|
||||||
{
|
{
|
||||||
|
/* If we can prove that there's no NS record, return that information. */
|
||||||
|
if (nons && (p[2] & (0x80 >> T_NS)) != 0)
|
||||||
|
*nons = 0;
|
||||||
|
|
||||||
/* A CNAME answer would also be valid, so if there's a CNAME is should
|
/* A CNAME answer would also be valid, so if there's a CNAME is should
|
||||||
have been returned. */
|
have been returned. */
|
||||||
if ((p[2] & (0x80 >> T_CNAME)) != 0)
|
if ((p[2] & (0x80 >> T_CNAME)) != 0)
|
||||||
@@ -1308,10 +1320,10 @@ static int prove_non_existence_nsec(struct dns_header *header, size_t plen, unsi
|
|||||||
if (name_labels != 0 && type == T_DS && (p[2] & (0x80 >> T_SOA)) != 0)
|
if (name_labels != 0 && type == T_DS && (p[2] & (0x80 >> T_SOA)) != 0)
|
||||||
return DNSSEC_FAIL_NONSEC;
|
return DNSSEC_FAIL_NONSEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (rdlen >= 2)
|
while (rdlen > 0)
|
||||||
{
|
{
|
||||||
if (!CHECK_LEN(header, p, plen, rdlen))
|
if (rdlen < 2 || rdlen < p[1] + 2)
|
||||||
return DNSSEC_FAIL_BADPACKET;
|
return DNSSEC_FAIL_BADPACKET;
|
||||||
|
|
||||||
if (p[0] == type >> 8)
|
if (p[0] == type >> 8)
|
||||||
@@ -1451,7 +1463,11 @@ static int check_nsec3_coverage(struct dns_header *header, size_t plen, int dige
|
|||||||
p += hash_len; /* skip next-domain hash */
|
p += hash_len; /* skip next-domain hash */
|
||||||
rdlen -= p - psave;
|
rdlen -= p - psave;
|
||||||
|
|
||||||
if (rdlen >= 2 && p[0] == 0)
|
/* check that the first typemap is complete. */
|
||||||
|
if (rdlen < 2 || rdlen < p[1] + 2)
|
||||||
|
return DNSSEC_FAIL_BADPACKET;
|
||||||
|
|
||||||
|
if (p[0] == 0 && p[1] >= 1)
|
||||||
{
|
{
|
||||||
/* If we can prove that there's no NS record, return that information. */
|
/* If we can prove that there's no NS record, return that information. */
|
||||||
if (nons && (p[2] & (0x80 >> T_NS)) != 0)
|
if (nons && (p[2] & (0x80 >> T_NS)) != 0)
|
||||||
@@ -1469,8 +1485,11 @@ static int check_nsec3_coverage(struct dns_header *header, size_t plen, int dige
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (rdlen >= 2)
|
while (rdlen > 0)
|
||||||
{
|
{
|
||||||
|
if (rdlen < 2 || rdlen < p[1] + 2)
|
||||||
|
return DNSSEC_FAIL_BADPACKET;
|
||||||
|
|
||||||
if (p[0] == type >> 8)
|
if (p[0] == type >> 8)
|
||||||
{
|
{
|
||||||
/* Does the NSEC3 say our type exists? */
|
/* Does the NSEC3 say our type exists? */
|
||||||
|
|||||||
Reference in New Issue
Block a user