From b77016e350f7fc19df3cfadd09141eaba236e36c Mon Sep 17 00:00:00 2001 From: Laukik Hase Date: Wed, 15 Jul 2026 13:12:23 +0530 Subject: [PATCH] fix(esp_tee): Validate REE-supplied memory bounds (`esp_tee_app_config`) before use --- .../main/include/esp_tee_memory_utils.h | 23 ++++++-------- .../soc/esp32c5/esp_tee_pmp_pma_prot_cfg.c | 29 +++++++++++------- .../soc/esp32c6/esp_tee_pmp_pma_prot_cfg.c | 30 ++++++++++++------- .../soc/esp32c61/esp_tee_pmp_pma_prot_cfg.c | 29 +++++++++++------- .../soc/esp32h2/esp_tee_pmp_pma_prot_cfg.c | 30 ++++++++++++------- 5 files changed, 85 insertions(+), 56 deletions(-) diff --git a/components/esp_tee/subproject/main/include/esp_tee_memory_utils.h b/components/esp_tee/subproject/main/include/esp_tee_memory_utils.h index e3ec2f50dfa..0d52b8fc636 100644 --- a/components/esp_tee/subproject/main/include/esp_tee_memory_utils.h +++ b/components/esp_tee/subproject/main/include/esp_tee_memory_utils.h @@ -16,19 +16,9 @@ extern "C" { #endif -FORCE_INLINE_ATTR bool esp_tee_ptr_in_ree(const void *p) -{ - uintptr_t addr = (uintptr_t)p; - return ( - (addr >= SOC_NS_IDRAM_START && addr < SOC_NS_IDRAM_END) || - (addr >= (uintptr_t)esp_tee_app_config.ns_drom_start && - addr < SOC_S_MMU_MMAP_RESV_START_VADDR) -#if SOC_RTC_MEM_SUPPORTED - || (addr >= SOC_RTC_DATA_LOW && addr < SOC_RTC_DATA_HIGH) -#endif - ); -} - +/* TODO: Revisit these bounds for high-performance RISC-V SoCs (e.g. ESP32-P4, + * ESP32-S31) with different memory maps than current ESP-TEE targets. + */ FORCE_INLINE_ATTR bool esp_tee_buf_in_ree(const void *p, size_t len) { uintptr_t start = (uintptr_t)p; @@ -40,13 +30,18 @@ FORCE_INLINE_ATTR bool esp_tee_buf_in_ree(const void *p, size_t len) uintptr_t end = start + len; return ((start >= SOC_NS_IDRAM_START && end <= SOC_NS_IDRAM_END) || - (start >= (uintptr_t)esp_tee_app_config.ns_drom_start && end <= SOC_S_MMU_MMAP_RESV_START_VADDR) + (start >= SOC_S_DROM_HIGH && end <= SOC_S_MMU_MMAP_RESV_START_VADDR) #if SOC_RTC_MEM_SUPPORTED || (start >= SOC_RTC_DATA_LOW && end <= SOC_RTC_DATA_HIGH) #endif ); } +FORCE_INLINE_ATTR bool esp_tee_ptr_in_ree(const void *p) +{ + return esp_tee_buf_in_ree(p, 4); +} + #ifdef __cplusplus } #endif diff --git a/components/esp_tee/subproject/main/soc/esp32c5/esp_tee_pmp_pma_prot_cfg.c b/components/esp_tee/subproject/main/soc/esp32c5/esp_tee_pmp_pma_prot_cfg.c index f7d47af6365..3947a6e72f2 100644 --- a/components/esp_tee/subproject/main/soc/esp32c5/esp_tee_pmp_pma_prot_cfg.c +++ b/components/esp_tee/subproject/main/soc/esp32c5/esp_tee_pmp_pma_prot_cfg.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -55,9 +55,9 @@ static void esp_tee_configure_invalid_regions(void) // 7. Using PMA to configure the TEE text and data section access attribute. */ PMA_ENTRY_CFG_RESET(12); - assert(IS_PMA_ENTRY_UNLOCKED(13)); - assert(IS_PMA_ENTRY_UNLOCKED(14)); - assert(IS_PMA_ENTRY_UNLOCKED(15)); + ESP_FAULT_ASSERT(IS_PMA_ENTRY_UNLOCKED(13) && + IS_PMA_ENTRY_UNLOCKED(14) && + IS_PMA_ENTRY_UNLOCKED(15)); extern int _tee_iram_end; PMA_RESET_AND_ENTRY_SET_TOR(13, SOC_S_IRAM_START, PMA_NONE); @@ -122,6 +122,20 @@ void esp_tee_configure_region_protection(void) PMP_ENTRY_CFG_RESET(4); PMP_ENTRY_CFG_RESET(5); PMP_ENTRY_CFG_RESET(6); + /* Validate the REE-supplied (esp_tee_app_config) bounds before programming + * the TOR-chained PMP entries below */ + const uint32_t ns_iram_end = (uint32_t)esp_tee_app_config.ns_iram_end; + const uint32_t s_irom_resv_end = SOC_IROM_LOW + CONFIG_SECURE_TEE_IROM_SIZE + CONFIG_SECURE_TEE_DROM_SIZE; + const uint32_t ns_irom_resv_end = ALIGN_UP_TO_MMU_PAGE_SIZE((uint32_t)esp_tee_app_config.ns_irom_end); + const uint32_t ns_drom_resv_end = ALIGN_UP_TO_MMU_PAGE_SIZE((uint32_t)esp_tee_app_config.ns_drom_end); + const uint32_t ns_drom_mmap_end = (uint32_t)(SOC_S_MMU_MMAP_RESV_START_VADDR); + + ESP_FAULT_ASSERT(ns_iram_end >= SOC_NS_IRAM_START && + ns_iram_end <= SOC_DRAM_HIGH && + s_irom_resv_end <= ns_irom_resv_end && + ns_irom_resv_end <= ns_drom_resv_end && + ns_drom_resv_end <= ns_drom_mmap_end); + if (esp_cpu_dbgr_is_attached()) { // Anti-FI check that cpu is really in ocd mode ESP_FAULT_ASSERT(esp_cpu_dbgr_is_attached()); @@ -131,15 +145,10 @@ void esp_tee_configure_region_protection(void) } else { // REE SRAM (D/IRAM) PMP_ENTRY_SET(4, (int)SOC_NS_IRAM_START, NONE); - PMP_ENTRY_SET(5, (int)esp_tee_app_config.ns_iram_end, PMP_TOR | RX); + PMP_ENTRY_SET(5, (int)ns_iram_end, PMP_TOR | RX); PMP_ENTRY_SET(6, SOC_DRAM_HIGH, PMP_TOR | RW); } - const uint32_t s_irom_resv_end = SOC_IROM_LOW + CONFIG_SECURE_TEE_IROM_SIZE + CONFIG_SECURE_TEE_DROM_SIZE; - const uint32_t ns_irom_resv_end = ALIGN_UP_TO_MMU_PAGE_SIZE((uint32_t)esp_tee_app_config.ns_irom_end); - const uint32_t ns_drom_resv_end = ALIGN_UP_TO_MMU_PAGE_SIZE((uint32_t)esp_tee_app_config.ns_drom_end); - const uint32_t ns_drom_mmap_end = (uint32_t)(SOC_S_MMU_MMAP_RESV_START_VADDR); - // 4. I_Cache / D_Cache (flash) - REE PMP_ENTRY_CFG_RESET(7); PMP_ENTRY_CFG_RESET(8); diff --git a/components/esp_tee/subproject/main/soc/esp32c6/esp_tee_pmp_pma_prot_cfg.c b/components/esp_tee/subproject/main/soc/esp32c6/esp_tee_pmp_pma_prot_cfg.c index bea234af031..4f977647f59 100644 --- a/components/esp_tee/subproject/main/soc/esp32c6/esp_tee_pmp_pma_prot_cfg.c +++ b/components/esp_tee/subproject/main/soc/esp32c6/esp_tee_pmp_pma_prot_cfg.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -63,9 +63,9 @@ static void esp_tee_configure_invalid_regions(void) PMA_RESET_AND_ENTRY_SET_TOR(12, UINT32_MAX, PMA_TOR | PMA_NONE); // 8. Using PMA to configure the TEE text and data section access attribute. */ - assert(IS_PMA_ENTRY_UNLOCKED(13)); - assert(IS_PMA_ENTRY_UNLOCKED(14)); - assert(IS_PMA_ENTRY_UNLOCKED(15)); + ESP_FAULT_ASSERT(IS_PMA_ENTRY_UNLOCKED(13) && + IS_PMA_ENTRY_UNLOCKED(14) && + IS_PMA_ENTRY_UNLOCKED(15)); extern int _tee_iram_end; PMA_RESET_AND_ENTRY_SET_TOR(13, SOC_S_IRAM_START, PMA_NONE); @@ -112,7 +112,20 @@ void esp_tee_configure_region_protection(void) PMP_ENTRY_SET(1, SOC_IROM_MASK_HIGH, PMP_TOR | RX); _Static_assert(SOC_IROM_MASK_LOW < SOC_IROM_MASK_HIGH, "Invalid I/D-ROM region"); - /* TODO: Check whether changes are required here */ + /* Validate the REE-supplied (esp_tee_app_config) bounds before programming + * the TOR-chained PMP entries below */ + const uint32_t ns_iram_end = (uint32_t)esp_tee_app_config.ns_iram_end; + const uint32_t s_irom_resv_end = SOC_IROM_LOW + CONFIG_SECURE_TEE_IROM_SIZE + CONFIG_SECURE_TEE_DROM_SIZE; + const uint32_t ns_irom_resv_end = ALIGN_UP_TO_MMU_PAGE_SIZE((uint32_t)esp_tee_app_config.ns_irom_end); + const uint32_t ns_drom_resv_end = ALIGN_UP_TO_MMU_PAGE_SIZE((uint32_t)esp_tee_app_config.ns_drom_end); + const uint32_t ns_drom_mmap_end = (uint32_t)(SOC_S_MMU_MMAP_RESV_START_VADDR); + + ESP_FAULT_ASSERT(ns_iram_end >= SOC_NS_IRAM_START && + ns_iram_end <= SOC_DRAM_HIGH && + s_irom_resv_end <= ns_irom_resv_end && + ns_irom_resv_end <= ns_drom_resv_end && + ns_drom_resv_end <= ns_drom_mmap_end); + if (esp_cpu_dbgr_is_attached()) { // Anti-FI check that cpu is really in ocd mode ESP_FAULT_ASSERT(esp_cpu_dbgr_is_attached()); @@ -125,15 +138,10 @@ void esp_tee_configure_region_protection(void) // 2. IRAM and DRAM // Splitting the REE SRAM region into IRAM and DRAM PMP_ENTRY_SET(2, (int)SOC_NS_IRAM_START, NONE); - PMP_ENTRY_SET(3, (int)esp_tee_app_config.ns_iram_end, PMP_TOR | RX); + PMP_ENTRY_SET(3, (int)ns_iram_end, PMP_TOR | RX); PMP_ENTRY_SET(4, SOC_DRAM_HIGH, PMP_TOR | RW); } - const uint32_t s_irom_resv_end = SOC_IROM_LOW + CONFIG_SECURE_TEE_IROM_SIZE + CONFIG_SECURE_TEE_DROM_SIZE; - const uint32_t ns_irom_resv_end = ALIGN_UP_TO_MMU_PAGE_SIZE((uint32_t)esp_tee_app_config.ns_irom_end); - const uint32_t ns_drom_resv_end = ALIGN_UP_TO_MMU_PAGE_SIZE((uint32_t)esp_tee_app_config.ns_drom_end); - const uint32_t ns_drom_mmap_end = (uint32_t)(SOC_S_MMU_MMAP_RESV_START_VADDR); - // 4. I_Cache / D_Cache (flash) - REE PMP_ENTRY_CFG_RESET(5); PMP_ENTRY_CFG_RESET(6); diff --git a/components/esp_tee/subproject/main/soc/esp32c61/esp_tee_pmp_pma_prot_cfg.c b/components/esp_tee/subproject/main/soc/esp32c61/esp_tee_pmp_pma_prot_cfg.c index 26c8116cf94..a574db48a7a 100644 --- a/components/esp_tee/subproject/main/soc/esp32c61/esp_tee_pmp_pma_prot_cfg.c +++ b/components/esp_tee/subproject/main/soc/esp32c61/esp_tee_pmp_pma_prot_cfg.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -55,9 +55,9 @@ static void esp_cpu_configure_invalid_regions(void) // 8. Using PMA to configure the TEE text and data section access attribute. */ PMA_ENTRY_CFG_RESET(12); - assert(IS_PMA_ENTRY_UNLOCKED(13)); - assert(IS_PMA_ENTRY_UNLOCKED(14)); - assert(IS_PMA_ENTRY_UNLOCKED(15)); + ESP_FAULT_ASSERT(IS_PMA_ENTRY_UNLOCKED(13) && + IS_PMA_ENTRY_UNLOCKED(14) && + IS_PMA_ENTRY_UNLOCKED(15)); extern int _tee_iram_end; PMA_RESET_AND_ENTRY_SET_TOR(13, SOC_S_IRAM_START, PMA_NONE); @@ -121,6 +121,20 @@ void esp_tee_configure_region_protection(void) PMP_ENTRY_CFG_RESET(4); PMP_ENTRY_CFG_RESET(5); PMP_ENTRY_CFG_RESET(6); + /* Validate the REE-supplied (esp_tee_app_config) bounds before programming + * the TOR-chained PMP entries below */ + const uint32_t ns_iram_end = (uint32_t)esp_tee_app_config.ns_iram_end; + const uint32_t s_irom_resv_end = SOC_IROM_LOW + CONFIG_SECURE_TEE_IROM_SIZE + CONFIG_SECURE_TEE_DROM_SIZE; + const uint32_t ns_irom_resv_end = ALIGN_UP_TO_MMU_PAGE_SIZE((uint32_t)esp_tee_app_config.ns_irom_end); + const uint32_t ns_drom_resv_end = ALIGN_UP_TO_MMU_PAGE_SIZE((uint32_t)esp_tee_app_config.ns_drom_end); + const uint32_t ns_drom_mmap_end = (uint32_t)(SOC_S_MMU_MMAP_RESV_START_VADDR); + + ESP_FAULT_ASSERT(ns_iram_end >= SOC_NS_IRAM_START && + ns_iram_end <= SOC_DRAM_HIGH && + s_irom_resv_end <= ns_irom_resv_end && + ns_irom_resv_end <= ns_drom_resv_end && + ns_drom_resv_end <= ns_drom_mmap_end); + if (esp_cpu_dbgr_is_attached()) { // Anti-FI check that cpu is really in ocd mode ESP_FAULT_ASSERT(esp_cpu_dbgr_is_attached()); @@ -130,15 +144,10 @@ void esp_tee_configure_region_protection(void) } else { // REE SRAM (D/IRAM) PMP_ENTRY_SET(4, (int)SOC_NS_IRAM_START, NONE); - PMP_ENTRY_SET(5, (int)esp_tee_app_config.ns_iram_end, PMP_TOR | RX); + PMP_ENTRY_SET(5, (int)ns_iram_end, PMP_TOR | RX); PMP_ENTRY_SET(6, SOC_DRAM_HIGH, PMP_TOR | RW); } - const uint32_t s_irom_resv_end = SOC_IROM_LOW + CONFIG_SECURE_TEE_IROM_SIZE + CONFIG_SECURE_TEE_DROM_SIZE; - const uint32_t ns_irom_resv_end = ALIGN_UP_TO_MMU_PAGE_SIZE((uint32_t)esp_tee_app_config.ns_irom_end); - const uint32_t ns_drom_resv_end = ALIGN_UP_TO_MMU_PAGE_SIZE((uint32_t)esp_tee_app_config.ns_drom_end); - const uint32_t ns_drom_mmap_end = (uint32_t)(SOC_S_MMU_MMAP_RESV_START_VADDR); - // 4. I_Cache / D_Cache (flash) - REE PMP_ENTRY_CFG_RESET(7); PMP_ENTRY_CFG_RESET(8); diff --git a/components/esp_tee/subproject/main/soc/esp32h2/esp_tee_pmp_pma_prot_cfg.c b/components/esp_tee/subproject/main/soc/esp32h2/esp_tee_pmp_pma_prot_cfg.c index 8de916768ce..5c7d3acd54b 100644 --- a/components/esp_tee/subproject/main/soc/esp32h2/esp_tee_pmp_pma_prot_cfg.c +++ b/components/esp_tee/subproject/main/soc/esp32h2/esp_tee_pmp_pma_prot_cfg.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -65,9 +65,9 @@ static void esp_tee_configure_invalid_regions(void) PMA_ENTRY_SET_TOR(12, UINT32_MAX, PMA_TOR | PMA_NONE); /* 8. Using PMA to configure the TEE text and data section access attribute. */ - assert(IS_PMA_ENTRY_UNLOCKED(13)); - assert(IS_PMA_ENTRY_UNLOCKED(14)); - assert(IS_PMA_ENTRY_UNLOCKED(15)); + ESP_FAULT_ASSERT(IS_PMA_ENTRY_UNLOCKED(13) && + IS_PMA_ENTRY_UNLOCKED(14) && + IS_PMA_ENTRY_UNLOCKED(15)); extern int _tee_iram_end; PMA_RESET_AND_ENTRY_SET_TOR(13, SOC_S_IRAM_START, PMA_NONE); @@ -108,7 +108,20 @@ void esp_tee_configure_region_protection(void) PMP_ENTRY_SET(0, pmpaddr0, PMP_NAPOT | RX); _Static_assert(SOC_IROM_MASK_LOW < SOC_IROM_MASK_HIGH, "Invalid I/D-ROM region"); - /* TODO: Check whether changes are required here */ + /* Validate the REE-supplied (esp_tee_app_config) bounds before programming + * the TOR-chained PMP entries below */ + const uint32_t ns_iram_end = (uint32_t)esp_tee_app_config.ns_iram_end; + const uint32_t s_irom_resv_end = SOC_IROM_LOW + CONFIG_SECURE_TEE_IROM_SIZE + CONFIG_SECURE_TEE_DROM_SIZE; + const uint32_t ns_irom_resv_end = ALIGN_UP_TO_MMU_PAGE_SIZE((uint32_t)esp_tee_app_config.ns_irom_end); + const uint32_t ns_drom_resv_end = ALIGN_UP_TO_MMU_PAGE_SIZE((uint32_t)esp_tee_app_config.ns_drom_end); + const uint32_t ns_drom_mmap_end = (uint32_t)(SOC_S_MMU_MMAP_RESV_START_VADDR); + + ESP_FAULT_ASSERT(ns_iram_end >= SOC_NS_IRAM_START && + ns_iram_end <= SOC_DRAM_HIGH && + s_irom_resv_end <= ns_irom_resv_end && + ns_irom_resv_end <= ns_drom_resv_end && + ns_drom_resv_end <= ns_drom_mmap_end); + if (esp_cpu_dbgr_is_attached()) { // Anti-FI check that cpu is really in ocd mode ESP_FAULT_ASSERT(esp_cpu_dbgr_is_attached()); @@ -121,15 +134,10 @@ void esp_tee_configure_region_protection(void) // 2. IRAM and DRAM // Splitting the REE SRAM region into IRAM and DRAM PMP_ENTRY_SET(1, (int)SOC_NS_IRAM_START, NONE); - PMP_ENTRY_SET(2, (int)esp_tee_app_config.ns_iram_end, PMP_TOR | RX); + PMP_ENTRY_SET(2, (int)ns_iram_end, PMP_TOR | RX); PMP_ENTRY_SET(3, SOC_DRAM_HIGH, PMP_TOR | RW); } - const uint32_t s_irom_resv_end = SOC_IROM_LOW + CONFIG_SECURE_TEE_IROM_SIZE + CONFIG_SECURE_TEE_DROM_SIZE; - const uint32_t ns_irom_resv_end = ALIGN_UP_TO_MMU_PAGE_SIZE((uint32_t)esp_tee_app_config.ns_irom_end); - const uint32_t ns_drom_resv_end = ALIGN_UP_TO_MMU_PAGE_SIZE((uint32_t)esp_tee_app_config.ns_drom_end); - const uint32_t ns_drom_mmap_end = (uint32_t)(SOC_S_MMU_MMAP_RESV_START_VADDR); - // 4. I_Cache / D_Cache (flash) - REE PMP_ENTRY_CFG_RESET(5); PMP_ENTRY_CFG_RESET(6);