mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 18:28:25 +00:00
Fix erroneous "DNSSEC validated" state with non-DNSSEC upstream servers.
When DNSEC validation is enabled, but a query is not validated because it gets forwarded to a non-DNSEC-capable upstream server, the rr_status array is not correctly cleared, with the effect that the answer may be maked as DNSSEC validated if the immediately preceding query was DNS signed and validated.
This commit is contained in:
@@ -72,6 +72,9 @@ version 2.91
|
|||||||
a DHCP relay. This change allows dnsmasq to act as both a
|
a DHCP relay. This change allows dnsmasq to act as both a
|
||||||
PXE proxy-DHCP server AND a DHCP relay for the same network.
|
PXE proxy-DHCP server AND a DHCP relay for the same network.
|
||||||
|
|
||||||
|
Fix erroneous "DNSSEC validated" state with non-DNSSEC
|
||||||
|
upstream servers. Thanks to Dominik Derigs for the bug report.
|
||||||
|
|
||||||
|
|
||||||
version 2.90
|
version 2.90
|
||||||
Fix reversion in --rev-server introduced in 2.88 which
|
Fix reversion in --rev-server introduced in 2.88 which
|
||||||
|
|||||||
@@ -1220,10 +1220,15 @@ void reply_query(int fd, time_t now)
|
|||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_DNSSEC
|
#ifdef HAVE_DNSSEC
|
||||||
|
if (option_bool(OPT_DNSSEC_VALID))
|
||||||
|
{
|
||||||
|
/* Clear this in case we don't call dnssec_validate() below */
|
||||||
|
memset(daemon->rr_status, 0, sizeof(*daemon->rr_status) * daemon->rr_status_sz);
|
||||||
|
|
||||||
if ((forward->sentto->flags & SERV_DO_DNSSEC) &&
|
if ((forward->sentto->flags & SERV_DO_DNSSEC) &&
|
||||||
option_bool(OPT_DNSSEC_VALID) &&
|
|
||||||
!(forward->flags & FREC_CHECKING_DISABLED))
|
!(forward->flags & FREC_CHECKING_DISABLED))
|
||||||
dnssec_validate(forward, header, n, STAT_OK, now);
|
dnssec_validate(forward, header, n, STAT_OK, now);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
return_reply(now, forward, header, n, STAT_OK);
|
return_reply(now, forward, header, n, STAT_OK);
|
||||||
@@ -2491,7 +2496,12 @@ unsigned char *tcp_request(int confd, time_t now,
|
|||||||
log_query_mysockaddr(F_SERVER | F_FORWARD, daemon->namebuff, &serv->addr, NULL, 0);
|
log_query_mysockaddr(F_SERVER | F_FORWARD, daemon->namebuff, &serv->addr, NULL, 0);
|
||||||
|
|
||||||
#ifdef HAVE_DNSSEC
|
#ifdef HAVE_DNSSEC
|
||||||
if (option_bool(OPT_DNSSEC_VALID) && !checking_disabled && (master->flags & SERV_DO_DNSSEC))
|
if (option_bool(OPT_DNSSEC_VALID))
|
||||||
|
{
|
||||||
|
/* Clear this in case we don't call tcp_key_recurse() below */
|
||||||
|
memset(daemon->rr_status, 0, sizeof(*daemon->rr_status) * daemon->rr_status_sz);
|
||||||
|
|
||||||
|
if (!checking_disabled && (master->flags & SERV_DO_DNSSEC))
|
||||||
{
|
{
|
||||||
int keycount = daemon->limit[LIMIT_WORK]; /* Limit to number of DNSSEC questions, to catch loops and avoid filling cache. */
|
int keycount = daemon->limit[LIMIT_WORK]; /* Limit to number of DNSSEC questions, to catch loops and avoid filling cache. */
|
||||||
int validatecount = daemon->limit[LIMIT_CRYPTO];
|
int validatecount = daemon->limit[LIMIT_CRYPTO];
|
||||||
@@ -2532,6 +2542,7 @@ unsigned char *tcp_request(int confd, time_t now,
|
|||||||
/* include DNSSEC queries in the limit for a connection. */
|
/* include DNSSEC queries in the limit for a connection. */
|
||||||
query_count += daemon->limit[LIMIT_WORK] - keycount;
|
query_count += daemon->limit[LIMIT_WORK] - keycount;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* restore CD bit to the value in the query */
|
/* restore CD bit to the value in the query */
|
||||||
|
|||||||
@@ -706,7 +706,7 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
|
|||||||
if (aqclass == C_IN && res != 2 && (aqtype == T_CNAME || aqtype == T_PTR))
|
if (aqclass == C_IN && res != 2 && (aqtype == T_CNAME || aqtype == T_PTR))
|
||||||
{
|
{
|
||||||
#ifdef HAVE_DNSSEC
|
#ifdef HAVE_DNSSEC
|
||||||
if (option_bool(OPT_DNSSEC_VALID) && daemon->rr_status[j] != 0)
|
if (option_bool(OPT_DNSSEC_VALID) && j < daemon->rr_status_sz && daemon->rr_status[j] != 0)
|
||||||
{
|
{
|
||||||
/* validated RR anywhere in CNAME chain, don't cache. */
|
/* validated RR anywhere in CNAME chain, don't cache. */
|
||||||
if (cname_short || aqtype == T_CNAME)
|
if (cname_short || aqtype == T_CNAME)
|
||||||
@@ -825,7 +825,7 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_DNSSEC
|
#ifdef HAVE_DNSSEC
|
||||||
if (option_bool(OPT_DNSSEC_VALID) && daemon->rr_status[j] != 0)
|
if (option_bool(OPT_DNSSEC_VALID) && j < daemon->rr_status_sz && daemon->rr_status[j] != 0)
|
||||||
{
|
{
|
||||||
secflag = F_DNSSECOK;
|
secflag = F_DNSSECOK;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user