Skip to content

Commit 731f7ad

Browse files
projectgusdpgeorge
authored andcommitted
stm32/sdcard: Fix unchecked uint32_t overflow in SD card driver.
Manifests as `readblocks(-1, buf)` failing. The ST HAL does a bounds check, but it checks `(block_num + num_blocks)` is within bounds, so if these values overflow then it allows the read which seems to hang some SD Cards (but not all). Fix by explicitly testing for overflow in our layer of the driver. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <[email protected]>
1 parent 8ce7a58 commit 731f7ad

File tree

1 file changed

+19
-7
lines changed

1 file changed

+19
-7
lines changed

ports/stm32/sdcard.c

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -498,13 +498,27 @@ static HAL_StatusTypeDef sdcard_wait_finished(uint32_t timeout) {
498498
return HAL_OK;
499499
}
500500

501-
mp_uint_t sdcard_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks) {
501+
static HAL_StatusTypeDef sdcard_common_checks(uint32_t block_num, uint32_t num_blocks) {
502502
// check that SD card is initialised
503503
if (!(pyb_sdmmc_flags & PYB_SDMMC_FLAG_ACTIVE)) {
504504
return HAL_ERROR;
505505
}
506506

507-
HAL_StatusTypeDef err = HAL_OK;
507+
// check that adding block_num & num_blocks don't overflow
508+
// (the ST HAL does a bounds check, but only after adding them...)
509+
uint32_t end_block;
510+
if (__builtin_add_overflow(block_num, num_blocks, &end_block)) {
511+
return HAL_ERROR;
512+
}
513+
514+
return HAL_OK;
515+
}
516+
517+
mp_uint_t sdcard_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks) {
518+
HAL_StatusTypeDef err = sdcard_common_checks(block_num, num_blocks);
519+
if (err != HAL_OK) {
520+
return err;
521+
}
508522

509523
// check that dest pointer is aligned on a 4-byte boundary
510524
uint8_t *orig_dest = NULL;
@@ -595,13 +609,11 @@ mp_uint_t sdcard_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blo
595609
}
596610

597611
mp_uint_t sdcard_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks) {
598-
// check that SD card is initialised
599-
if (!(pyb_sdmmc_flags & PYB_SDMMC_FLAG_ACTIVE)) {
600-
return HAL_ERROR;
612+
HAL_StatusTypeDef err = sdcard_common_checks(block_num, num_blocks);
613+
if (err != HAL_OK) {
614+
return err;
601615
}
602616

603-
HAL_StatusTypeDef err = HAL_OK;
604-
605617
// check that src pointer is aligned on a 4-byte boundary
606618
if (((uint32_t)src & 3) != 0) {
607619
// pointer is not aligned, so allocate a temporary block to do the write

0 commit comments

Comments
 (0)