fix(core): pwm_data[] buffer clear check fix
What changed, and why it matters
This commit fixes a small logic bug in the Trezor hardware wallet's screen backlight driver for STM32U5 devices. The driver uses a two-element buffer (pwm_data[][0] and pwm_data[][1]) to send pulse values to a backlight power chip (TPS61062). The old code only checked whether the first element was 'empty' (set to UINT16_MAX) before deciding to clear the buffer, ignoring the second element. This meant the buffer could fail to be cleared when it should have been, potentially leaving stale pulse values and causing incorrect backlight behavior or visual glitches during brightness transitions.
Treat as a functional bug fix with low security impact. Include in normal firmware release testing; verify backlight fade/brightness transitions remain smooth. No urgent security response is indicated by the diff alone, but firmware integrity and supply-chain controls should ensure this patch is included in builds.
Security signals we found
Incorrect buffer-clear predicate in DMA backlight driver
Stale PWM data element could be transmitted to TPS61062 backlight IC
Hardware peripheral driver bug with potential device behavior side effects
No explicit security framing or CVE in commit message
Evidence from the diff
In core/embed/io/backlight/stm32u5/tps61062.c, the DMA transfer-complete callback decides whether to clear the prepare buffer by checking if the requested duty cycle differs from the latched one OR if pwm_data[prepare_buf_idx][0] != UINT16_MAX. The fix adds an OR check for pwm_data[prepare_buf_idx][1] != UINT16_MAX. Previously, if element [0] happened to be UINT16_MAX but element [1] was not, the buffer-clear branch would be skipped, leaving element [1] uncleared. Because both elements are used when programming new pulse values to the TPS61062, the stale [1] value could be transmitted, leading to incorrect backlight timing/duty output.
Changed components
core/embed/io/backlight/stm32u5/tps61062.cTrezor Model Safe hardware backlight driver (STM32U5)TPS61062 backlight/boost IC control pathInspect captured patch +2 / −1
diff --git a/core/embed/io/backlight/stm32u5/tps61062.c b/core/embed/io/backlight/stm32u5/tps61062.c
index 7c008a9d..3d78c477 100644
--- a/core/embed/io/backlight/stm32u5/tps61062.c
+++ b/core/embed/io/backlight/stm32u5/tps61062.c
@@ -634,7 +634,8 @@ static void DMA_XferCpltCallback(DMA_HandleTypeDef *hdma) {
// transfer
if (drv->requested_step_duty_cycle !=
drv->latched_step_duty_cycle[drv->prepare_buf_idx] ||
- drv->pwm_data[drv->prepare_buf_idx][0] != UINT16_MAX) {
+ (drv->pwm_data[drv->prepare_buf_idx][0] != UINT16_MAX ||
+ drv->pwm_data[drv->prepare_buf_idx][1] != UINT16_MAX)) {
// Clear the buffer
memset(drv->pwm_data[drv->prepare_buf_idx], UINT8_MAX,
sizeof(drv->pwm_data[drv->prepare_buf_idx]));
Why this scored 31/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.