mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-26 23:04:50 +00:00
fix(rcar3): fix load address range check
Fixed the check of the address range which the program is loaded to. Use the addresses and sizes in the BL31 and BL32 certificates to check that they are within the range of the target address and size defined inside the TF-A. It also uses the addresses and sizes in the BL33x certificates to check that they are outside the protected area defined inside the TF-A. Signed-off-by: Hideyuki Nitta <hideyuki.nitta.jf@hitachi.com> Signed-off-by: Toshiyuki Ogasahara <toshiyuki.ogasahara.bo@hitachi.com> Signed-off-by: Yoshifumi Hosoya <yoshifumi.hosoya.wj@renesas.com> Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org> # Code clean up Change-Id: Iade15431fc86587489fb0ca9106f6baaf7e926e2
This commit is contained in:
parent
ae4860b0f5
commit
4f7e0fa38f
3 changed files with 157 additions and 52 deletions
|
@ -598,13 +598,6 @@ static int32_t rcar_file_open(io_dev_info_t *info, const uintptr_t file_spec,
|
||||||
|
|
||||||
rcar_read_certificate((uint64_t) cert, &len, &dst);
|
rcar_read_certificate((uint64_t) cert, &len, &dst);
|
||||||
|
|
||||||
/* Baylibre: HACK */
|
|
||||||
if (spec->offset == BL31_IMAGE_ID && len < RCAR_TRUSTED_SRAM_SIZE) {
|
|
||||||
WARN("%s,%s\n", "r-car ignoring the BL31 size from certificate",
|
|
||||||
"using RCAR_TRUSTED_SRAM_SIZE instead");
|
|
||||||
len = RCAR_TRUSTED_SRAM_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
current_file.partition = partition;
|
current_file.partition = partition;
|
||||||
current_file.no_load = noload;
|
current_file.no_load = noload;
|
||||||
current_file.offset = offset;
|
current_file.offset = offset;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2021, Renesas Electronics Corporation. All rights reserved.
|
* Copyright (c) 2018-2023, Renesas Electronics Corporation. All rights reserved.
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -417,44 +417,61 @@ void bl2_plat_preload_setup(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int bl2_plat_handle_pre_image_load(unsigned int image_id)
|
static uint64_t check_secure_load_area(uintptr_t base, uint32_t size,
|
||||||
|
uintptr_t dest, uint32_t len)
|
||||||
{
|
{
|
||||||
u_register_t *boot_kind = (void *) BOOT_KIND_BASE;
|
uintptr_t free_end, requested_end;
|
||||||
bl_mem_params_node_t *bl_mem_params;
|
|
||||||
|
|
||||||
bl_mem_params = get_bl_mem_params_node(image_id);
|
/*
|
||||||
|
* Handle corner cases first.
|
||||||
#if RCAR_GEN3_BL33_GZIP == 1
|
*
|
||||||
if (image_id == BL33_IMAGE_ID) {
|
* The order of the 2 tests is important, because if there's no space
|
||||||
image_decompress_prepare(&bl_mem_params->image_info);
|
* left (i.e. free_size == 0) but we don't ask for any memory
|
||||||
|
* (i.e. size == 0) then we should report that the memory is free.
|
||||||
|
*/
|
||||||
|
if (len == 0U) {
|
||||||
|
WARN("BL2: load data size is zero\n");
|
||||||
|
return 0; /* A zero-byte region is always free */
|
||||||
|
}
|
||||||
|
if (size == 0U) {
|
||||||
|
goto err;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if (image_id != BL31_IMAGE_ID)
|
/*
|
||||||
return 0;
|
* Check that the end addresses don't overflow.
|
||||||
|
* If they do, consider that this memory region is not free, as this
|
||||||
|
* is an invalid scenario.
|
||||||
|
*/
|
||||||
|
if (check_uptr_overflow(base, size - 1U)) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
free_end = base + (size - 1U);
|
||||||
|
|
||||||
if (is_ddr_backup_mode() == RCAR_COLD_BOOT)
|
if (check_uptr_overflow(dest, len - 1U)) {
|
||||||
goto cold_boot;
|
goto err;
|
||||||
|
}
|
||||||
|
requested_end = dest + (len - 1U);
|
||||||
|
|
||||||
*boot_kind = RCAR_WARM_BOOT;
|
/*
|
||||||
flush_dcache_range(BOOT_KIND_BASE, sizeof(*boot_kind));
|
* Finally, check that the requested memory region lies within the free
|
||||||
|
* region.
|
||||||
console_flush();
|
*/
|
||||||
bl2_plat_flush_bl31_params();
|
if ((dest < base) || (requested_end > free_end)) {
|
||||||
|
goto err;
|
||||||
/* will not return */
|
}
|
||||||
bl2_enter_bl31(&bl_mem_params->ep_info);
|
|
||||||
|
|
||||||
cold_boot:
|
|
||||||
*boot_kind = RCAR_COLD_BOOT;
|
|
||||||
flush_dcache_range(BOOT_KIND_BASE, sizeof(*boot_kind));
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err:
|
||||||
|
ERROR("BL2: load data is outside the loadable area.\n");
|
||||||
|
ERROR("BL2: dst=0x%lx, len=%d(0x%x)\n", dest, len, len);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint64_t rcar_get_dest_addr_from_cert(uint32_t certid, uintptr_t *dest)
|
static uint64_t rcar_get_dest_addr_from_cert(uint32_t certid, uintptr_t *dest,
|
||||||
|
uint32_t *len)
|
||||||
{
|
{
|
||||||
uint32_t cert, len;
|
uint32_t cert;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = rcar_get_certificate(certid, &cert);
|
ret = rcar_get_certificate(certid, &cert);
|
||||||
|
@ -463,7 +480,104 @@ static uint64_t rcar_get_dest_addr_from_cert(uint32_t certid, uintptr_t *dest)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
rcar_read_certificate((uint64_t) cert, &len, dest);
|
rcar_read_certificate((uint64_t) cert, len, dest);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bl2_plat_handle_pre_image_load(unsigned int image_id)
|
||||||
|
{
|
||||||
|
u_register_t *boot_kind = (void *) BOOT_KIND_BASE;
|
||||||
|
bl_mem_params_node_t *bl_mem_params;
|
||||||
|
uintptr_t dev_handle;
|
||||||
|
uintptr_t image_spec;
|
||||||
|
uintptr_t dest;
|
||||||
|
uint32_t len;
|
||||||
|
uint64_t ui64_ret;
|
||||||
|
int iret;
|
||||||
|
|
||||||
|
bl_mem_params = get_bl_mem_params_node(image_id);
|
||||||
|
if (bl_mem_params == NULL) {
|
||||||
|
ERROR("BL2: Failed to get loading parameter.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (image_id) {
|
||||||
|
case BL31_IMAGE_ID:
|
||||||
|
if (is_ddr_backup_mode() == RCAR_COLD_BOOT) {
|
||||||
|
iret = plat_get_image_source(image_id, &dev_handle,
|
||||||
|
&image_spec);
|
||||||
|
if (iret != 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ui64_ret = rcar_get_dest_addr_from_cert(
|
||||||
|
SOC_FW_CONTENT_CERT_ID, &dest, &len);
|
||||||
|
if (ui64_ret != 0U) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ui64_ret = check_secure_load_area(
|
||||||
|
BL31_BASE, BL31_LIMIT - BL31_BASE,
|
||||||
|
dest, len);
|
||||||
|
if (ui64_ret != 0U) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*boot_kind = RCAR_COLD_BOOT;
|
||||||
|
flush_dcache_range(BOOT_KIND_BASE, sizeof(*boot_kind));
|
||||||
|
|
||||||
|
bl_mem_params->image_info.image_base = dest;
|
||||||
|
bl_mem_params->image_info.image_size = len;
|
||||||
|
} else {
|
||||||
|
*boot_kind = RCAR_WARM_BOOT;
|
||||||
|
flush_dcache_range(BOOT_KIND_BASE, sizeof(*boot_kind));
|
||||||
|
|
||||||
|
console_flush();
|
||||||
|
bl2_plat_flush_bl31_params();
|
||||||
|
|
||||||
|
/* will not return */
|
||||||
|
bl2_enter_bl31(&bl_mem_params->ep_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
#ifndef SPD_NONE
|
||||||
|
case BL32_IMAGE_ID:
|
||||||
|
ui64_ret = rcar_get_dest_addr_from_cert(
|
||||||
|
TRUSTED_OS_FW_CONTENT_CERT_ID, &dest, &len);
|
||||||
|
if (ui64_ret != 0U) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ui64_ret = check_secure_load_area(
|
||||||
|
BL32_BASE, BL32_LIMIT - BL32_BASE, dest, len);
|
||||||
|
if (ui64_ret != 0U) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bl_mem_params->image_info.image_base = dest;
|
||||||
|
bl_mem_params->image_info.image_size = len;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
case BL33_IMAGE_ID:
|
||||||
|
/* case of image_id == BL33_IMAGE_ID */
|
||||||
|
ui64_ret = rcar_get_dest_addr_from_cert(
|
||||||
|
NON_TRUSTED_FW_CONTENT_CERT_ID,
|
||||||
|
&dest, &len);
|
||||||
|
|
||||||
|
if (ui64_ret != 0U) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if RCAR_GEN3_BL33_GZIP == 1
|
||||||
|
image_decompress_prepare(&bl_mem_params->image_info);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -472,8 +586,6 @@ int bl2_plat_handle_post_image_load(unsigned int image_id)
|
||||||
{
|
{
|
||||||
static bl2_to_bl31_params_mem_t *params;
|
static bl2_to_bl31_params_mem_t *params;
|
||||||
bl_mem_params_node_t *bl_mem_params;
|
bl_mem_params_node_t *bl_mem_params;
|
||||||
uintptr_t dest;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (!params) {
|
if (!params) {
|
||||||
params = (bl2_to_bl31_params_mem_t *) PARAMS_BASE;
|
params = (bl2_to_bl31_params_mem_t *) PARAMS_BASE;
|
||||||
|
@ -481,25 +593,23 @@ int bl2_plat_handle_post_image_load(unsigned int image_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
bl_mem_params = get_bl_mem_params_node(image_id);
|
bl_mem_params = get_bl_mem_params_node(image_id);
|
||||||
|
if (!bl_mem_params) {
|
||||||
|
ERROR("BL2: Failed to get loading parameter.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
switch (image_id) {
|
switch (image_id) {
|
||||||
case BL31_IMAGE_ID:
|
case BL31_IMAGE_ID:
|
||||||
ret = rcar_get_dest_addr_from_cert(SOC_FW_CONTENT_CERT_ID,
|
bl_mem_params->ep_info.pc = bl_mem_params->image_info.image_base;
|
||||||
&dest);
|
return 0;
|
||||||
if (!ret)
|
|
||||||
bl_mem_params->image_info.image_base = dest;
|
|
||||||
break;
|
|
||||||
case BL32_IMAGE_ID:
|
case BL32_IMAGE_ID:
|
||||||
ret = rcar_get_dest_addr_from_cert(TRUSTED_OS_FW_CONTENT_CERT_ID,
|
bl_mem_params->ep_info.pc = bl_mem_params->image_info.image_base;
|
||||||
&dest);
|
|
||||||
if (!ret)
|
|
||||||
bl_mem_params->image_info.image_base = dest;
|
|
||||||
|
|
||||||
memcpy(¶ms->bl32_ep_info, &bl_mem_params->ep_info,
|
memcpy(¶ms->bl32_ep_info, &bl_mem_params->ep_info,
|
||||||
sizeof(entry_point_info_t));
|
sizeof(entry_point_info_t));
|
||||||
break;
|
return 0;
|
||||||
case BL33_IMAGE_ID:
|
case BL33_IMAGE_ID:
|
||||||
#if RCAR_GEN3_BL33_GZIP == 1
|
#if RCAR_GEN3_BL33_GZIP == 1
|
||||||
|
int ret;
|
||||||
if ((mmio_read_32(BL33_COMP_BASE) & 0xffff) == 0x8b1f) {
|
if ((mmio_read_32(BL33_COMP_BASE) & 0xffff) == 0x8b1f) {
|
||||||
/* decompress gzip-compressed image */
|
/* decompress gzip-compressed image */
|
||||||
ret = image_decompress(&bl_mem_params->image_info);
|
ret = image_decompress(&bl_mem_params->image_info);
|
||||||
|
@ -514,7 +624,9 @@ int bl2_plat_handle_post_image_load(unsigned int image_id)
|
||||||
#endif
|
#endif
|
||||||
memcpy(¶ms->bl33_ep_info, &bl_mem_params->ep_info,
|
memcpy(¶ms->bl33_ep_info, &bl_mem_params->ep_info,
|
||||||
sizeof(entry_point_info_t));
|
sizeof(entry_point_info_t));
|
||||||
break;
|
return 0;
|
||||||
|
default:
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved.
|
* Copyright (c) 2015-2023, Renesas Electronics Corporation. All rights reserved.
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -91,7 +91,7 @@
|
||||||
#define RCAR_BL31DST_ADDRESS (0x44000000U)
|
#define RCAR_BL31DST_ADDRESS (0x44000000U)
|
||||||
#define RCAR_BL31DST_ADDRESSH (0x00000000U)
|
#define RCAR_BL31DST_ADDRESSH (0x00000000U)
|
||||||
/* Destination size for BL31 */
|
/* Destination size for BL31 */
|
||||||
#define RCAR_BL31DST_SIZE (0x00004000U)
|
#define RCAR_BL31DST_SIZE (0x0000F800U)
|
||||||
/* Destination address for BL32 */
|
/* Destination address for BL32 */
|
||||||
#define RCAR_BL32DST_ADDRESS (0x44100000U)
|
#define RCAR_BL32DST_ADDRESS (0x44100000U)
|
||||||
#define RCAR_BL32DST_ADDRESSH (0x00000000U)
|
#define RCAR_BL32DST_ADDRESSH (0x00000000U)
|
||||||
|
|
Loading…
Add table
Reference in a new issue