From fdcc9ab427f8deb73a4b5603ec2cb5233ec8bd78 Mon Sep 17 00:00:00 2001 From: Deyan Doychev Date: Fri, 17 Oct 2025 14:37:32 +0300 Subject: [PATCH] authoritative: Prevent a potential race condition in cache cleaning Clean query cache before cleaning packet cache. Otherwise the following situation is possible: * thread A cleans packet cache * thread B answers a question for the same name that is being cleaned by A * since there is no packet cache it populates a packet cache entry from the query cache (which has not yet been cleaned by thread A * thread A cleans query cache * the server will return the old packet cache entry until its TTL expires or cache is cleaned again Switching which cache is cleaned first fixes this race condition. Signed-off-by: Deyan Doychev --- pdns/auth-caches.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/pdns/auth-caches.cc b/pdns/auth-caches.cc index 4fd75bb74a..580d4dde67 100644 --- a/pdns/auth-caches.cc +++ b/pdns/auth-caches.cc @@ -31,8 +31,9 @@ extern AuthQueryCache QC; uint64_t purgeAuthCaches() { uint64_t ret = 0; - ret += PC.purge(); + /* Clean query cache before packet cache to avoid potential race condition */ ret += QC.purge(); + ret += PC.purge(); return ret; } @@ -40,8 +41,9 @@ uint64_t purgeAuthCaches() uint64_t purgeAuthCaches(const std::string& match) { uint64_t ret = 0; - ret += PC.purge(match); + /* Clean query cache before packet cache to avoid potential race condition */ ret += QC.purge(match); + ret += PC.purge(match); return ret; } @@ -49,8 +51,9 @@ uint64_t purgeAuthCaches(const std::string& match) uint64_t purgeAuthCachesExact(const DNSName& qname) { uint64_t ret = 0; - ret += PC.purgeExact(qname); + /* Clean query cache before packet cache to avoid potential race condition */ ret += QC.purgeExact(qname); + ret += PC.purgeExact(qname); return ret; } -- 2.47.3