queue.c: Change some asserts into conditionals and improve overflow checks (#328)

This commit is contained in:
Dan Good 2021-05-27 19:17:59 -04:00 committed by GitHub
parent a1b918c1aa
commit 8e2f723996
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 123 additions and 92 deletions

View file

@ -49,4 +49,8 @@ typedef unsigned short uint16_t;
typedef long int32_t; typedef long int32_t;
typedef unsigned long uint32_t; typedef unsigned long uint32_t;
#ifndef SIZE_MAX
#define SIZE_MAX ( ( size_t ) -1 )
#endif
#endif /* FREERTOS_STDINT */ #endif /* FREERTOS_STDINT */

85
queue.c
View file

@ -264,12 +264,18 @@ static void prvInitialiseNewQueue( const UBaseType_t uxQueueLength,
BaseType_t xQueueGenericReset( QueueHandle_t xQueue, BaseType_t xQueueGenericReset( QueueHandle_t xQueue,
BaseType_t xNewQueue ) BaseType_t xNewQueue )
{ {
BaseType_t xReturn = pdPASS;
Queue_t * const pxQueue = xQueue; Queue_t * const pxQueue = xQueue;
configASSERT( pxQueue ); configASSERT( pxQueue );
taskENTER_CRITICAL(); if( ( pxQueue != NULL ) &&
( pxQueue->uxLength >= 1U ) &&
/* Check for multiplication overflow. */
( ( SIZE_MAX / pxQueue->uxLength ) >= pxQueue->uxItemSize ) )
{ {
taskENTER_CRITICAL();
pxQueue->u.xQueue.pcTail = pxQueue->pcHead + ( pxQueue->uxLength * pxQueue->uxItemSize ); /*lint !e9016 Pointer arithmetic allowed on char types, especially when it assists conveying intent. */ pxQueue->u.xQueue.pcTail = pxQueue->pcHead + ( pxQueue->uxLength * pxQueue->uxItemSize ); /*lint !e9016 Pointer arithmetic allowed on char types, especially when it assists conveying intent. */
pxQueue->uxMessagesWaiting = ( UBaseType_t ) 0U; pxQueue->uxMessagesWaiting = ( UBaseType_t ) 0U;
pxQueue->pcWriteTo = pxQueue->pcHead; pxQueue->pcWriteTo = pxQueue->pcHead;
@ -306,12 +312,18 @@ BaseType_t xQueueGenericReset( QueueHandle_t xQueue,
vListInitialise( &( pxQueue->xTasksWaitingToSend ) ); vListInitialise( &( pxQueue->xTasksWaitingToSend ) );
vListInitialise( &( pxQueue->xTasksWaitingToReceive ) ); vListInitialise( &( pxQueue->xTasksWaitingToReceive ) );
} }
}
taskEXIT_CRITICAL(); taskEXIT_CRITICAL();
}
else
{
xReturn = pdFAIL;
}
configASSERT( xReturn != pdFAIL );
/* A value is returned for calling semantic consistency with previous /* A value is returned for calling semantic consistency with previous
* versions. */ * versions. */
return pdPASS; return xReturn;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -323,18 +335,19 @@ BaseType_t xQueueGenericReset( QueueHandle_t xQueue,
StaticQueue_t * pxStaticQueue, StaticQueue_t * pxStaticQueue,
const uint8_t ucQueueType ) const uint8_t ucQueueType )
{ {
Queue_t * pxNewQueue; Queue_t * pxNewQueue = NULL;
configASSERT( uxQueueLength > ( UBaseType_t ) 0 );
/* The StaticQueue_t structure and the queue storage area must be /* The StaticQueue_t structure and the queue storage area must be
* supplied. */ * supplied. */
configASSERT( pxStaticQueue != NULL ); configASSERT( pxStaticQueue );
if( ( uxQueueLength > ( UBaseType_t ) 0 ) &&
( pxStaticQueue != NULL ) &&
/* A queue storage area should be provided if the item size is not 0, and /* A queue storage area should be provided if the item size is not 0, and
* should not be provided if the item size is 0. */ * should not be provided if the item size is 0. */
configASSERT( !( ( pucQueueStorage != NULL ) && ( uxItemSize == 0 ) ) ); ( !( ( pucQueueStorage != NULL ) && ( uxItemSize == 0 ) ) ) &&
configASSERT( !( ( pucQueueStorage == NULL ) && ( uxItemSize != 0 ) ) ); ( !( ( pucQueueStorage == NULL ) && ( uxItemSize != 0 ) ) ) )
{
#if ( configASSERT_DEFINED == 1 ) #if ( configASSERT_DEFINED == 1 )
{ {
@ -354,8 +367,6 @@ BaseType_t xQueueGenericReset( QueueHandle_t xQueue,
* but is already set. */ * but is already set. */
pxNewQueue = ( Queue_t * ) pxStaticQueue; /*lint !e740 !e9087 Unusual cast is ok as the structures are designed to have the same alignment, and the size is checked by an assert. */ pxNewQueue = ( Queue_t * ) pxStaticQueue; /*lint !e740 !e9087 Unusual cast is ok as the structures are designed to have the same alignment, and the size is checked by an assert. */
if( pxNewQueue != NULL )
{
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
{ {
/* Queues can be allocated wither statically or dynamically, so /* Queues can be allocated wither statically or dynamically, so
@ -369,7 +380,7 @@ BaseType_t xQueueGenericReset( QueueHandle_t xQueue,
} }
else else
{ {
traceQUEUE_CREATE_FAILED( ucQueueType ); configASSERT( pxNewQueue );
mtCOVERAGE_TEST_MARKER(); mtCOVERAGE_TEST_MARKER();
} }
@ -385,23 +396,21 @@ BaseType_t xQueueGenericReset( QueueHandle_t xQueue,
const UBaseType_t uxItemSize, const UBaseType_t uxItemSize,
const uint8_t ucQueueType ) const uint8_t ucQueueType )
{ {
Queue_t * pxNewQueue; Queue_t * pxNewQueue = NULL;
size_t xQueueSizeInBytes; size_t xQueueSizeInBytes;
uint8_t * pucQueueStorage; uint8_t * pucQueueStorage;
configASSERT( uxQueueLength > ( UBaseType_t ) 0 ); if( ( uxQueueLength > ( UBaseType_t ) 0 ) &&
/* Check for multiplication overflow. */
( ( SIZE_MAX / uxQueueLength ) >= uxItemSize ) &&
/* Check for addition overflow. */
( ( SIZE_MAX - sizeof( Queue_t ) ) >= ( uxQueueLength * uxItemSize ) ) )
{
/* Allocate enough space to hold the maximum number of items that /* Allocate enough space to hold the maximum number of items that
* can be in the queue at any time. It is valid for uxItemSize to be * can be in the queue at any time. It is valid for uxItemSize to be
* zero in the case the queue is used as a semaphore. */ * zero in the case the queue is used as a semaphore. */
xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
/* Check for multiplication overflow. */
configASSERT( ( uxItemSize == 0 ) || ( uxQueueLength == ( xQueueSizeInBytes / uxItemSize ) ) );
/* Check for addition overflow. */
configASSERT( ( sizeof( Queue_t ) + xQueueSizeInBytes ) > xQueueSizeInBytes );
/* Allocate the queue and storage area. Justification for MISRA /* Allocate the queue and storage area. Justification for MISRA
* deviation as follows: pvPortMalloc() always ensures returned memory * deviation as follows: pvPortMalloc() always ensures returned memory
* blocks are aligned per the requirements of the MCU stack. In this case * blocks are aligned per the requirements of the MCU stack. In this case
@ -436,6 +445,12 @@ BaseType_t xQueueGenericReset( QueueHandle_t xQueue,
traceQUEUE_CREATE_FAILED( ucQueueType ); traceQUEUE_CREATE_FAILED( ucQueueType );
mtCOVERAGE_TEST_MARKER(); mtCOVERAGE_TEST_MARKER();
} }
}
else
{
configASSERT( pxNewQueue );
mtCOVERAGE_TEST_MARKER();
}
return pxNewQueue; return pxNewQueue;
} }
@ -719,11 +734,11 @@ static void prvInitialiseNewQueue( const UBaseType_t uxQueueLength,
const UBaseType_t uxInitialCount, const UBaseType_t uxInitialCount,
StaticQueue_t * pxStaticQueue ) StaticQueue_t * pxStaticQueue )
{ {
QueueHandle_t xHandle; QueueHandle_t xHandle = NULL;
configASSERT( uxMaxCount != 0 );
configASSERT( uxInitialCount <= uxMaxCount );
if( ( uxMaxCount != 0 ) &&
( uxInitialCount <= uxMaxCount ) )
{
xHandle = xQueueGenericCreateStatic( uxMaxCount, queueSEMAPHORE_QUEUE_ITEM_LENGTH, NULL, pxStaticQueue, queueQUEUE_TYPE_COUNTING_SEMAPHORE ); xHandle = xQueueGenericCreateStatic( uxMaxCount, queueSEMAPHORE_QUEUE_ITEM_LENGTH, NULL, pxStaticQueue, queueQUEUE_TYPE_COUNTING_SEMAPHORE );
if( xHandle != NULL ) if( xHandle != NULL )
@ -736,6 +751,12 @@ static void prvInitialiseNewQueue( const UBaseType_t uxQueueLength,
{ {
traceCREATE_COUNTING_SEMAPHORE_FAILED(); traceCREATE_COUNTING_SEMAPHORE_FAILED();
} }
}
else
{
configASSERT( xHandle );
mtCOVERAGE_TEST_MARKER();
}
return xHandle; return xHandle;
} }
@ -748,11 +769,11 @@ static void prvInitialiseNewQueue( const UBaseType_t uxQueueLength,
QueueHandle_t xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, QueueHandle_t xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount,
const UBaseType_t uxInitialCount ) const UBaseType_t uxInitialCount )
{ {
QueueHandle_t xHandle; QueueHandle_t xHandle = NULL;
configASSERT( uxMaxCount != 0 );
configASSERT( uxInitialCount <= uxMaxCount );
if( ( uxMaxCount != 0 ) &&
( uxInitialCount <= uxMaxCount ) )
{
xHandle = xQueueGenericCreate( uxMaxCount, queueSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_COUNTING_SEMAPHORE ); xHandle = xQueueGenericCreate( uxMaxCount, queueSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_COUNTING_SEMAPHORE );
if( xHandle != NULL ) if( xHandle != NULL )
@ -765,6 +786,12 @@ static void prvInitialiseNewQueue( const UBaseType_t uxQueueLength,
{ {
traceCREATE_COUNTING_SEMAPHORE_FAILED(); traceCREATE_COUNTING_SEMAPHORE_FAILED();
} }
}
else
{
configASSERT( xHandle );
mtCOVERAGE_TEST_MARKER();
}
return xHandle; return xHandle;
} }