+3555. [bug] Address theoretical race conditions in acache.c
+ (change #3553 was incomplete). [RT #33252]
+
3553. [bug] Address suspected double free in acache. [RT #33252]
3552. [bug] Wrong getopt option string for 'nsupdate -r'.
if (entry != NULL) {
/*
* If we are still in the overmem
- * state, keep cleaning.
+ * state, keep cleaning. In case we
+ * exit from the loop immediately after
+ * this, reset next to the head entry
+ * as we'll expect it will be never
+ * NULL.
*/
isc_log_write(dns_lctx,
DNS_LOGCATEGORY_DATABASE,
"acache cleaner: "
"still overmem, "
"reset and try again");
+ next = entry;
continue;
}
}
* be the starting point in the next clean-up, and reschedule another
* batch. If it fails, just try to continue anyway.
*/
- INSIST(next != NULL && next != cleaner->current_entry);
+ INSIST(next != NULL);
dns_acache_detachentry(&cleaner->current_entry);
dns_acache_attachentry(next, &cleaner->current_entry);
return (result);
}
-void
+isc_boolean_t
dns_acache_cancelentry(dns_acacheentry_t *entry) {
- dns_acache_t *acache = entry->acache;
+ dns_acache_t *acache;
+ isc_boolean_t callback_active;
REQUIRE(DNS_ACACHEENTRY_VALID(entry));
- INSIST(DNS_ACACHE_VALID(acache));
+
+ acache = entry->acache;
+ callback_active = ISC_TF(entry->cbarg != NULL);
+
+ INSIST(DNS_ACACHE_VALID(entry->acache));
LOCK(&acache->lock);
ACACHE_LOCK(&acache->entrylocks[entry->locknum], isc_rwlocktype_write);
ACACHE_UNLOCK(&acache->entrylocks[entry->locknum],
isc_rwlocktype_write);
UNLOCK(&acache->lock);
+
+ return (callback_active);
}
void
cbarg = *cbargp;
- dns_acache_cancelentry(entry);
- dns_db_detachnode(cbarg->db, &cbarg->node);
- dns_db_detach(&cbarg->db);
+ if (dns_acache_cancelentry(entry)) {
+ dns_db_detachnode(cbarg->db, &cbarg->node);
+ dns_db_detach(&cbarg->db);
+ }
isc_mem_put(mctx, cbarg, sizeof(acache_cbarg_t));