From: Ondřej Surý Date: Wed, 29 Apr 2026 16:20:03 +0000 (+0200) Subject: Use a keyed hash for the RRL bucket table X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0f821104e0a7fddaa3f79eaf01f0dbd456edf295;p=thirdparty%2Fbind9.git Use a keyed hash for the RRL bucket table The previous hash_key() was a deterministic, unkeyed (<<1) + add over the key words. An off-path attacker could invert it offline and submit queries whose source /24, qname hash, and qtype map to a single bucket; under chaining this turns every lookup into an O(N) walk under rrl->lock and starves legitimate query processing on the very feature deployed to mitigate DoS. Replace it with isc_hash32(), which is HalfSipHash-2-4 keyed by a per-process random seed, so collision sets cannot be precomputed. Assisted-by: Claude:claude-opus-4-7 (cherry picked from commit a6b7ce29c4cfab2ab1d46f48f21f531d5ffde942) --- diff --git a/lib/dns/rrl.c b/lib/dns/rrl.c index 4a6de0144a6..7ff79f87c7d 100644 --- a/lib/dns/rrl.c +++ b/lib/dns/rrl.c @@ -22,6 +22,8 @@ #include #include +#include +#include #include #include #include @@ -374,14 +376,12 @@ key_cmp(const dns_rrl_key_t *a, const dns_rrl_key_t *b) { static uint32_t hash_key(const dns_rrl_key_t *key) { - uint32_t hval; - int i; - - hval = key->w[0]; - for (i = sizeof(key->w) / sizeof(key->w[0]) - 1; i >= 0; --i) { - hval = key->w[i] + (hval << 1); - } - return hval; + /* + * The key includes attacker-controlled bits (client /24, qname + * hash, qtype). Use the keyed, per-process-randomised hash so + * collisions cannot be engineered to overload one bucket chain. + */ + return isc_hash32(key, sizeof(*key), true); } /*