-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Description
Current Behavior
There is a severe out-of-bounds (OOB) memory access vulnerability in the STM32H7 timer interrupt implementation. It stems from an architectural assumption that timer numbers sequentially map to the timerCtx array indices, which is false for the STM32H7 series due to the absence of TIM9, TIM10, and TIM11.
In timer_impl.h, the IRQ handler macros are defined as:
#define _TIM_IRQ_HANDLER(name, i) \
void name(void) \
{ \
impl_timerCaptureCompareHandler(TIM ## i, timerCtx[i - 1]); \
} struct dummyThis hardcodes the array index to i - 1 (where i is the hardware timer number).
In timer_stm32h7xx.c, the timers are defined using these macros:
_TIM_IRQ_HANDLER(TIM15_IRQHandler, 15);
_TIM_IRQ_HANDLER(TIM16_IRQHandler, 16);
_TIM_IRQ_HANDLER(TIM17_IRQHandler, 17);However, in timer.c, the context array is allocated based on the total number of defined timers:
timHardwareContext_t * timerCtx[HARDWARE_TIMER_DEFINITION_COUNT];For STM32H7, HARDWARE_TIMER_DEFINITION_COUNT is typically 14.
When TIM17_IRQHandler is triggered, the macro expands to timerCtx[17 - 1], which evaluates to timerCtx[16]. Accessing index 16 on an array of size 14 results in a direct Out-Of-Bounds memory read. If the garbage value at this memory location is dereferenced inside impl_timerCaptureCompareHandler, it will cause an immediate HardFault.
Note: This bug has likely remained dormant because TIM15/16/17 are usually assigned to outputs (PWM/DShot) which do not enable the timer's global IRQ. However, if a user maps an input capture feature (like RC input or ESC RPM telemetry) to TIM15/16/17 on an H7 board, the FC will crash.
Steps to Reproduce
- Take any STM32H7 based flight controller.
- In
target.cor CLI, assign a receiver input (e.g., PPM/PWM) or ESC RPM Telemetry to a pad that corresponds toTIM15,TIM16, orTIM17(This forces the initialization of the timer in Input Capture mode, which enables theTIMx_IRQnvia NVIC). - Power on the board and feed a signal to that pad.
- The hardware triggers the IRQ, the firmware attempts to read
timerCtx[14],[15], or[16], leading to memory corruption or an immediate HardFault.
Expected behavior
The IRQ handler should access the correct timerCtx pointer that strictly corresponds to the linear index defined in timerDefinitions[], without exceeding HARDWARE_TIMER_DEFINITION_COUNT.
Suggested solution(s)
There are two ways to fix this architecture limitation:
Option 1: Modify the macro to accept explicit array indices (Recommended)
Update timer_impl.h to decouple the Timer Number from the Array Index:
#define _TIM_IRQ_HANDLER_IDX(name, i, ctxIdx) \
void name(void) \
{ \
impl_timerCaptureCompareHandler(TIM ## i, timerCtx[ctxIdx]); \
} struct dummyThen in timer_stm32h7xx.c (and potentially others like G4), explicitly pass the index that matches timerDefinitions[]:
// Assuming TIM17 is at index 13 in timerDefinitions