From: Tatuya JINMEI 神明達哉 Date: Thu, 4 Feb 2010 23:27:32 +0000 (+0000) Subject: 2850. [bug] If isc_heap_insert() failed due to memory shortage X-Git-Tag: v9.6.2~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d03e7dd2779a11e8417b196cc24013fbd78519af;p=thirdparty%2Fbind9.git 2850. [bug] If isc_heap_insert() failed due to memory shortage the heap would have corrupted entries. [RT #20951] 9.8.0, 9.7.1(?), 9.6.2, 9.5.3 (what about 9.4-ESV?) --- diff --git a/CHANGES b/CHANGES index b2bc01c54ae..508bbd3d2b1 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +2850. [bug] If isc_heap_insert() failed due to memory shortage + the heap would have corrupted entries. [RT #20951] + 2849. [bug] Don't treat errors from the xml2 library as fatal. [RT #20945] diff --git a/lib/isc/heap.c b/lib/isc/heap.c index 91d78c06d46..d25cb501267 100644 --- a/lib/isc/heap.c +++ b/lib/isc/heap.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: heap.c,v 1.37 2007/10/19 17:15:53 explorer Exp $ */ +/* $Id: heap.c,v 1.37.240.1 2010/02/04 23:27:32 jinmei Exp $ */ /*! \file * Heap implementation of priority queues adapted from the following: @@ -149,10 +149,12 @@ float_up(isc_heap_t *heap, unsigned int i, void *elt) { i > 1 && heap->compare(elt, heap->array[p]) ; i = p, p = heap_parent(i)) { heap->array[i] = heap->array[p]; + INSIST(heap->array[i] != NULL); if (heap->index != NULL) (heap->index)(heap->array[i], i); } heap->array[i] = elt; + INSIST(heap->array[i] != NULL); if (heap->index != NULL) (heap->index)(heap->array[i], i); @@ -173,11 +175,13 @@ sink_down(isc_heap_t *heap, unsigned int i, void *elt) { if (heap->compare(elt, heap->array[j])) break; heap->array[i] = heap->array[j]; + INSIST(heap->array[i] != NULL); if (heap->index != NULL) (heap->index)(heap->array[i], i); i = j; } heap->array[i] = elt; + INSIST(heap->array[i] != NULL); if (heap->index != NULL) (heap->index)(heap->array[i], i); @@ -186,15 +190,17 @@ sink_down(isc_heap_t *heap, unsigned int i, void *elt) { isc_result_t isc_heap_insert(isc_heap_t *heap, void *elt) { - unsigned int i; + unsigned int new_last; REQUIRE(VALID_HEAP(heap)); - i = ++heap->last; - if (heap->last >= heap->size && !resize(heap)) + new_last = heap->last + 1; + RUNTIME_CHECK(new_last > 0); /* overflow check */ + if (new_last >= heap->size && !resize(heap)) return (ISC_R_NOMEMORY); + heap->last = new_last; - float_up(heap, i, elt); + float_up(heap, new_last, elt); return (ISC_R_SUCCESS); } @@ -203,10 +209,16 @@ void isc_heap_delete(isc_heap_t *heap, unsigned int index) { void *elt; isc_boolean_t less; + void **array; + unsigned int size, last; REQUIRE(VALID_HEAP(heap)); REQUIRE(index >= 1 && index <= heap->last); + array = heap->array; + size = heap->size; + last = heap->last; + if (index == heap->last) { heap->array[heap->last] = NULL; heap->last--; @@ -215,8 +227,13 @@ isc_heap_delete(isc_heap_t *heap, unsigned int index) { heap->array[heap->last] = NULL; heap->last--; + INSIST(array == heap->array && + size == heap->size && + last == heap->last + 1); + less = heap->compare(elt, heap->array[index]); heap->array[index] = elt; + INSIST(heap->array[index] != NULL); if (less) float_up(heap, index, heap->array[index]); else