Skip to content

Commit d26e18c

Browse files
committed
ci(esp_tee): Verify the malloc-write-free cycle in the TEE heap
1 parent 223c0d5 commit d26e18c

File tree

6 files changed

+114
-2
lines changed

6 files changed

+114
-2
lines changed

components/esp_tee/test_apps/tee_test_fw/components/test_sec_srv/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ if(esp_tee_build)
99
list(APPEND srcs "src/test_dummy_srv.c"
1010
"src/test_interrupt.c"
1111
"src/test_panic.c"
12-
"src/test_sec_srv.c")
12+
"src/test_sec_srv.c"
13+
"src/test_heap.c")
1314
list(APPEND priv_requires main)
1415
else()
1516
list(APPEND srcs "src/test_dummy_srv_wrapper.c")

components/esp_tee/test_apps/tee_test_fw/components/test_sec_srv/include/esp_tee_test.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ void NOINLINE_ATTR dummy_secure_service(int a, int b, int c, int d, int e, int f
3838

3939
uint32_t add_in_loop(uint32_t a, uint32_t b, uint32_t iter);
4040

41+
int _ss_esp_tee_test_heap_malloc_write_free(void);
42+
4143
#ifdef __cplusplus
4244
}
4345
#endif

components/esp_tee/test_apps/tee_test_fw/components/test_sec_srv/sec_srv_tbl_test.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,7 @@ secure_services:
6969
type: custom
7070
function: add_in_loop
7171
args: 3
72+
- id: 217
73+
type: custom
74+
function: esp_tee_test_heap_malloc_write_free
75+
args: 0
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
#include "esp_rom_sys.h"
7+
#include "multi_heap.h"
8+
#include "esp_rom_tlsf.h"
9+
10+
typedef struct {
11+
int *ptr;
12+
size_t size;
13+
} alloc_block_t;
14+
15+
static size_t try_malloc_write_free(void)
16+
{
17+
size_t blk_sz = 512;
18+
size_t max_blks = esp_tee_heap_get_free_size() / blk_sz;
19+
size_t total_mem = 0;
20+
21+
alloc_block_t *blocks = malloc(sizeof(alloc_block_t) * (max_blks + 1));
22+
if (!blocks) {
23+
return -1;
24+
}
25+
26+
int n_blks = 0;
27+
28+
// Attempt to allocate memory blocks and write to them
29+
for (int i = 0; i < max_blks; i++) {
30+
blocks[i].ptr = malloc(blk_sz);
31+
if (!blocks[i].ptr) {
32+
break;
33+
}
34+
blocks[i].size = blk_sz;
35+
total_mem += blk_sz;
36+
memset(blocks[i].ptr, 0xEF, blk_sz);
37+
n_blks++;
38+
}
39+
40+
// Check if there is leftover memory that can be allocated
41+
size_t left = esp_tee_heap_get_free_size();
42+
if (left > 24 && n_blks == max_blks) {
43+
size_t rm_sz = left - 24; // Calculate remaining size to allocate
44+
blocks[n_blks].ptr = malloc(rm_sz);
45+
if (blocks[n_blks].ptr) {
46+
blocks[n_blks].size = rm_sz;
47+
total_mem += rm_sz;
48+
memset(blocks[n_blks].ptr, 0xEF, rm_sz);
49+
n_blks++;
50+
} else {
51+
esp_rom_printf("Failed to allocate leftover bytes\n");
52+
free(blocks);
53+
return -1;
54+
}
55+
}
56+
57+
int *ptr = malloc(blk_sz);
58+
if (ptr) {
59+
esp_rom_printf("Illegal allocation\n");
60+
free(blocks);
61+
return -1;
62+
}
63+
64+
// Verify the integrity of allocated memory blocks
65+
for (int i = 0; i < n_blks; i++) {
66+
unsigned char *block_ptr = (unsigned char *)blocks[i].ptr;
67+
for (size_t j = 0; j < blocks[i].size; j++) {
68+
if (block_ptr[j] != 0xEF) {
69+
esp_rom_printf("Corrupt heap\n");
70+
free(blocks);
71+
return -1;
72+
}
73+
}
74+
free(blocks[i].ptr);
75+
}
76+
77+
free(blocks);
78+
return total_mem;
79+
}
80+
81+
int _ss_esp_tee_test_heap_malloc_write_free(void)
82+
{
83+
size_t prev_sz = 0;
84+
for (int i = 0; i < 3; i++) {
85+
size_t cur_sz = try_malloc_write_free();
86+
if (cur_sz == -1) {
87+
return -1;
88+
}
89+
90+
if (i > 0 && cur_sz != prev_sz) {
91+
esp_rom_printf("Processed memory sizes differ between iterations!\n");
92+
return -1;
93+
}
94+
95+
prev_sz = cur_sz;
96+
}
97+
98+
return 0;
99+
}

components/esp_tee/test_apps/tee_test_fw/main/test_esp_tee_ctx_switch.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,3 +95,8 @@ TEST_CASE("Task switching during secure service calls", "[basic]")
9595
world = esp_cpu_get_curr_privilege_level();
9696
TEST_ASSERT_MESSAGE((world == ESP_CPU_NS_MODE), "Current world is not NS");
9797
}
98+
99+
TEST_CASE("Test TEE Heap: Malloc-write-free cycles", "[heap]")
100+
{
101+
TEST_ASSERT_EQUAL(0, esp_tee_service_call(1, SS_ESP_TEE_TEST_HEAP_MALLOC_WRITE_FREE));
102+
}

components/esp_tee/test_apps/tee_test_fw/pytest_esp_tee_ut.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
@idf_parametrize('target', ['esp32c6'], indirect=['target'])
5252
def test_esp_tee(dut: IdfDut) -> None:
5353
dut.run_all_single_board_cases(group='basic')
54+
dut.run_all_single_board_cases(group='heap')
5455

5556

5657
@pytest.mark.generic
@@ -104,7 +105,7 @@ def test_esp_tee_apm_violation(dut: IdfDut) -> None:
104105
@idf_parametrize('target', ['esp32c6'], indirect=['target'])
105106
def test_esp_tee_illegal_instruction(dut: IdfDut) -> None:
106107
dut.expect_exact('Press ENTER to see the list of tests')
107-
dut.write(f'"Test TEE-TEE violation: Illegal Instruction"')
108+
dut.write('"Test TEE-TEE violation: Illegal Instruction"')
108109
exc = dut.expect(r'Core ([01]) panic\'ed \(([^)]+)\)', timeout=30).group(2).decode()
109110
if exc != 'Illegal instruction':
110111
raise RuntimeError('Incorrect exception received!')

0 commit comments

Comments
 (0)