From a6a269697246f9c8aea005a2c06672b019242a6d Mon Sep 17 00:00:00 2001 From: "nilesh.kale" Date: Wed, 11 Mar 2026 11:00:15 +0530 Subject: [PATCH] fix(cpu_region_protect): set DROM mask PMP entry to read-only PMP entry 3 (SOC_DROM_MASK_HIGH, TOR mode) in the memprot path was incorrectly granted RW permission on esp32h21 and esp32c61. The mask ROM data region is inherently read-only; remove the W bit. Also added necessary tests to check voilations and re-enabled tests for ESP32P4 --- .../port/esp32c61/cpu_region_protect.c | 2 +- .../port/esp32h21/cpu_region_protect.c | 2 +- .../system/panic/main/include/test_memprot.h | 6 ++++ .../system/panic/main/test_app_main.c | 4 +++ .../system/panic/main/test_memprot.c | 19 ++++++++++++- tools/test_apps/system/panic/pytest_panic.py | 28 +++++++++++++++++++ 6 files changed, 58 insertions(+), 3 deletions(-) diff --git a/components/esp_hw_support/port/esp32c61/cpu_region_protect.c b/components/esp_hw_support/port/esp32c61/cpu_region_protect.c index 73b9078c8c..050d3dfa6b 100644 --- a/components/esp_hw_support/port/esp32c61/cpu_region_protect.c +++ b/components/esp_hw_support/port/esp32c61/cpu_region_protect.c @@ -147,7 +147,7 @@ void esp_cpu_configure_region_protection(void) if ((drom_start & (SOC_CPU_PMP_REGION_GRANULARITY - 1)) == 0) { PMP_ENTRY_SET(1, SOC_IROM_MASK_LOW, NONE); PMP_ENTRY_SET(2, drom_start, PMP_TOR | RX); - PMP_ENTRY_SET(3, SOC_DROM_MASK_HIGH, PMP_TOR | RW); + PMP_ENTRY_SET(3, SOC_DROM_MASK_HIGH, PMP_TOR | R); } else #endif { diff --git a/components/esp_hw_support/port/esp32h21/cpu_region_protect.c b/components/esp_hw_support/port/esp32h21/cpu_region_protect.c index 03aabcb981..3ad86e928f 100644 --- a/components/esp_hw_support/port/esp32h21/cpu_region_protect.c +++ b/components/esp_hw_support/port/esp32h21/cpu_region_protect.c @@ -139,7 +139,7 @@ void esp_cpu_configure_region_protection(void) PMP_ENTRY_CFG_RESET(3); PMP_ENTRY_SET(1, SOC_IROM_MASK_LOW, NONE); PMP_ENTRY_SET(2, drom_start, PMP_TOR | RX); - PMP_ENTRY_SET(3, SOC_DROM_MASK_HIGH, PMP_TOR | RW); + PMP_ENTRY_SET(3, SOC_DROM_MASK_HIGH, PMP_TOR | R); } else #endif { diff --git a/tools/test_apps/system/panic/main/include/test_memprot.h b/tools/test_apps/system/panic/main/include/test_memprot.h index e3e0dc40af..ed084b43c8 100644 --- a/tools/test_apps/system/panic/main/include/test_memprot.h +++ b/tools/test_apps/system/panic/main/include/test_memprot.h @@ -63,6 +63,12 @@ void test_spiram_xip_irom_alignment_reg_execute_violation(void); void test_spiram_xip_drom_alignment_reg_execute_violation(void); +void test_irom_mask_reg_write_violation(void); + +#ifdef SOC_DROM_MASK_HIGH +void test_drom_mask_reg_write_violation(void); +#endif + void test_drom_reg_write_violation(void); void test_drom_reg_execute_violation(void); diff --git a/tools/test_apps/system/panic/main/test_app_main.c b/tools/test_apps/system/panic/main/test_app_main.c index a50cb8e0ba..c0c86d64a9 100644 --- a/tools/test_apps/system/panic/main/test_app_main.c +++ b/tools/test_apps/system/panic/main/test_app_main.c @@ -188,6 +188,10 @@ void app_main(void) #if CONFIG_ESP_SYSTEM_MEMPROT HANDLE_TEST(test_name, test_irom_reg_write_violation); + HANDLE_TEST(test_name, test_irom_mask_reg_write_violation); +#ifdef SOC_DROM_MASK_HIGH + HANDLE_TEST(test_name, test_drom_mask_reg_write_violation); +#endif HANDLE_TEST(test_name, test_drom_reg_write_violation); HANDLE_TEST(test_name, test_drom_reg_execute_violation); diff --git a/tools/test_apps/system/panic/main/test_memprot.c b/tools/test_apps/system/panic/main/test_memprot.c index 209809127a..420225405d 100644 --- a/tools/test_apps/system/panic/main/test_memprot.c +++ b/tools/test_apps/system/panic/main/test_memprot.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -299,6 +299,23 @@ void test_irom_reg_write_violation(void) *test_addr = RND_VAL; } +void test_irom_mask_reg_write_violation(void) +{ + uint32_t *test_addr = (uint32_t *)(SOC_IROM_MASK_LOW + 0x04); + printf("ROM (IROM Mask): Write operation | Address: %p\n", test_addr); + *test_addr = RND_VAL; +} + +#ifdef SOC_DROM_MASK_HIGH +void test_drom_mask_reg_write_violation(void) +{ + uint32_t *test_addr = (uint32_t *)(SOC_DROM_MASK_HIGH - 0x04); + printf("ROM (DROM Mask): Write operation | Address: %p\n", test_addr); + *test_addr = RND_VAL; +} + +#endif + void test_drom_reg_write_violation(void) { uint32_t *test_addr = (uint32_t *)((uint32_t)(foo_buf)); diff --git a/tools/test_apps/system/panic/pytest_panic.py b/tools/test_apps/system/panic/pytest_panic.py index 3ffccee320..094c453b7a 100644 --- a/tools/test_apps/system/panic/pytest_panic.py +++ b/tools/test_apps/system/panic/pytest_panic.py @@ -1121,6 +1121,34 @@ def test_non_cache_irom_reg_write_violation(dut: PanicTestDut, test_func_name: s irom_reg_write_violation(dut, test_func_name) +def irom_mask_reg_write_violation(dut: PanicTestDut, test_func_name: str) -> None: + dut.run_test_func(test_func_name) + dut.expect_gme('Store access fault') + dut.expect_reg_dump(0) + dut.expect_cpu_reset() + + +@pytest.mark.generic +@pytest.mark.temp_skip_ci(targets=['esp32h21'], reason='lack of runners') +@idf_parametrize('config, target', CONFIGS_MEMPROT_FLASH_IDROM, indirect=['config', 'target']) +def test_irom_mask_reg_write_violation(dut: PanicTestDut, test_func_name: str) -> None: + irom_mask_reg_write_violation(dut, test_func_name) + + +def drom_mask_reg_write_violation(dut: PanicTestDut, test_func_name: str) -> None: + dut.run_test_func(test_func_name) + dut.expect_gme('Store access fault') + dut.expect_reg_dump(0) + dut.expect_cpu_reset() + + +@pytest.mark.generic +@pytest.mark.temp_skip_ci(targets=['esp32h21'], reason='lack of runners') +@idf_parametrize('config, target', CONFIGS_MEMPROT_FLASH_IDROM, indirect=['config', 'target']) +def test_drom_mask_reg_write_violation(dut: PanicTestDut, test_func_name: str) -> None: + drom_mask_reg_write_violation(dut, test_func_name) + + def drom_reg_write_violation(dut: PanicTestDut, test_func_name: str) -> None: dut.run_test_func(test_func_name) dut.expect_gme('Store access fault')