Skip to content

Commit b51e744

Browse files
WonderMrclaude
andcommitted
spi/heap: address Copilot review feedback on #4360
furi_hal_spi.c (TX-only DMA path): On timeout the cleanup unconditionally released spi_dma_completed while LL_DMA_DisableIT_TC was issued *after*. A late or pending DMA completion ISR would then call furi_semaphore_release() on an already full binary semaphore and crash furi_check. Disable TC IRQ and clear the pending TC flag before releasing the semaphore so the ISR cannot double-release. memmgr_heap.c (memmgr_heap_get_block_size): Add heapVALIDATE_BLOCK_POINTER(pxLink) to match vPortFree(). Without it a caller passing an invalid pointer through this public API would read out of bounds before the configASSERT fires. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 06b1992 commit b51e744

2 files changed

Lines changed: 12 additions & 1 deletion

File tree

furi/core/memmgr_heap.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,7 @@ size_t memmgr_heap_get_block_size(void* pv) {
550550
puc -= xHeapStructSize;
551551
pxLink = (void*)puc;
552552

553+
heapVALIDATE_BLOCK_POINTER(pxLink);
553554
configASSERT(heapBLOCK_IS_ALLOCATED(pxLink) != 0);
554555

555556
return (pxLink->xBlockSize & ~heapBLOCK_ALLOCATED_BITMASK) - xHeapStructSize;

targets/f7/furi_hal/furi_hal_spi.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,10 +297,20 @@ bool furi_hal_spi_bus_trx_dma(
297297
ret = false;
298298
FURI_LOG_E(TAG, "DMA timeout\r\n");
299299
}
300+
301+
// Disable TC IRQ and clear pending TC flag BEFORE releasing the
302+
// semaphore. On timeout the ISR may still fire and would try to
303+
// re-release the binary semaphore, crashing furi_check.
304+
LL_DMA_DisableIT_TC(SPI_DMA_RX_DEF);
305+
#if SPI_DMA_RX_CHANNEL == LL_DMA_CHANNEL_6
306+
LL_DMA_ClearFlag_TC6(SPI_DMA);
307+
#else
308+
#error Update this code. Would you kindly?
309+
#endif
310+
300311
// release semaphore, because we are using it as a flag
301312
furi_semaphore_release(spi_dma_completed);
302313

303-
LL_DMA_DisableIT_TC(SPI_DMA_RX_DEF);
304314
LL_DMA_DisableChannel(SPI_DMA_TX_DEF);
305315
LL_DMA_DisableChannel(SPI_DMA_RX_DEF);
306316
if(!dma_tx_was_enabled) {

0 commit comments

Comments
 (0)