-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refine heap_5 heap protector #1146
Conversation
Thank you for sharing your proposal! I think it is a lot of complexity to bring to catch one specific type of pointer corruption. This also requires handling another corner case when What do you think about letting the application to override #ifndef configVALIDATE_HEAP_BLOCK_POINTER
#define heapVALIDATE_BLOCK_POINTER( pxBlock ) \
configASSERT( ( pucHeapHighAddress != NULL ) && \
( pucHeapLowAddress != NULL ) && \
( ( uint8_t * ) ( pxBlock ) >= pucHeapLowAddress ) && \
( ( uint8_t * ) ( pxBlock ) < pucHeapHighAddress ) )
#else
#define heapVALIDATE_BLOCK_POINTER( pxBlock ) \
configVALIDATE_HEAP_BLOCK_POINTER( pxBlock )
#endif This way the interested application can implement |
@aggarg Thanks for your review.
I agree with your point. When implementing this PR, the uncertainty about the number of memory regions is the reason why dynamic allocation of Region_Bound_t is needed in vPortDefinesRegion() after the heap is initialized, as at that point only free blocks are available. configVALIDATE_HEAP_BLOCK_POINTER is a good idea. In cases where the number of memory regions is known, static allocation can reduce complexity. However, in this case, the user will need to manually calculate the highest and lowest aligned addresses for each memory region, which is something to be aware of.
I'm a bit confused about this point. pvPortMalloc() for Region_Bound_t is the first allocation in the system, so if it fails, doesn't that mean the first pvPortMalloc() will fail? I can't quite understand under what circumstances it would fail. |
But those regions are known to the application, isn't it? One possible implementation is - #define HEAP_1_SIZE ( 24 * 1024 )
#define HEAP_2_SIZE ( 48 * 1024 )
uint8_t ucHeap1[ HEAP_1_SIZE ] __attribute__( ( section( ".freertos_heap1" ) ) );
uint8_t ucHeap2[ HEAP_2_SIZE ] __attribute__( ( section( ".freertos_heap2" ) ) );
void AppInitializeHeap( void )
{
HeapRegion_t xHeapRegions[] =
{
{ ( unsigned char * ) ucHeap1, sizeof( ucHeap1 ) },
{ ( unsigned char * ) ucHeap2, sizeof( ucHeap2 ) },
{ NULL, 0 }
};
vPortDefineHeapRegions( xHeapRegions );
} And in this case the application can implement the check like this - #define configVALIDATE_HEAP_BLOCK_POINTER( pxBlock ) ValidateHeapPointer( pxBlock )
void ValidateHeapPointer( void * ptr )
{
if( !( ptr >= &( ucHeap1[ 0 ] ) ) && ( ptr < &( ucHeap1[ HEAP_1_SIZE ] ) ) &&
!( ptr >= &( ucHeap2[ 0 ] ) ) && ( ptr < &( ucHeap2[ HEAP_2_SIZE ] ) ) )
{
/* If pointer is not in ucHeap1 and ucHeap2, it is invalid. */
configASSERT( pdFALSE );
}
}
You are right that if this fails, likely the first cal to |
Thank you for your reply, I agree with your point of view. |
Thank you! Would you please update your PR? |
Of course, then I will modify the PR according to this suggestion.
|
heap_5 is used for multiple separated memory spaces. In the previous implementation, it only verifies the highest and lowest addresses. A pointer may not be within heap regions, but is still located between the highest and lowest addressed. Add maco configVALIDATE_HEAP_BLOCK_POINTER to provide customized heap block pointers detection based on the settings of heap regions. Signed-off-by: wangfei_chen <wangfei_chen@realsil.com.cn>
938981a
to
23d9210
Compare
I updated the PR and force pushed. Thanks for your suggestion! |
Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
Quality Gate passedIssues Measures |
@Saiiijchan Thank you for your contribution! |
heap_5 is used for multiple separated memory spaces. In the previous implementation, it only verifies the highest and lowest addresses. A pointer may not be within heap regions, but is still located between the highest and lowest addressed.
Description
heap_5 is used for multiple separated memory spaces. In the previous implementation, it only verifies the highest and lowest addresses. A pointer may not be within heap regions, but is still located between the highest and lowest addressed.
This PR will use a buffer to record the boundary of each heap region so the pointer detection can be made more accurate . This buffter is dynamically allocated at the end of vPortDefineHeapRegions(). At this time, the multi heap regions have been defined and there is only a free block and "pxFakeEnd" (the heap structure points to the next heap region) and pxEnd (At the last heap region).
As shown in the diagram above, the white area represents the valid pointer range.
Test Steps
Test on FreeRTO and runs correctly.
I have also manually corrupted a free list block and triggered assertion successfully.
Checklist:
Related Issue
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.