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.
This commit is contained in:
parent
db148c21a9
commit
36c46f8e09
2 changed files with 37 additions and 13 deletions
|
@ -1,3 +1,8 @@
|
|||
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.
|
||||
|
|
45
src/ralloc.c
45
src/ralloc.c
|
@ -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 ();
|
||||
|
|
Loading…
Add table
Reference in a new issue