diff --git a/dhcp-isc_heap_delete.patch b/dhcp-isc_heap_delete.patch new file mode 100644 index 0000000..3bf1b2b --- /dev/null +++ b/dhcp-isc_heap_delete.patch @@ -0,0 +1,164 @@ +diff --git a/includes/dhcpd.h b/includes/dhcpd.h +index aac2c108..c83dc9a6 100644 +--- a/includes/dhcpd.h ++++ b/includes/dhcpd.h +@@ -1622,8 +1622,9 @@ struct iasubopt { + */ + #define EXPIRED_IPV6_CLEANUP_TIME (60*60) + +- int heap_index; /* index into heap, or -1 +- (internal use only) */ ++ /* index into heaps, or -1 (internal use only) */ ++ int active_index; ++ int inactive_index; + + /* + * A pointer to the state of the ddns update for this lease. +diff --git a/server/mdb6.c b/server/mdb6.c +index 1a728eb3..418ff606 100644 +--- a/server/mdb6.c ++++ b/server/mdb6.c +@@ -216,7 +216,8 @@ iasubopt_allocate(struct iasubopt **iasubopt, const char *file, int line) { + + tmp->refcnt = 1; + tmp->state = FTS_FREE; +- tmp->heap_index = -1; ++ tmp->active_index = -1; ++ tmp->inactive_index = -1; + tmp->plen = 255; + + *iasubopt = tmp; +@@ -604,10 +605,14 @@ lease_older(void *a, void *b) { + * Callback when an address's position in the heap changes. + */ + static void +-lease_index_changed(void *iasubopt, unsigned int new_heap_index) { +- ((struct iasubopt *)iasubopt)-> heap_index = new_heap_index; ++active_changed(void *iasubopt, unsigned int new_heap_index) { ++ ((struct iasubopt *)iasubopt)-> active_index = new_heap_index; + } + ++static void ++inactive_changed(void *iasubopt, unsigned int new_heap_index) { ++ ((struct iasubopt *)iasubopt)-> inactive_index = new_heap_index; ++} + + /*! + * +@@ -660,13 +665,13 @@ ipv6_pool_allocate(struct ipv6_pool **pool, u_int16_t type, + dfree(tmp, file, line); + return ISC_R_NOMEMORY; + } +- if (isc_heap_create(dhcp_gbl_ctx.mctx, lease_older, lease_index_changed, ++ if (isc_heap_create(dhcp_gbl_ctx.mctx, lease_older, active_changed, + 0, &(tmp->active_timeouts)) != ISC_R_SUCCESS) { + iasubopt_free_hash_table(&(tmp->leases), file, line); + dfree(tmp, file, line); + return ISC_R_NOMEMORY; + } +- if (isc_heap_create(dhcp_gbl_ctx.mctx, lease_older, lease_index_changed, ++ if (isc_heap_create(dhcp_gbl_ctx.mctx, lease_older, inactive_changed, + 0, &(tmp->inactive_timeouts)) != ISC_R_SUCCESS) { + isc_heap_destroy(&(tmp->active_timeouts)); + iasubopt_free_hash_table(&(tmp->leases), file, line); +@@ -1361,7 +1366,7 @@ cleanup_lease6(ia_hash_t *ia_table, + * Remove the old lease from the active heap and from the hash table + * then remove the lease from the IA and clean up the IA if necessary. + */ +- isc_heap_delete(pool->active_timeouts, test_iasubopt->heap_index); ++ isc_heap_delete(pool->active_timeouts, test_iasubopt->active_index); + pool->num_active--; + if (pool->ipv6_pond) + pool->ipv6_pond->num_active--; +@@ -1434,7 +1439,7 @@ add_lease6(struct ipv6_pool *pool, struct iasubopt *lease, + if ((test_iasubopt->state == FTS_ACTIVE) || + (test_iasubopt->state == FTS_ABANDONED)) { + isc_heap_delete(pool->active_timeouts, +- test_iasubopt->heap_index); ++ test_iasubopt->active_index); + pool->num_active--; + if (pool->ipv6_pond) + pool->ipv6_pond->num_active--; +@@ -1446,7 +1451,7 @@ add_lease6(struct ipv6_pool *pool, struct iasubopt *lease, + } + } else { + isc_heap_delete(pool->inactive_timeouts, +- test_iasubopt->heap_index); ++ test_iasubopt->inactive_index); + pool->num_inactive--; + } + +@@ -1567,14 +1572,13 @@ lease6_usable(struct iasubopt *lease) { + static isc_result_t + move_lease_to_active(struct ipv6_pool *pool, struct iasubopt *lease) { + isc_result_t insert_result; +- int old_heap_index; + +- old_heap_index = lease->heap_index; + insert_result = isc_heap_insert(pool->active_timeouts, lease); + if (insert_result == ISC_R_SUCCESS) { + iasubopt_hash_add(pool->leases, &lease->addr, + sizeof(lease->addr), lease, MDL); +- isc_heap_delete(pool->inactive_timeouts, old_heap_index); ++ isc_heap_delete(pool->inactive_timeouts, ++ lease->inactive_index); + pool->num_active++; + pool->num_inactive--; + lease->state = FTS_ACTIVE; +@@ -1624,16 +1628,16 @@ renew_lease6(struct ipv6_pool *pool, struct iasubopt *lease) { + if (lease->state == FTS_ACTIVE) { + if (old_end_time <= lease->hard_lifetime_end_time) { + isc_heap_decreased(pool->active_timeouts, +- lease->heap_index); ++ lease->active_index); + } else { + isc_heap_increased(pool->active_timeouts, +- lease->heap_index); ++ lease->active_index); + } + return ISC_R_SUCCESS; + } else if (lease->state == FTS_ABANDONED) { + char tmp_addr[INET6_ADDRSTRLEN]; + lease->state = FTS_ACTIVE; +- isc_heap_increased(pool->active_timeouts, lease->heap_index); ++ isc_heap_increased(pool->active_timeouts, lease->active_index); + log_info("Reclaiming previously abandoned address %s", + inet_ntop(AF_INET6, &(lease->addr), tmp_addr, + sizeof(tmp_addr))); +@@ -1655,9 +1659,7 @@ static isc_result_t + move_lease_to_inactive(struct ipv6_pool *pool, struct iasubopt *lease, + binding_state_t state) { + isc_result_t insert_result; +- int old_heap_index; + +- old_heap_index = lease->heap_index; + insert_result = isc_heap_insert(pool->inactive_timeouts, lease); + if (insert_result == ISC_R_SUCCESS) { + /* +@@ -1708,7 +1710,7 @@ move_lease_to_inactive(struct ipv6_pool *pool, struct iasubopt *lease, + + iasubopt_hash_delete(pool->leases, + &lease->addr, sizeof(lease->addr), MDL); +- isc_heap_delete(pool->active_timeouts, old_heap_index); ++ isc_heap_delete(pool->active_timeouts, lease->active_index); + lease->state = state; + pool->num_active--; + pool->num_inactive++; +@@ -1786,7 +1788,7 @@ decline_lease6(struct ipv6_pool *pool, struct iasubopt *lease) { + pool->ipv6_pond->num_abandoned++; + + lease->hard_lifetime_end_time = MAX_TIME; +- isc_heap_decreased(pool->active_timeouts, lease->heap_index); ++ isc_heap_decreased(pool->active_timeouts, lease->active_index); + return ISC_R_SUCCESS; + } + +@@ -2059,7 +2061,7 @@ cleanup_old_expired(struct ipv6_pool *pool) { + break; + } + +- isc_heap_delete(pool->inactive_timeouts, tmp->heap_index); ++ isc_heap_delete(pool->inactive_timeouts, tmp->inactive_index); + pool->num_inactive--; + + if (tmp->ia != NULL) { diff --git a/dhcp.spec b/dhcp.spec index 0ea0ef2..2318b01 100644 --- a/dhcp.spec +++ b/dhcp.spec @@ -16,7 +16,8 @@ Summary: Dynamic host configuration protocol software Name: dhcp Version: 4.3.6 -Release: 32%{?dist} +Release: 33%{?dist} + # NEVER CHANGE THE EPOCH on this package. The previous maintainer (prior to # dcantrell maintaining the package) made incorrect use of the epoch and # that's why it is at 12 now. It should have never been used, but it was. @@ -80,6 +81,8 @@ Patch43: dhcp-4.3.6-reference_count_overflow.patch Patch44: dhcp-iface_hwaddr_discovery.patch Patch45: dhcp-noreplay.patch Patch46: dhcp-4.3.6-bind-9.11.5.patch +Patch47: dhcp-isc_heap_delete.patch + BuildRequires: autoconf BuildRequires: automake @@ -361,6 +364,9 @@ rm bind/bind.tar.gz %patch46 -p1 -b .bind +# https://bugs.isc.org/Public/Bug/Display.html?id=46719# +%patch47 -p1 -b .heap + # DHCLIENT_DEFAULT_PREFIX_LEN 64 -> 128 # https://bugzilla.gnome.org/show_bug.cgi?id=656610 sed -i -e 's|DHCLIENT_DEFAULT_PREFIX_LEN 64|DHCLIENT_DEFAULT_PREFIX_LEN 128|g' includes/site.h @@ -684,6 +690,10 @@ done %endif %changelog + +* Tue Apr 30 2019 Pavel Zhukov - 12:4.3.6- +- Resolves: #1641246 - Do not rely on isc_heap_delete bug + * Thu Jan 31 2019 Fedora Release Engineering - 12:4.3.6-32 - Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild