forked from espressif/esp-idf
ci(esp_tee): Verify the malloc-write-free cycle in the TEE heap
This commit is contained in:
@@ -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")
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
}
|
@@ -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));
|
||||
}
|
||||
|
@@ -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!')
|
||||
|
Reference in New Issue
Block a user