diff options
| author | Harrison Mutai <harrison.mutai@arm.com> | 2026-06-29 08:47:00 +0000 |
|---|---|---|
| committer | TrustedFirmware Code Review <review@review.trustedfirmware.org> | 2026-06-29 08:47:00 +0000 |
| commit | 31255dd9b2e14c1ebe4eab1b8f4984cde72c51d5 (patch) | |
| tree | c36960f8bf634abdf14c04c56c257e5923250fae | |
| parent | 0ff6f48335d66e69cfdc42bb9c4d49a43b819bfc (diff) | |
| parent | a06d0c222e6b4f78f6b2798372959f9079c76f5c (diff) | |
| download | arm-trusted-firmware-31255dd9b2e14c1ebe4eab1b8f4984cde72c51d5.tar.gz arm-trusted-firmware-31255dd9b2e14c1ebe4eab1b8f4984cde72c51d5.zip | |
Merge "fix(imx8m): validate NS pointer arguments in HAB report handlers" into integration
| -rw-r--r-- | plat/imx/imx8m/imx8m_smc_validation.c | 42 | ||||
| -rw-r--r-- | plat/imx/imx8m/imx8mm/platform.mk | 1 | ||||
| -rw-r--r-- | plat/imx/imx8m/imx8mn/platform.mk | 1 | ||||
| -rw-r--r-- | plat/imx/imx8m/imx8mp/platform.mk | 1 | ||||
| -rw-r--r-- | plat/imx/imx8m/imx8mq/platform.mk | 1 | ||||
| -rw-r--r-- | plat/imx/imx8m/imx_hab.c | 68 |
6 files changed, 109 insertions, 5 deletions
diff --git a/plat/imx/imx8m/imx8m_smc_validation.c b/plat/imx/imx8m/imx8m_smc_validation.c new file mode 100644 index 000000000..5efe33250 --- /dev/null +++ b/plat/imx/imx8m/imx8m_smc_validation.c @@ -0,0 +1,42 @@ +/* + * Copyright 2026 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> + +#include <common/smc_validation_framework.h> + +#include <platform_def.h> + +/* + * plat_is_valid_ns_address_range() - i.MX8M override. + * + * Accept only the DRAM region as valid Non-Secure memory, excluding the + * BL32 (OP-TEE) carve-out. This prevents NS callers from passing + * pointers into OCRAM (BL31), ROM, MMIO, or secure BL32 memory + * regions through SMC arguments. + */ +bool plat_is_valid_ns_address_range(uintptr_t base, size_t size) +{ + uintptr_t end = base + size; + + /* Reject addresses outside DRAM */ + if ((base < IMX_DRAM_BASE) || + (end > ((uintptr_t)IMX_DRAM_BASE + IMX_DRAM_SIZE))) { + return false; + } + +#if defined(BL32_BASE) && defined(BL32_SIZE) + /* Reject addresses that overlap the BL32 (OP-TEE) region */ + if ((end > BL32_BASE) && + (base < (BL32_BASE + BL32_SIZE))) { + return false; + } +#endif + + return true; +} diff --git a/plat/imx/imx8m/imx8mm/platform.mk b/plat/imx/imx8m/imx8mm/platform.mk index f494e47b8..4cad97697 100644 --- a/plat/imx/imx8m/imx8mm/platform.mk +++ b/plat/imx/imx8m/imx8mm/platform.mk @@ -34,6 +34,7 @@ BL31_SOURCES += common/desc_image_load.c \ plat/imx/common/imx8_helpers.S \ plat/imx/imx8m/gpc_common.c \ plat/imx/imx8m/imx_hab.c \ + plat/imx/imx8m/imx8m_smc_validation.c \ plat/imx/imx8m/imx_aipstz.c \ plat/imx/imx8m/imx_rdc.c \ plat/imx/imx8m/imx8m_csu.c \ diff --git a/plat/imx/imx8m/imx8mn/platform.mk b/plat/imx/imx8m/imx8mn/platform.mk index 6a9d22e12..9cf5b05a6 100644 --- a/plat/imx/imx8m/imx8mn/platform.mk +++ b/plat/imx/imx8m/imx8mn/platform.mk @@ -29,6 +29,7 @@ BL31_SOURCES += common/desc_image_load.c \ plat/imx/common/imx8_helpers.S \ plat/imx/imx8m/gpc_common.c \ plat/imx/imx8m/imx_hab.c \ + plat/imx/imx8m/imx8m_smc_validation.c \ plat/imx/imx8m/imx_aipstz.c \ plat/imx/imx8m/imx_rdc.c \ plat/imx/imx8m/imx8m_caam.c \ diff --git a/plat/imx/imx8m/imx8mp/platform.mk b/plat/imx/imx8m/imx8mp/platform.mk index 11fc01b0b..7ec417f63 100644 --- a/plat/imx/imx8m/imx8mp/platform.mk +++ b/plat/imx/imx8m/imx8mp/platform.mk @@ -31,6 +31,7 @@ BL31_SOURCES += common/desc_image_load.c \ plat/imx/common/imx8_helpers.S \ plat/imx/imx8m/gpc_common.c \ plat/imx/imx8m/imx_hab.c \ + plat/imx/imx8m/imx8m_smc_validation.c \ plat/imx/imx8m/imx_aipstz.c \ plat/imx/imx8m/imx_rdc.c \ plat/imx/imx8m/imx8m_caam.c \ diff --git a/plat/imx/imx8m/imx8mq/platform.mk b/plat/imx/imx8m/imx8mq/platform.mk index 76fc07107..17437da04 100644 --- a/plat/imx/imx8m/imx8mq/platform.mk +++ b/plat/imx/imx8m/imx8mq/platform.mk @@ -30,6 +30,7 @@ BL31_SOURCES += plat/imx/common/imx8_helpers.S \ plat/imx/imx8m/imx8mq/imx8mq_psci.c \ plat/imx/imx8m/gpc_common.c \ plat/imx/imx8m/imx_hab.c \ + plat/imx/imx8m/imx8m_smc_validation.c \ plat/imx/imx8m/imx_aipstz.c \ plat/imx/imx8m/imx8m_caam.c \ plat/imx/imx8m/imx8m_ccm.c \ diff --git a/plat/imx/imx8m/imx_hab.c b/plat/imx/imx8m/imx_hab.c index 222046fb9..d34d495bf 100644 --- a/plat/imx/imx8m/imx_hab.c +++ b/plat/imx/imx8m/imx_hab.c @@ -5,7 +5,10 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include <common/debug.h> #include <common/runtime_svc.h> +#include <common/smc_validation_framework.h> + #include <imx_sip_svc.h> #define HAB_CID_ATF U(2) /* TF-A Caller ID */ @@ -80,7 +83,8 @@ struct hab_rvt_api { size_t *bytes, hab_loader_callback_f_t loader, uint32_t srkmask, int skip_dcd); }; -struct hab_rvt_api *g_hab_rvt_api = (struct hab_rvt_api *)HAB_RVT_BASE; +static const struct hab_rvt_api *g_hab_rvt_api = + (const struct hab_rvt_api *)HAB_RVT_BASE; /******************************************************************************* * Handler for servicing HAB SMC calls @@ -102,12 +106,66 @@ int imx_hab_handler(uint32_t smc_fid, case IMX_SIP_HAB_AUTH_IMG: return (unsigned long)g_hab_rvt_api->authenticate_image(HAB_CID_ATF, x2, (void **)x3, (size_t *)x4, NULL); + case IMX_SIP_HAB_REPORT_EVENT: - return g_hab_rvt_api->report_event(HAB_FAILURE, - (uint32_t)x2, (uint8_t *)x3, (size_t *)x4); + { + uintptr_t event_buf = (uintptr_t)x3; + uintptr_t bytes_ptr = (uintptr_t)x4; + + if (smc_validate_mem_range(bytes_ptr, sizeof(size_t)) != SMC_OK) { + WARN("HAB: REPORT_EVENT bytes_ptr 0x%lx failed NS check\n", + bytes_ptr); + return (int)HAB_FAILURE; + } + + size_t max_bytes = *(size_t *)bytes_ptr; + + if (smc_validate_mem_range(event_buf, max_bytes) != SMC_OK) { + WARN("HAB: REPORT_EVENT buf 0x%lx+0x%zx failed NS check\n", + event_buf, max_bytes); + return (int)HAB_FAILURE; + } + + enum hab_status status = g_hab_rvt_api->report_event( + HAB_FAILURE, (uint32_t)x2, + (uint8_t *)event_buf, &max_bytes); + + *(size_t *)bytes_ptr = max_bytes; + + return (int)status; + } + case IMX_SIP_HAB_REPORT_STATUS: - return g_hab_rvt_api->report_status((enum hab_config *)x2, - (enum hab_state *)x3); + { + uintptr_t config_ptr = (uintptr_t)x2; + uintptr_t state_ptr = (uintptr_t)x3; + + if (smc_validate_mem_range(config_ptr, + sizeof(enum hab_config)) != SMC_OK) { + WARN("HAB: REPORT_STATUS config_ptr 0x%lx failed NS check\n", + config_ptr); + return (int)HAB_FAILURE; + } + + if (smc_validate_mem_range(state_ptr, + sizeof(enum hab_state)) != SMC_OK) { + WARN("HAB: REPORT_STATUS state_ptr 0x%lx failed NS check\n", + state_ptr); + return (int)HAB_FAILURE; + } + + enum hab_config config_local; + enum hab_state state_local; + + enum hab_status status = g_hab_rvt_api->report_status( + &config_local, &state_local); + + *(enum hab_config *)config_ptr = config_local; + *(enum hab_state *)state_ptr = state_local; + + return (int)status; + } + case IMX_SIP_HAB_FAILSAFE: g_hab_rvt_api->failsafe(); break; |
