mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 14:35:26 +00:00
[master] fix LOADPENDING issues
4063. [bug] Asynchronous zone loads were not handled correctly when the zone load was already in progress; this could trigger a crash in zt.c. [RT #37573]
This commit is contained in:
5
CHANGES
5
CHANGES
@@ -1,3 +1,8 @@
|
|||||||
|
4063. [bug] Asynchronous zone loads were not handled
|
||||||
|
correctly when the zone load was already in
|
||||||
|
progress; this could trigger a crash in zt.c.
|
||||||
|
[RT #37573]
|
||||||
|
|
||||||
4062. [bug] Fix an out-of-bounds read in RPZ code. If the
|
4062. [bug] Fix an out-of-bounds read in RPZ code. If the
|
||||||
read succeeded, it doesn't result in a bug
|
read succeeded, it doesn't result in a bug
|
||||||
during operation. If the read failed, named
|
during operation. If the read failed, named
|
||||||
|
@@ -537,6 +537,13 @@
|
|||||||
information. [RT #38458]
|
information. [RT #38458]
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Asynchronous zone loads were not handled correctly when the
|
||||||
|
zone load was already in progress; this could trigger a crash
|
||||||
|
in zt.c. [RT #37573]
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</sect2>
|
</sect2>
|
||||||
<sect2 id="end_of_life">
|
<sect2 id="end_of_life">
|
||||||
|
@@ -370,6 +370,15 @@ dns_zone_asyncload(dns_zone_t *zone, dns_zt_zoneloaded_t done, void *arg);
|
|||||||
* its first argument and 'zone' as its second. (Normally, 'arg' is
|
* its first argument and 'zone' as its second. (Normally, 'arg' is
|
||||||
* expected to point to the zone table but is left undefined for testing
|
* expected to point to the zone table but is left undefined for testing
|
||||||
* purposes.)
|
* purposes.)
|
||||||
|
*
|
||||||
|
* Require:
|
||||||
|
*\li 'zone' to be a valid zone.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
*\li #ISC_R_ALREADYRUNNING
|
||||||
|
*\li #ISC_R_SUCCESS
|
||||||
|
*\li #ISC_R_FAILURE
|
||||||
|
*\li #ISC_R_NOMEMORY
|
||||||
*/
|
*/
|
||||||
|
|
||||||
isc_boolean_t
|
isc_boolean_t
|
||||||
|
@@ -1757,7 +1757,7 @@ zone_touched(dns_zone_t *zone) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
zone_load(dns_zone_t *zone, unsigned int flags) {
|
zone_load(dns_zone_t *zone, unsigned int flags, isc_boolean_t locked) {
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
isc_time_t now;
|
isc_time_t now;
|
||||||
isc_time_t loadtime;
|
isc_time_t loadtime;
|
||||||
@@ -1766,12 +1766,15 @@ zone_load(dns_zone_t *zone, unsigned int flags) {
|
|||||||
|
|
||||||
REQUIRE(DNS_ZONE_VALID(zone));
|
REQUIRE(DNS_ZONE_VALID(zone));
|
||||||
|
|
||||||
|
if (!locked)
|
||||||
LOCK_ZONE(zone);
|
LOCK_ZONE(zone);
|
||||||
|
|
||||||
INSIST(zone != zone->raw);
|
INSIST(zone != zone->raw);
|
||||||
hasraw = inline_secure(zone);
|
hasraw = inline_secure(zone);
|
||||||
if (hasraw) {
|
if (hasraw) {
|
||||||
result = zone_load(zone->raw, flags);
|
result = zone_load(zone->raw, flags, ISC_FALSE);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
|
if (!locked)
|
||||||
UNLOCK_ZONE(zone);
|
UNLOCK_ZONE(zone);
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
@@ -1981,6 +1984,7 @@ zone_load(dns_zone_t *zone, unsigned int flags) {
|
|||||||
cleanup:
|
cleanup:
|
||||||
if (hasraw)
|
if (hasraw)
|
||||||
UNLOCK_ZONE(zone->raw);
|
UNLOCK_ZONE(zone->raw);
|
||||||
|
if (!locked)
|
||||||
UNLOCK_ZONE(zone);
|
UNLOCK_ZONE(zone);
|
||||||
if (db != NULL)
|
if (db != NULL)
|
||||||
dns_db_detach(&db);
|
dns_db_detach(&db);
|
||||||
@@ -1989,12 +1993,12 @@ zone_load(dns_zone_t *zone, unsigned int flags) {
|
|||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
dns_zone_load(dns_zone_t *zone) {
|
dns_zone_load(dns_zone_t *zone) {
|
||||||
return (zone_load(zone, 0));
|
return (zone_load(zone, 0, ISC_FALSE));
|
||||||
}
|
}
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
dns_zone_loadnew(dns_zone_t *zone) {
|
dns_zone_loadnew(dns_zone_t *zone) {
|
||||||
return (zone_load(zone, DNS_ZONELOADFLAG_NOSTAT));
|
return (zone_load(zone, DNS_ZONELOADFLAG_NOSTAT, ISC_FALSE));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -2002,6 +2006,7 @@ zone_asyncload(isc_task_t *task, isc_event_t *event) {
|
|||||||
dns_asyncload_t *asl = event->ev_arg;
|
dns_asyncload_t *asl = event->ev_arg;
|
||||||
dns_zone_t *zone = asl->zone;
|
dns_zone_t *zone = asl->zone;
|
||||||
isc_result_t result = ISC_R_SUCCESS;
|
isc_result_t result = ISC_R_SUCCESS;
|
||||||
|
isc_boolean_t load_pending;
|
||||||
|
|
||||||
UNUSED(task);
|
UNUSED(task);
|
||||||
|
|
||||||
@@ -2010,13 +2015,21 @@ zone_asyncload(isc_task_t *task, isc_event_t *event) {
|
|||||||
if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
|
if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
|
||||||
result = ISC_R_CANCELED;
|
result = ISC_R_CANCELED;
|
||||||
isc_event_free(&event);
|
isc_event_free(&event);
|
||||||
if (result == ISC_R_CANCELED ||
|
|
||||||
!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING))
|
if (result == ISC_R_CANCELED)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
zone_load(zone, 0);
|
/* Make sure load is still pending */
|
||||||
|
|
||||||
LOCK_ZONE(zone);
|
LOCK_ZONE(zone);
|
||||||
|
load_pending = ISC_TF(DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING));
|
||||||
|
|
||||||
|
if (!load_pending) {
|
||||||
|
UNLOCK_ZONE(zone);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
zone_load(zone, 0, ISC_TRUE);
|
||||||
|
|
||||||
DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING);
|
DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING);
|
||||||
UNLOCK_ZONE(zone);
|
UNLOCK_ZONE(zone);
|
||||||
|
|
||||||
@@ -2042,7 +2055,7 @@ dns_zone_asyncload(dns_zone_t *zone, dns_zt_zoneloaded_t done, void *arg) {
|
|||||||
|
|
||||||
/* If we already have a load pending, stop now */
|
/* If we already have a load pending, stop now */
|
||||||
if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING))
|
if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING))
|
||||||
done(arg, zone, NULL);
|
return (ISC_R_ALREADYRUNNING);
|
||||||
|
|
||||||
asl = isc_mem_get(zone->mctx, sizeof (*asl));
|
asl = isc_mem_get(zone->mctx, sizeof (*asl));
|
||||||
if (asl == NULL)
|
if (asl == NULL)
|
||||||
@@ -2085,9 +2098,10 @@ dns_zone_loadandthaw(dns_zone_t *zone) {
|
|||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
|
|
||||||
if (inline_raw(zone))
|
if (inline_raw(zone))
|
||||||
result = zone_load(zone->secure, DNS_ZONELOADFLAG_THAW);
|
result = zone_load(zone->secure, DNS_ZONELOADFLAG_THAW,
|
||||||
|
ISC_FALSE);
|
||||||
else
|
else
|
||||||
result = zone_load(zone, DNS_ZONELOADFLAG_THAW);
|
result = zone_load(zone, DNS_ZONELOADFLAG_THAW, ISC_FALSE);
|
||||||
|
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case DNS_R_CONTINUE:
|
case DNS_R_CONTINUE:
|
||||||
|
Reference in New Issue
Block a user