diff --git a/components/esp_tee/test_apps/tee_test_fw/components/test_sec_srv/CMakeLists.txt b/components/esp_tee/test_apps/tee_test_fw/components/test_sec_srv/CMakeLists.txt index a93e6bc7ef..0dae5f2596 100644 --- a/components/esp_tee/test_apps/tee_test_fw/components/test_sec_srv/CMakeLists.txt +++ b/components/esp_tee/test_apps/tee_test_fw/components/test_sec_srv/CMakeLists.txt @@ -9,7 +9,8 @@ if(esp_tee_build) list(APPEND srcs "src/test_dummy_srv.c" "src/test_interrupt.c" "src/test_panic.c" - "src/test_sec_srv.c") + "src/test_sec_srv.c" + "src/test_heap.c") list(APPEND priv_requires main) else() list(APPEND srcs "src/test_dummy_srv_wrapper.c") diff --git a/components/esp_tee/test_apps/tee_test_fw/components/test_sec_srv/include/esp_tee_test.h b/components/esp_tee/test_apps/tee_test_fw/components/test_sec_srv/include/esp_tee_test.h index 705383e5fc..4874ccc5c7 100644 --- a/components/esp_tee/test_apps/tee_test_fw/components/test_sec_srv/include/esp_tee_test.h +++ b/components/esp_tee/test_apps/tee_test_fw/components/test_sec_srv/include/esp_tee_test.h @@ -38,6 +38,8 @@ void NOINLINE_ATTR dummy_secure_service(int a, int b, int c, int d, int e, int f uint32_t add_in_loop(uint32_t a, uint32_t b, uint32_t iter); +int _ss_esp_tee_test_heap_malloc_write_free(void); + #ifdef __cplusplus } #endif diff --git a/components/esp_tee/test_apps/tee_test_fw/components/test_sec_srv/sec_srv_tbl_test.yml b/components/esp_tee/test_apps/tee_test_fw/components/test_sec_srv/sec_srv_tbl_test.yml index 5945326e7a..d62238944a 100644 --- a/components/esp_tee/test_apps/tee_test_fw/components/test_sec_srv/sec_srv_tbl_test.yml +++ b/components/esp_tee/test_apps/tee_test_fw/components/test_sec_srv/sec_srv_tbl_test.yml @@ -69,3 +69,7 @@ secure_services: type: custom function: add_in_loop args: 3 + - id: 217 + type: custom + function: esp_tee_test_heap_malloc_write_free + args: 0 diff --git a/components/esp_tee/test_apps/tee_test_fw/components/test_sec_srv/src/test_heap.c b/components/esp_tee/test_apps/tee_test_fw/components/test_sec_srv/src/test_heap.c new file mode 100644 index 0000000000..457cb31e23 --- /dev/null +++ b/components/esp_tee/test_apps/tee_test_fw/components/test_sec_srv/src/test_heap.c @@ -0,0 +1,99 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "esp_rom_sys.h" +#include "multi_heap.h" +#include "esp_rom_tlsf.h" + +typedef struct { + int *ptr; + size_t size; +} alloc_block_t; + +static size_t try_malloc_write_free(void) +{ + size_t blk_sz = 512; + size_t max_blks = esp_tee_heap_get_free_size() / blk_sz; + size_t total_mem = 0; + + alloc_block_t *blocks = malloc(sizeof(alloc_block_t) * (max_blks + 1)); + if (!blocks) { + return -1; + } + + int n_blks = 0; + + // Attempt to allocate memory blocks and write to them + for (int i = 0; i < max_blks; i++) { + blocks[i].ptr = malloc(blk_sz); + if (!blocks[i].ptr) { + break; + } + blocks[i].size = blk_sz; + total_mem += blk_sz; + memset(blocks[i].ptr, 0xEF, blk_sz); + n_blks++; + } + + // Check if there is leftover memory that can be allocated + size_t left = esp_tee_heap_get_free_size(); + if (left > 24 && n_blks == max_blks) { + size_t rm_sz = left - 24; // Calculate remaining size to allocate + blocks[n_blks].ptr = malloc(rm_sz); + if (blocks[n_blks].ptr) { + blocks[n_blks].size = rm_sz; + total_mem += rm_sz; + memset(blocks[n_blks].ptr, 0xEF, rm_sz); + n_blks++; + } else { + esp_rom_printf("Failed to allocate leftover bytes\n"); + free(blocks); + return -1; + } + } + + int *ptr = malloc(blk_sz); + if (ptr) { + esp_rom_printf("Illegal allocation\n"); + free(blocks); + return -1; + } + + // Verify the integrity of allocated memory blocks + for (int i = 0; i < n_blks; i++) { + unsigned char *block_ptr = (unsigned char *)blocks[i].ptr; + for (size_t j = 0; j < blocks[i].size; j++) { + if (block_ptr[j] != 0xEF) { + esp_rom_printf("Corrupt heap\n"); + free(blocks); + return -1; + } + } + free(blocks[i].ptr); + } + + free(blocks); + return total_mem; +} + +int _ss_esp_tee_test_heap_malloc_write_free(void) +{ + size_t prev_sz = 0; + for (int i = 0; i < 3; i++) { + size_t cur_sz = try_malloc_write_free(); + if (cur_sz == -1) { + return -1; + } + + if (i > 0 && cur_sz != prev_sz) { + esp_rom_printf("Processed memory sizes differ between iterations!\n"); + return -1; + } + + prev_sz = cur_sz; + } + + return 0; +} diff --git a/components/esp_tee/test_apps/tee_test_fw/main/test_esp_tee_ctx_switch.c b/components/esp_tee/test_apps/tee_test_fw/main/test_esp_tee_ctx_switch.c index 474e2c3430..6534cf712f 100644 --- a/components/esp_tee/test_apps/tee_test_fw/main/test_esp_tee_ctx_switch.c +++ b/components/esp_tee/test_apps/tee_test_fw/main/test_esp_tee_ctx_switch.c @@ -95,3 +95,8 @@ TEST_CASE("Task switching during secure service calls", "[basic]") world = esp_cpu_get_curr_privilege_level(); TEST_ASSERT_MESSAGE((world == ESP_CPU_NS_MODE), "Current world is not NS"); } + +TEST_CASE("Test TEE Heap: Malloc-write-free cycles", "[heap]") +{ + TEST_ASSERT_EQUAL(0, esp_tee_service_call(1, SS_ESP_TEE_TEST_HEAP_MALLOC_WRITE_FREE)); +} diff --git a/components/esp_tee/test_apps/tee_test_fw/pytest_esp_tee_ut.py b/components/esp_tee/test_apps/tee_test_fw/pytest_esp_tee_ut.py index ec47009f7f..e4f574c69f 100644 --- a/components/esp_tee/test_apps/tee_test_fw/pytest_esp_tee_ut.py +++ b/components/esp_tee/test_apps/tee_test_fw/pytest_esp_tee_ut.py @@ -51,6 +51,7 @@ TEST_PARTITION_LABEL = 'test' @idf_parametrize('target', ['esp32c6'], indirect=['target']) def test_esp_tee(dut: IdfDut) -> None: dut.run_all_single_board_cases(group='basic') + dut.run_all_single_board_cases(group='heap') @pytest.mark.generic @@ -104,7 +105,7 @@ def test_esp_tee_apm_violation(dut: IdfDut) -> None: @idf_parametrize('target', ['esp32c6'], indirect=['target']) def test_esp_tee_illegal_instruction(dut: IdfDut) -> None: dut.expect_exact('Press ENTER to see the list of tests') - dut.write(f'"Test TEE-TEE violation: Illegal Instruction"') + dut.write('"Test TEE-TEE violation: Illegal Instruction"') exc = dut.expect(r'Core ([01]) panic\'ed \(([^)]+)\)', timeout=30).group(2).decode() if exc != 'Illegal instruction': raise RuntimeError('Incorrect exception received!')