From 678b206fd8a798a9564dfffc2cfd1aadfb4a777f Mon Sep 17 00:00:00 2001 From: Chris Johns Date: Tue, 1 Mar 2011 05:29:26 +0000 Subject: 2011-03-01 Chris Johns * score/src/heapfree.c, score/src/heapresizeblock.c: PR 1746. Move protection block checks to after the block address has been checked as a valid heap address. Add a special case in the heap free for a NULL address. --- cpukit/ChangeLog | 7 +++++++ cpukit/score/src/heapfree.c | 27 ++++++++++++++++++--------- cpukit/score/src/heapresizeblock.c | 6 ++---- 3 files changed, 27 insertions(+), 13 deletions(-) (limited to 'cpukit') diff --git a/cpukit/ChangeLog b/cpukit/ChangeLog index a8fdaae9f4..58bdcfed82 100644 --- a/cpukit/ChangeLog +++ b/cpukit/ChangeLog @@ -1,3 +1,10 @@ +2011-03-01 Chris Johns + + * score/src/heapfree.c, score/src/heapresizeblock.c: PR 1746. Move + protection block checks to after the block address has been + checked as a valid heap address. Add a special case in the heap + free for a NULL address. + 2011-02-27 Jennifer Averett * score/include/rtems/score/schedulerpriority.h, diff --git a/cpukit/score/src/heapfree.c b/cpukit/score/src/heapfree.c index 27e853d5bb..25a1e6964d 100644 --- a/cpukit/score/src/heapfree.c +++ b/cpukit/score/src/heapfree.c @@ -108,33 +108,42 @@ bool _Heap_Free( Heap_Control *heap, void *alloc_begin_ptr ) { Heap_Statistics *const stats = &heap->stats; - uintptr_t alloc_begin = (uintptr_t) alloc_begin_ptr; - Heap_Block *block = - _Heap_Block_of_alloc_area( alloc_begin, heap->page_size ); + uintptr_t alloc_begin; + Heap_Block *block; Heap_Block *next_block = NULL; uintptr_t block_size = 0; uintptr_t next_block_size = 0; bool next_is_free = false; - _Heap_Protection_block_check( heap, block ); - + /* + * If NULL return true so a free on NULL is considered a valid release. This + * is a special case that could be handled by the in heap check how-ever that + * would result in false being returned which is wrong. + */ + if ( alloc_begin_ptr == NULL ) { + return true; + } + + alloc_begin = (uintptr_t) alloc_begin_ptr; + block = _Heap_Block_of_alloc_area( alloc_begin, heap->page_size ); + if ( !_Heap_Is_block_in_heap( heap, block ) ) { return false; } + _Heap_Protection_block_check( heap, block ); + block_size = _Heap_Block_size( block ); next_block = _Heap_Block_at( block, block_size ); - _Heap_Protection_block_check( heap, next_block ); - if ( !_Heap_Is_block_in_heap( heap, next_block ) ) { - _HAssert( false ); return false; } + _Heap_Protection_block_check( heap, next_block ); + if ( !_Heap_Is_prev_used( next_block ) ) { _Heap_Protection_block_error( heap, block ); - return false; } diff --git a/cpukit/score/src/heapresizeblock.c b/cpukit/score/src/heapresizeblock.c index 152418fc71..2d3528645f 100644 --- a/cpukit/score/src/heapresizeblock.c +++ b/cpukit/score/src/heapresizeblock.c @@ -104,9 +104,8 @@ Heap_Resize_status _Heap_Resize_block( *old_size = 0; *new_size = 0; - _Heap_Protection_block_check( heap, block ); - if ( _Heap_Is_block_in_heap( heap, block ) ) { + _Heap_Protection_block_check( heap, block ); return _Heap_Resize_block_checked( heap, block, @@ -115,7 +114,6 @@ Heap_Resize_status _Heap_Resize_block( old_size, new_size ); - } else { - return HEAP_RESIZE_FATAL_ERROR; } + return HEAP_RESIZE_FATAL_ERROR; } -- cgit v1.2.3