From: Otto Moerbeek Date: Thu, 16 Mar 2023 15:08:56 +0000 (+0100) Subject: Sanitize d_orig_ttl X-Git-Tag: rec-4.9.0-beta1~2^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b29a61b140510aa3c40d203e894fb0171dc0b7ab;p=thirdparty%2Fpdns.git Sanitize d_orig_ttl The computed orig_ttl can be wrong if d_now.tv_sec is more recent than the d_now.tv_sec the ttd was computed from. This can happen if we went out to get e.g. keys and that took time. d_orig_ttl wraps around in that case if the TTL value was smaller than that delay. Work around that and make sure d_orig_ttl is within the legal range. --- diff --git a/pdns/recursordist/recursor_cache.cc b/pdns/recursordist/recursor_cache.cc index 4c95c052c5..c32364c40d 100644 --- a/pdns/recursordist/recursor_cache.cc +++ b/pdns/recursordist/recursor_cache.cc @@ -607,7 +607,19 @@ void MemRecursorCache::replace(time_t now, const DNSName& qname, const QType qt, /* Yes, we have altered the d_ttl value by adding time(nullptr) to it prior to calling this function, so the TTL actually holds a TTD. */ ce.d_ttd = min(maxTTD, static_cast(i.d_ttl)); // XXX this does weird things if TTLs differ in the set + ce.d_orig_ttl = ce.d_ttd - now; + + // d_orig_ttl should be between s_minimumTTL and s_maxcachettl, as d_ttd was sanitized wrt those + // bounds. But our reference point (d_now aka now) might be "too new" at this point, if we went + // outside to e.g. get DNSKEYS and that took a while. In that case, if the original TTL was + // smaller than the delay, d_orig_ttl will wrap and become very large. Detect that case and + // make sure d_orig_ttl is fixed. Likewise if there was a delay but that was smaller than the + // original TTL, d_orig_ttl can become smaller than s_minimumTTL. Detect those cases and use a + // small but legal d_orig_ttl in those cases. + if (ce.d_orig_ttl < SyncRes::s_minimumTTL || ce.d_orig_ttl > SyncRes::s_maxcachettl) { + ce.d_orig_ttl = SyncRes::s_minimumTTL; + } ce.d_records.push_back(i.getContent()); }