From: Diego Fronza Date: Wed, 27 Jan 2021 22:09:46 +0000 (-0300) Subject: Fix race condition on check_stale_header X-Git-Tag: v9.17.10~13^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c75575e350684ba2c3603462f654f9897e162be3;p=thirdparty%2Fbind9.git Fix race condition on check_stale_header This commit fix a race that could happen when two or more threads have failed to refresh the same RRset, the threads could simultaneously attempt to update the header->last_refresh_fail_ts field in check_stale_header, a field used to implement stale-refresh-time. By making this field atomic we avoid such race. --- diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index 83f6e30c7c2..26fab2df04f 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -205,7 +205,7 @@ typedef struct rdatasetheader { rbtdb_rdatatype_t type; atomic_uint_least16_t attributes; dns_trust_t trust; - isc_stdtime_t last_refresh_fail_ts; + atomic_uint_fast32_t last_refresh_fail_ts; struct noqname *noqname; struct noqname *closest; unsigned int is_mmapped : 1; @@ -1487,6 +1487,7 @@ init_rdataset(dns_rbtdb_t *rbtdb, rdatasetheader_t *h) { h->next_is_relative = 0; h->node_is_relative = 0; atomic_init(&h->attributes, 0); + atomic_init(&h->last_refresh_fail_ts, 0); #ifndef ISC_MUTEX_ATOMICS STATIC_ASSERT((sizeof(h->attributes) == 2), @@ -4571,11 +4572,14 @@ check_stale_header(dns_rbtnode_t *node, rdatasetheader_t *header, * failed. */ if ((search->options & DNS_DBFIND_STALESTART) != 0) { - header->last_refresh_fail_ts = search->now; + atomic_store_release( + &header->last_refresh_fail_ts, + search->now); } else if ((search->options & DNS_DBFIND_STALEENABLED) != 0 && search->now < - (header->last_refresh_fail_ts + + (atomic_load_acquire( + &header->last_refresh_fail_ts) + search->rbtdb->serve_stale_refresh)) { /*