[9.20] fix: Address potential TSAN issue with find->status

find->status is a private field of dns_adbfind_t so it now has an accessor function and has been made atomic.

Closes #4802

Backport of MR !9137

Merge branch 'backport-4802-address-potential-tsan-issue-with-find-status-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!9433
This commit is contained in:
Mark Andrews 2024-09-02 05:27:56 +00:00
commit 4f01e8d33c
3 changed files with 30 additions and 13 deletions

View file

@ -937,7 +937,7 @@ clean_finds_at_name(dns_adbname_t *name, dns_adbstatus_t astat,
INSIST(!FIND_EVENTSENT(find));
find->status = astat;
atomic_store(&find->status, astat);
DP(DEF_LEVEL, "cfan: sending find %p to caller", find);
@ -2225,7 +2225,7 @@ post_copy:
if (want_event) {
INSIST((find->flags & DNS_ADBFIND_ADDRESSMASK) != 0);
find->loop = loop;
find->status = DNS_ADB_UNSET;
atomic_store(&find->status, DNS_ADB_UNSET);
find->cb = cb;
find->cbarg = cbarg;
}
@ -2279,7 +2279,7 @@ dns_adb_destroyfind(dns_adbfind_t **findp) {
static void
find_sendevent(dns_adbfind_t *find) {
if (!FIND_EVENTSENT(find)) {
find->status = DNS_ADB_CANCELED;
atomic_store(&find->status, DNS_ADB_CANCELED);
DP(DEF_LEVEL, "sending find %p to caller", find);
@ -2324,6 +2324,13 @@ dns_adb_cancelfind(dns_adbfind_t *find) {
}
}
unsigned int
dns_adb_findstatus(dns_adbfind_t *find) {
REQUIRE(DNS_ADBFIND_VALID(find));
return (atomic_load(&find->status));
}
void
dns_adb_dump(dns_adb_t *adb, FILE *f) {
isc_stdtime_t now = isc_stdtime_now();

View file

@ -121,15 +121,15 @@ struct dns_adbfind {
ISC_LINK(dns_adbfind_t) publink; /*%< RW: client use */
/* Private */
isc_mutex_t lock; /* locks all below */
in_port_t port;
unsigned int flags;
dns_adbname_t *adbname;
dns_adb_t *adb;
isc_loop_t *loop;
dns_adbstatus_t status;
isc_job_cb cb;
void *cbarg;
isc_mutex_t lock; /* locks all below */
in_port_t port;
unsigned int flags;
dns_adbname_t *adbname;
dns_adb_t *adb;
isc_loop_t *loop;
_Atomic(dns_adbstatus_t) status;
isc_job_cb cb;
void *cbarg;
ISC_LINK(dns_adbfind_t) plink;
};
@ -387,6 +387,16 @@ dns_adbfind_done(dns_adbfind_t find);
*\li 'find' != NULL and *find be valid dns_adbfind_t pointer.
*/
unsigned int
dns_adb_findstatus(dns_adbfind_t *);
/*%<
* Returns the status field of the find.
*
* Requires:
*
*\li 'find' be a valid dns_adbfind_t pointer.
*/
void
dns_adb_destroyfind(dns_adbfind_t **find);
/*%<

View file

@ -2910,7 +2910,7 @@ fctx_finddone(void *arg) {
* The fetch is waiting for a name to be found.
*/
INSIST(!SHUTTINGDOWN(fctx));
if (find->status == DNS_ADB_MOREADDRESSES) {
if (dns_adb_findstatus(find) == DNS_ADB_MOREADDRESSES) {
FCTX_ATTR_CLR(fctx, FCTX_ATTR_ADDRWAIT);
want_try = true;
} else {