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"
|
list(APPEND srcs "src/test_dummy_srv.c"
|
||||||
"src/test_interrupt.c"
|
"src/test_interrupt.c"
|
||||||
"src/test_panic.c"
|
"src/test_panic.c"
|
||||||
"src/test_sec_srv.c")
|
"src/test_sec_srv.c"
|
||||||
|
"src/test_heap.c")
|
||||||
list(APPEND priv_requires main)
|
list(APPEND priv_requires main)
|
||||||
else()
|
else()
|
||||||
list(APPEND srcs "src/test_dummy_srv_wrapper.c")
|
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);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -69,3 +69,7 @@ secure_services:
|
|||||||
type: custom
|
type: custom
|
||||||
function: add_in_loop
|
function: add_in_loop
|
||||||
args: 3
|
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();
|
world = esp_cpu_get_curr_privilege_level();
|
||||||
TEST_ASSERT_MESSAGE((world == ESP_CPU_NS_MODE), "Current world is not NS");
|
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'])
|
@idf_parametrize('target', ['esp32c6'], indirect=['target'])
|
||||||
def test_esp_tee(dut: IdfDut) -> None:
|
def test_esp_tee(dut: IdfDut) -> None:
|
||||||
dut.run_all_single_board_cases(group='basic')
|
dut.run_all_single_board_cases(group='basic')
|
||||||
|
dut.run_all_single_board_cases(group='heap')
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.generic
|
@pytest.mark.generic
|
||||||
@@ -104,7 +105,7 @@ def test_esp_tee_apm_violation(dut: IdfDut) -> None:
|
|||||||
@idf_parametrize('target', ['esp32c6'], indirect=['target'])
|
@idf_parametrize('target', ['esp32c6'], indirect=['target'])
|
||||||
def test_esp_tee_illegal_instruction(dut: IdfDut) -> None:
|
def test_esp_tee_illegal_instruction(dut: IdfDut) -> None:
|
||||||
dut.expect_exact('Press ENTER to see the list of tests')
|
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()
|
exc = dut.expect(r'Core ([01]) panic\'ed \(([^)]+)\)', timeout=30).group(2).decode()
|
||||||
if exc != 'Illegal instruction':
|
if exc != 'Illegal instruction':
|
||||||
raise RuntimeError('Incorrect exception received!')
|
raise RuntimeError('Incorrect exception received!')
|
||||||
|
Reference in New Issue
Block a user