mirror of
https://github.com/espressif/esp-idf.git
synced 2026-09-22 13:01:16 +03:00
fix(esp_tee): enforce MMU-map vaddr validity at the REE->TEE boundary
This commit is contained in:
committed by
Laukik Hase
parent
53d6c28d3f
commit
5091e7c874
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_macros.h"
|
||||
#include "esp_fault.h"
|
||||
|
||||
#include "hal/mmu_types.h"
|
||||
@@ -36,6 +37,9 @@
|
||||
|
||||
static __attribute__((unused)) const char *TAG = "esp_tee_sec_srv_iram";
|
||||
|
||||
#define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
|
||||
#define ALIGN_DOWN(num, align) ((num) & ~((align) - 1))
|
||||
|
||||
/* ---------------------------------------------- Interrupts ------------------------------------------------- */
|
||||
|
||||
#if SOC_INT_CLIC_SUPPORTED
|
||||
@@ -272,11 +276,37 @@ esp_err_t _ss_esp_tee_sec_storage_ecdsa_sign_pbkdf2(const esp_tee_sec_storage_pb
|
||||
|
||||
/* ---------------------------------------------- MMU HAL ------------------------------------------------- */
|
||||
|
||||
/* Gates for REE-supplied external-flash address ranges. The HAL maps whole pages,
|
||||
* so validate the page-rounded span it will actually touch (not the raw byte len)
|
||||
* and require page-aligned addresses, so a sub-page or misaligned request cannot
|
||||
* smuggle in an adjacent TEE page. mmu_hal_check_valid_ext_vaddr_region() must be
|
||||
* enforced HERE, at the boundary: it rejects out-of-window (aliased) vaddrs. */
|
||||
static bool tee_ree_ext_vaddr_ok(uint32_t mmu_id, uint32_t vaddr, uint32_t len)
|
||||
{
|
||||
uint32_t page = mmu_hal_pages_to_bytes(mmu_id, 1);
|
||||
uint32_t map_len = ALIGN_UP(len, page);
|
||||
|
||||
return (len != 0 && map_len >= len && (vaddr % page == 0) &&
|
||||
mmu_hal_check_valid_ext_vaddr_region(mmu_id, vaddr, map_len,
|
||||
MMU_VADDR_DATA | MMU_VADDR_INSTRUCTION) &&
|
||||
!esp_tee_flash_check_vrange_in_tee_region(vaddr, map_len));
|
||||
}
|
||||
|
||||
static bool tee_ree_ext_paddr_ok(uint32_t mmu_id, uint32_t paddr, uint32_t len)
|
||||
{
|
||||
uint32_t page = mmu_hal_pages_to_bytes(mmu_id, 1);
|
||||
uint32_t map_len = ALIGN_UP(len, page);
|
||||
|
||||
return (len != 0 && map_len >= len && (paddr % page == 0) &&
|
||||
mmu_hal_check_valid_paddr_region(mmu_id, paddr, map_len) &&
|
||||
!esp_tee_flash_check_prange_in_tee_region(paddr, map_len));
|
||||
}
|
||||
|
||||
void _ss_mmu_hal_map_region(uint32_t mmu_id, mmu_target_t mem_type, uint32_t vaddr,
|
||||
uint32_t paddr, uint32_t len, uint32_t *out_len)
|
||||
{
|
||||
bool valid_addr = (!esp_tee_flash_check_vrange_in_tee_region(vaddr, len) &&
|
||||
!esp_tee_flash_check_prange_in_tee_region(paddr, len) &&
|
||||
bool valid_addr = (tee_ree_ext_vaddr_ok(mmu_id, vaddr, len) &&
|
||||
tee_ree_ext_paddr_ok(mmu_id, paddr, len) &&
|
||||
esp_tee_buf_in_ree(out_len, sizeof(uint32_t)));
|
||||
|
||||
if (!valid_addr) {
|
||||
@@ -290,20 +320,23 @@ void _ss_mmu_hal_map_region(uint32_t mmu_id, mmu_target_t mem_type, uint32_t vad
|
||||
|
||||
void _ss_mmu_hal_unmap_region(uint32_t mmu_id, uint32_t vaddr, uint32_t len)
|
||||
{
|
||||
bool vaddr_chk = esp_tee_flash_check_vrange_in_tee_region(vaddr, len);
|
||||
bool valid_addr = tee_ree_ext_vaddr_ok(mmu_id, vaddr, len);
|
||||
|
||||
if (vaddr_chk) {
|
||||
if (!valid_addr) {
|
||||
ESP_LOGD(TAG, "[%s] Illegal flash access at 0x%08x", __func__, vaddr);
|
||||
return;
|
||||
}
|
||||
ESP_FAULT_ASSERT(!vaddr_chk);
|
||||
ESP_FAULT_ASSERT(valid_addr);
|
||||
|
||||
mmu_hal_unmap_region(mmu_id, vaddr, len);
|
||||
}
|
||||
|
||||
bool _ss_mmu_hal_vaddr_to_paddr(uint32_t mmu_id, uint32_t vaddr, uint32_t *out_paddr, mmu_target_t *out_target)
|
||||
{
|
||||
bool valid_addr = (!esp_tee_flash_check_vaddr_in_tee_region(vaddr) &&
|
||||
/* Same aliasing gate as map/unmap; translation itself is page-granular and
|
||||
* vaddr need not be aligned, so validate the page containing it. */
|
||||
uint32_t page = mmu_hal_pages_to_bytes(mmu_id, 1);
|
||||
bool valid_addr = (tee_ree_ext_vaddr_ok(mmu_id, ALIGN_DOWN(vaddr, page), 1) &&
|
||||
esp_tee_buf_in_ree(out_paddr, sizeof(uint32_t)) &&
|
||||
esp_tee_buf_in_ree(out_target, sizeof(mmu_target_t)));
|
||||
|
||||
@@ -317,7 +350,8 @@ bool _ss_mmu_hal_vaddr_to_paddr(uint32_t mmu_id, uint32_t vaddr, uint32_t *out_p
|
||||
|
||||
bool _ss_mmu_hal_paddr_to_vaddr(uint32_t mmu_id, uint32_t paddr, mmu_target_t target, mmu_vaddr_t type, uint32_t *out_vaddr)
|
||||
{
|
||||
bool valid_addr = (!esp_tee_flash_check_paddr_in_tee_region(paddr) &&
|
||||
bool valid_addr = (mmu_hal_check_valid_paddr_region(mmu_id, paddr, 1) &&
|
||||
!esp_tee_flash_check_paddr_in_tee_region(paddr) &&
|
||||
esp_tee_buf_in_ree(out_vaddr, sizeof(uint32_t)));
|
||||
|
||||
if (!valid_addr) {
|
||||
|
||||
@@ -132,6 +132,18 @@ bool mmu_hal_paddr_to_vaddr(uint32_t mmu_id, uint32_t paddr, mmu_target_t target
|
||||
*/
|
||||
bool mmu_hal_check_valid_ext_vaddr_region(uint32_t mmu_id, uint32_t vaddr_start, uint32_t len, mmu_vaddr_t type);
|
||||
|
||||
/**
|
||||
* Check if the paddr region is valid
|
||||
*
|
||||
* @param mmu_id MMU ID
|
||||
* @param paddr_start start of the physical address
|
||||
* @param len length, in bytes
|
||||
*
|
||||
* @return
|
||||
* True for valid
|
||||
*/
|
||||
bool mmu_hal_check_valid_paddr_region(uint32_t mmu_id, uint32_t paddr_start, uint32_t len);
|
||||
|
||||
#if SOC_MMU_PER_EXT_MEM_TARGET
|
||||
/**
|
||||
* Get MMU ID from MMU target
|
||||
|
||||
@@ -186,6 +186,11 @@ bool mmu_hal_check_valid_ext_vaddr_region(uint32_t mmu_id, uint32_t vaddr_start,
|
||||
return mmu_ll_check_valid_ext_vaddr_region(mmu_id, vaddr_start, len, type);
|
||||
}
|
||||
|
||||
bool mmu_hal_check_valid_paddr_region(uint32_t mmu_id, uint32_t paddr_start, uint32_t len)
|
||||
{
|
||||
return mmu_ll_check_valid_paddr_region(mmu_id, paddr_start, len);
|
||||
}
|
||||
|
||||
#if SOC_MMU_PER_EXT_MEM_TARGET
|
||||
uint32_t mmu_hal_get_id_from_target(mmu_target_t target)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user