* Exim - an Internet mail transport agent *
*************************************************/
+/* Copyright (c) The Exim Maintainers 2020 - 2022 */
/* Copyright (c) University of Cambridge 1995 - 2018 */
-/* Copyright (c) The Exim Maintainers 2020 - 2021 */
/* See the file NOTICE for conditions of use and distribution. */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
/* Functions for interfacing with the DNS. */
static BOOL
dnss_inc_aptr(const dns_answer * dnsa, dns_scan * dnss, unsigned delta)
{
-return (dnss->aptr += delta) >= dnsa->answer + dnsa->answerlen;
+return (dnss->aptr += delta) > dnsa->answer + dnsa->answerlen;
}
/*************************************************
TRACE trace = "A-hdr";
if (dnss_inc_aptr(dnsa, dnss, namelen+8)) goto null_return;
GETSHORT(dnss->srr.size, dnss->aptr); /* size of data portion */
- /* skip over it */
+ /* skip over it, checking for a bogus size */
TRACE trace = "A-skip";
if (dnss_inc_aptr(dnsa, dnss, dnss->srr.size)) goto null_return;
}
GETSHORT(dnss->srr.size, dnss->aptr); /* Size of data portion */
dnss->srr.data = dnss->aptr; /* The record's data follows */
-/* Unchecked increment ok here since no further access on this iteration;
-will be checked on next at "R-name". */
-
-dnss->aptr += dnss->srr.size; /* Advance to next RR */
+/* skip over it, checking for a bogus size */
+if (dnss_inc_aptr(dnsa, dnss, dnss->srr.size))
+ goto null_return;
/* Return a pointer to the dns_record structure within the dns_answer. This is
for convenience so that the scans can use nice-looking for loops. */
int rc;
#ifndef STAND_ALONE
const uschar * save_domain;
+static BOOL try_again_recursion = FALSE;
#endif
/* DNS lookup failures of any kind are cached in a tree. This is mainly so that
/* Cut this out for various test programs */
#ifndef STAND_ALONE
- save_domain = deliver_domain;
- deliver_domain = string_copy(name); /* set $domain */
- rc = match_isinlist(name, CUSS &dns_again_means_nonexist, 0,
- &domainlist_anchor, NULL, MCL_DOMAIN, TRUE, NULL);
- deliver_domain = save_domain;
+ /* Permitting dns_again_means nonexist for TLSA lookups breaks the
+ doewngrade resistance of dane, so avoid for those. */
+
+ if (type == T_TLSA)
+ rc = FAIL;
+ else
+ {
+ if (try_again_recursion)
+ {
+ log_write(0, LOG_MAIN|LOG_PANIC,
+ "dns_again_means_nonexist recursion seen for %s"
+ " (assuming nonexist)", name);
+ return dns_fail_return(name, type, dns_expire_from_soa(dnsa, type),
+ DNS_NOMATCH);
+ }
+
+ try_again_recursion = TRUE;
+ save_domain = deliver_domain;
+ deliver_domain = string_copy(name); /* set $domain */
+ rc = match_isinlist(name, CUSS &dns_again_means_nonexist, 0,
+ &domainlist_anchor, NULL, MCL_DOMAIN, TRUE, NULL);
+ deliver_domain = save_domain;
+ try_again_recursion = FALSE;
+ }
+
if (rc != OK)
{
DEBUG(D_dns) debug_printf("returning DNS_AGAIN\n");
{
if (check_dns_names_pattern[0] != 0 && !regex_check_dns_names)
regex_check_dns_names =
- regex_must_compile(check_dns_names_pattern, FALSE, TRUE);
+ regex_must_compile(check_dns_names_pattern, MCS_NOFLAGS, TRUE);
}
/* vi: aw ai sw=2