fix(sdmmc): Validate DMA buffer address range

Closes https://github.com/espressif/esp-idf/issues/18714
This commit is contained in:
Adam Múdry
2026-07-28 15:38:11 +02:00
parent 0f2ce91f14
commit 3543dcf016
9 changed files with 106 additions and 23 deletions
@@ -16,6 +16,7 @@ endif()
set(priv_requires "sdmmc"
"esp_driver_sdmmc"
"esp_psram"
"sdmmc_test_boards"
"common_test_flows"
"unity"
@@ -6,6 +6,7 @@
#include <stdio.h>
#include <stddef.h>
#include "unity.h"
#include "esp_psram.h"
#include "sdmmc_cmd.h"
#include "sdmmc_test_begin_end_sd.h"
#include "sdmmc_test_rw_common.h"
@@ -135,6 +136,10 @@ static void do_one_sdmmc_rw_test_psram_dma_buffer(int slot, int width)
int freq_khz = SDMMC_FREQ_HIGHSPEED;
#if !CONFIG_SPIRAM
TEST_IGNORE_MESSAGE("PSRAM is not enabled");
#else
if (!esp_psram_is_initialized()) {
TEST_IGNORE_MESSAGE("PSRAM is not available");
}
#endif
sdmmc_test_sd_skip_if_board_incompatible(slot, width, freq_khz, NO_DDR, NO_EMMC);
sdmmc_test_sd_begin(slot, width, freq_khz, 0, &card);
@@ -1,4 +1,4 @@
set(srcs "test_app_main.c" "test_sd_driver_resource.c")
set(srcs "test_app_main.c" "test_sd_driver_resource.c" "test_sdmmc_buffer.c")
set(priv_requires
# tests reside in this component, also available for `sdmmc_console`
@@ -0,0 +1,49 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include "sdkconfig.h"
#include "unity.h"
#include "esp_private/sd_host_buffer.h"
#include "soc/soc.h"
#include "esp_heap_caps.h"
#include "esp_memory_utils.h"
#include "esp_psram.h"
#if SOC_RTC_FAST_MEM_SUPPORTED
TEST_CASE("SDMMC rejects an RTC fast RAM DMA buffer", "[sdmmc]")
{
const size_t buffer_size = 512;
void *internal_dma_buf = heap_caps_malloc(buffer_size, MALLOC_CAP_DMA | MALLOC_CAP_CACHE_ALIGNED);
const size_t offset = 0x20;
const void *rtc_fast_ram_buf = (const void *)(SOC_RTC_DRAM_LOW + offset);
TEST_ASSERT_NOT_NULL(internal_dma_buf);
TEST_ASSERT_TRUE(sd_host_check_buffer_alignment(NULL, internal_dma_buf, buffer_size));
TEST_ASSERT_FALSE(sd_host_check_buffer_alignment(NULL, rtc_fast_ram_buf, buffer_size));
TEST_ASSERT_FALSE(sd_host_check_buffer_alignment(NULL, (const void *)(UINTPTR_MAX - 255), buffer_size));
heap_caps_free(internal_dma_buf);
}
#endif
#if CONFIG_SPIRAM && !SOC_SDMMC_PSRAM_DMA_CAPABLE
TEST_CASE("SDMMC rejects a PSRAM buffer when PSRAM is not DMA capable", "[sdmmc]")
{
const size_t buffer_size = 512;
if (!esp_psram_is_initialized()) {
TEST_IGNORE_MESSAGE("PSRAM is not available");
}
void *psram_buf = heap_caps_malloc(buffer_size, MALLOC_CAP_SPIRAM | MALLOC_CAP_CACHE_ALIGNED);
TEST_ASSERT_NOT_NULL(psram_buf);
TEST_ASSERT_TRUE(esp_ptr_external_ram(psram_buf));
TEST_ASSERT_FALSE(sd_host_check_buffer_alignment(NULL, psram_buf, buffer_size));
heap_caps_free(psram_buf);
}
#endif
@@ -0,0 +1,2 @@
CONFIG_SPIRAM=y
CONFIG_SPIRAM_IGNORE_NOTFOUND=y
@@ -0,0 +1,2 @@
CONFIG_SPIRAM=y
CONFIG_SPIRAM_IGNORE_NOTFOUND=y