Commit 36c46f8e authored by Eli Zaretskii's avatar Eli Zaretskii

Fix bug #12242 with crashes in ralloc.c on OpenBSD.

 src/ralloc.c (free_bloc): Don't dereference a 'heap' structure if it
 is not one of the heaps we manage.
parent db148c21
2012-08-24 Eli Zaretskii <eliz@gnu.org>
* ralloc.c (free_bloc): Don't dereference a 'heap' structure if it
is not one of the heaps we manage. (Bug#12242)
2012-08-15 Chong Yidong <cyd@gnu.org>
* Version 24.2 released.
......
......@@ -686,6 +686,7 @@ static void
free_bloc (bloc_ptr bloc)
{
heap_ptr heap = bloc->heap;
heap_ptr h;
if (r_alloc_freeze_level)
{
......@@ -715,20 +716,38 @@ free_bloc (bloc_ptr bloc)
bloc->prev->next = bloc->next;
}
/* Update the records of which blocs are in HEAP. */
if (heap->first_bloc == bloc)
/* Sometimes, 'heap' obtained from bloc->heap above is not really a
'heap' structure. It can even be beyond the current break point,
which will cause crashes when we dereference it below (see
bug#12242). Evidently, the reason is bloc allocations done while
use_relocatable_buffers was non-positive, because additional
memory we get then is not recorded in the heaps we manage. If
bloc->heap records such a "heap", we cannot (and don't need to)
update its records. So we validate the 'heap' value by making
sure it is one of the heaps we manage via the heaps linked list,
and don't touch a 'heap' that isn't found there. This avoids
accessing memory we know nothing about. */
for (h = first_heap; h != NIL_HEAP; h = h->next)
if (heap == h)
break;
if (h)
{
if (bloc->next != 0 && bloc->next->heap == heap)
heap->first_bloc = bloc->next;
else
heap->first_bloc = heap->last_bloc = NIL_BLOC;
}
if (heap->last_bloc == bloc)
{
if (bloc->prev != 0 && bloc->prev->heap == heap)
heap->last_bloc = bloc->prev;
else
heap->first_bloc = heap->last_bloc = NIL_BLOC;
/* Update the records of which blocs are in HEAP. */
if (heap->first_bloc == bloc)
{
if (bloc->next != 0 && bloc->next->heap == heap)
heap->first_bloc = bloc->next;
else
heap->first_bloc = heap->last_bloc = NIL_BLOC;
}
if (heap->last_bloc == bloc)
{
if (bloc->prev != 0 && bloc->prev->heap == heap)
heap->last_bloc = bloc->prev;
else
heap->first_bloc = heap->last_bloc = NIL_BLOC;
}
}
relinquish ();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment