Improve heap2 bounds checking (#224)

* Improve heap bounds checking in pvPortMalloc
This commit is contained in:
Cobus van Eeden 2020-12-07 10:36:27 -08:00 committed by GitHub
parent b5020cb3d8
commit c7a9a01c94
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 66 additions and 34 deletions

View file

@ -22,7 +22,6 @@
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.com/FreeRTOS
* *
* 1 tab == 4 spaces!
*/ */
@ -72,14 +71,21 @@ void * pvPortMalloc( size_t xWantedSize )
void * pvReturn = NULL; void * pvReturn = NULL;
static uint8_t * pucAlignedHeap = NULL; static uint8_t * pucAlignedHeap = NULL;
/* Ensure that blocks are always aligned to the required number of bytes. */ /* Ensure that blocks are always aligned. */
#if ( portBYTE_ALIGNMENT != 1 ) #if ( portBYTE_ALIGNMENT != 1 )
{ {
if( xWantedSize & portBYTE_ALIGNMENT_MASK ) if( xWantedSize & portBYTE_ALIGNMENT_MASK )
{ {
/* Byte alignment required. */ /* Byte alignment required. Check for overflow. */
if ( (xWantedSize + ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) )) > xWantedSize )
{
xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) );
} }
else
{
xWantedSize = 0;
}
}
} }
#endif #endif
@ -91,8 +97,9 @@ void * pvPortMalloc( size_t xWantedSize )
pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) & ucHeap[ portBYTE_ALIGNMENT ] ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) ); pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) & ucHeap[ portBYTE_ALIGNMENT ] ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) );
} }
/* Check there is enough room left for the allocation. */ /* Check there is enough room left for the allocation and. */
if( ( ( xNextFreeByte + xWantedSize ) < configADJUSTED_HEAP_SIZE ) && if( ( xWantedSize > 0 ) && /* valid size */
( ( xNextFreeByte + xWantedSize ) < configADJUSTED_HEAP_SIZE ) &&
( ( xNextFreeByte + xWantedSize ) > xNextFreeByte ) ) /* Check for overflow. */ ( ( xNextFreeByte + xWantedSize ) > xNextFreeByte ) ) /* Check for overflow. */
{ {
/* Return the next free byte then increment the index past this /* Return the next free byte then increment the index past this

View file

@ -22,7 +22,6 @@
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.com/FreeRTOS
* *
* 1 tab == 4 spaces!
*/ */
/* /*
@ -132,21 +131,32 @@ void * pvPortMalloc( size_t xWantedSize )
xHeapHasBeenInitialised = pdTRUE; xHeapHasBeenInitialised = pdTRUE;
} }
/* The wanted size is increased so it can contain a BlockLink_t /* The wanted size must be increased so it can contain a BlockLink_t
* structure in addition to the requested amount of bytes. */ * structure in addition to the requested amount of bytes. */
if( xWantedSize > 0 ) if( ( xWantedSize > 0 ) &&
( ( xWantedSize + heapSTRUCT_SIZE ) > xWantedSize ) ) /* Overflow check */
{ {
xWantedSize += heapSTRUCT_SIZE; xWantedSize += heapSTRUCT_SIZE;
/* Ensure that blocks are always aligned to the required number of bytes. */ /* Byte alignment required. Check for overflow. */
if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0 ) if( ( xWantedSize + ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ) )
> xWantedSize )
{ {
/* Byte alignment required. */
xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) );
configASSERT( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) == 0 );
} }
else
{
xWantedSize = 0;
}
}
else
{
xWantedSize = 0;
} }
if( ( xWantedSize > 0 ) && ( xWantedSize < configADJUSTED_HEAP_SIZE ) )
if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) )
{ {
/* Blocks are stored in byte order - traverse the list from the start /* Blocks are stored in byte order - traverse the list from the start
* (smallest) block until one of adequate size is found. */ * (smallest) block until one of adequate size is found. */

View file

@ -136,29 +136,37 @@ void * pvPortMalloc( size_t xWantedSize )
* kernel, so it must be free. */ * kernel, so it must be free. */
if( ( xWantedSize & xBlockAllocatedBit ) == 0 ) if( ( xWantedSize & xBlockAllocatedBit ) == 0 )
{ {
/* The wanted size is increased so it can contain a BlockLink_t /* The wanted size must be increased so it can contain a BlockLink_t
* structure in addition to the requested amount of bytes. */ * structure in addition to the requested amount of bytes. */
if( xWantedSize > 0 ) if( ( xWantedSize > 0 ) &&
( ( xWantedSize + xHeapStructSize ) > xWantedSize ) ) /* Overflow check */
{ {
xWantedSize += xHeapStructSize; xWantedSize += xHeapStructSize;
/* Ensure that blocks are always aligned to the required number /* Ensure that blocks are always aligned. */
* of bytes. */
if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0x00 ) if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0x00 )
{ {
/* Byte alignment required. */ /* Byte alignment required. Check for overflow. */
if( ( xWantedSize + ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ) )
> xWantedSize )
{
xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) );
configASSERT( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) == 0 ); configASSERT( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) == 0 );
} }
else else
{ {
mtCOVERAGE_TEST_MARKER(); xWantedSize = 0;
} }
} }
else else
{ {
mtCOVERAGE_TEST_MARKER(); mtCOVERAGE_TEST_MARKER();
} }
}
else
{
xWantedSize = 0;
}
if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) ) if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) )
{ {

View file

@ -22,7 +22,6 @@
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.com/FreeRTOS
* *
* 1 tab == 4 spaces!
*/ */
/* /*
@ -150,26 +149,34 @@ void * pvPortMalloc( size_t xWantedSize )
{ {
/* The wanted size is increased so it can contain a BlockLink_t /* The wanted size is increased so it can contain a BlockLink_t
* structure in addition to the requested amount of bytes. */ * structure in addition to the requested amount of bytes. */
if( xWantedSize > 0 ) if( ( xWantedSize > 0 ) &&
( ( xWantedSize + xHeapStructSize ) > xWantedSize ) ) /* Overflow check */
{ {
xWantedSize += xHeapStructSize; xWantedSize += xHeapStructSize;
/* Ensure that blocks are always aligned to the required number /* Ensure that blocks are always aligned */
* of bytes. */
if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0x00 ) if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0x00 )
{ {
/* Byte alignment required. */ /* Byte alignment required. Check for overflow */
if( ( xWantedSize + ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ) ) >
xWantedSize )
{
xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) );
} }
else else
{ {
mtCOVERAGE_TEST_MARKER(); xWantedSize = 0;
} }
} }
else else
{ {
mtCOVERAGE_TEST_MARKER(); mtCOVERAGE_TEST_MARKER();
} }
}
else
{
xWantedSize = 0;
}
if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) ) if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) )
{ {