FreeRTOS with Heap Protector

The latest FreeRTOS V11 release includes an interesting feature: a heap protector feature, which can help detect memory corruption early at runtime.

FreeRTOS Heap Protection

The heap protection is turned off by default, and it can be enabled by setting the following FreeRTOS #define to 1:

#define configENABLE_HEAP_PROTECTOR  (1)

Heap protection in FreeRTOS works with two things:

  1. The heap block pointers get ‘obfuscated’ with an XOR operation.
  2. The heap block pointers get checked if they are within the heap boundaries.

FreeRTOS Heap Block Pointers

FreRTOS offers multiple different heap implementations (see https://www.freertos.org/a00111.html). The FreeRTOS Heap Protectors is currently only implemented for the heap scheme 4 (block merge) and heap scheme 5 (block merge with multiple heaps).

Basically a ‘heap’ with scheme 4 is an array of bytes:

unsigned char ucheap[configTOTAL_HEAP_SIZE];

The FreeRTOS heap manager maintains a list with free block information:

/* Define the linked list structure.  This is used to link free blocks in order
 * of their memory address. */
typedef struct A_BLOCK_LINK
{
    struct A_BLOCK_LINK * pxNextFreeBlock; /**< The next free block in the list. */
    size_t xBlockSize;                     /**< The size of the free block. */
} BlockLink_t;

Below a graphical representation how a heap could look like with one allocated block (blue) and two free blocks (white):

FreeRTOS Heap Structure
  • ‘xStart’ is the first free block.
  • ‘pNextFreeBlock’ points to the next free block (e.g. address 0x1000 in above example).
  • ‘xblockSize’ is the size of the free block.
  • In case of a allocated block (pointer p used by the application), the pointer points to the start of the memory, right after the management block. The management block has a NULL pxNextFreeBlock pointer, and the block size is marked with the least significant bit to indicate it is ‘allocated’.
  • ‘pxEnd’ is used as pointer to the last free block in the chain of blocks.

Canary Value

With Heap Protection enabled, the application has to provide a ‘canary’ value which is used for XORing the heap pointers. This value should be kind of ‘random’, below an example implementation:

#if configENABLE_HEAP_PROTECTOR
void vApplicationGetRandomHeapCanary( portPOINTER_SIZE_TYPE *pxHeapCanary) {
  *pxHeapCanary = 0xdeaf25f3;
}
#endif

Heap Block Pointer Protection

The canary value is used to protect the heap block pointers:

#define heapPROTECT_BLOCK_POINTER( pxBlock )    ( ( BlockLink_t * ) ( ( ( portPOINTER_SIZE_TYPE ) ( pxBlock ) ) ^ xHeapCanary ) )

Whenever the manager is reading or writing the heap block pointer, it uses the above macro to XOR it. The XOR operation with a ‘random’ value makes it more likely to point outside the heap memory range which is checked by a Heap Validation.

FreeRTOS Protected Pointers

Heap Validation

Whenever the heap block pointer is used, it is checked if the pointer is still within the heap boundaries:

/* Assert that a heap block pointer is within the heap bounds. */
#define heapVALIDATE_BLOCK_POINTER( pxBlock )                          \
    configASSERT( ( ( uint8_t * ) ( pxBlock ) >= &( ucHeap[ 0 ] ) ) && \
                  ( ( uint8_t * ) ( pxBlock ) <= &( ucHeap[ configTOTAL_HEAP_SIZE - 1 ] ) ) )

Note that above check is now performed regardless if configENABLE_HEAP_PROTECTOR is enabled or not.

Summary

The FreeRTOS heap protection is a nice enhancements which can catch heap problems early in the issue chain and error propagation. Note that this only protects part of the heap management structure (the heap block pointer), and not everything else (size of heap block or the data itself). Still, better than not having any guards in place.

💡 Another useful setting in FreeRTOS is configHEAP_CLEAR_MEMORY_ON_FREE: with this, the memory blocks get initialized back to zero during a free. Very neat!

If you you want more information about memory leaks and the like, make sure you have a read at my other article: Added Heap Memory Monitoring and Tracking to FreeRTOS V10.5

Happy protecting 🙂

Links

What do you think?

This site uses Akismet to reduce spam. Learn how your comment data is processed.