diff --git a/drivers/renesas/common/io/io_rcar.c b/drivers/renesas/common/io/io_rcar.c index 80f32aab0..66662c111 100644 --- a/drivers/renesas/common/io/io_rcar.c +++ b/drivers/renesas/common/io/io_rcar.c @@ -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); - /* 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.no_load = noload; current_file.offset = offset; diff --git a/plat/renesas/rcar/bl2_plat_setup.c b/plat/renesas/rcar/bl2_plat_setup.c index 81ee93e53..6b1d4fc77 100644 --- a/plat/renesas/rcar/bl2_plat_setup.c +++ b/plat/renesas/rcar/bl2_plat_setup.c @@ -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 */ @@ -417,44 +417,61 @@ void bl2_plat_preload_setup(void) } #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; - bl_mem_params_node_t *bl_mem_params; + uintptr_t free_end, requested_end; - bl_mem_params = get_bl_mem_params_node(image_id); - -#if RCAR_GEN3_BL33_GZIP == 1 - if (image_id == BL33_IMAGE_ID) { - image_decompress_prepare(&bl_mem_params->image_info); + /* + * Handle corner cases first. + * + * The order of the 2 tests is important, because if there's no space + * 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) - goto cold_boot; + if (check_uptr_overflow(dest, len - 1U)) { + goto err; + } + requested_end = dest + (len - 1U); - *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); - -cold_boot: - *boot_kind = RCAR_COLD_BOOT; - flush_dcache_range(BOOT_KIND_BASE, sizeof(*boot_kind)); + /* + * Finally, check that the requested memory region lies within the free + * region. + */ + if ((dest < base) || (requested_end > free_end)) { + goto err; + } 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; 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; } - 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; } @@ -472,8 +586,6 @@ int bl2_plat_handle_post_image_load(unsigned int image_id) { static bl2_to_bl31_params_mem_t *params; bl_mem_params_node_t *bl_mem_params; - uintptr_t dest; - int ret; if (!params) { 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); + if (!bl_mem_params) { + ERROR("BL2: Failed to get loading parameter.\n"); + return 1; + } switch (image_id) { case BL31_IMAGE_ID: - ret = rcar_get_dest_addr_from_cert(SOC_FW_CONTENT_CERT_ID, - &dest); - if (!ret) - bl_mem_params->image_info.image_base = dest; - break; + bl_mem_params->ep_info.pc = bl_mem_params->image_info.image_base; + return 0; case BL32_IMAGE_ID: - ret = rcar_get_dest_addr_from_cert(TRUSTED_OS_FW_CONTENT_CERT_ID, - &dest); - if (!ret) - bl_mem_params->image_info.image_base = dest; - + bl_mem_params->ep_info.pc = bl_mem_params->image_info.image_base; memcpy(¶ms->bl32_ep_info, &bl_mem_params->ep_info, sizeof(entry_point_info_t)); - break; + return 0; case BL33_IMAGE_ID: #if RCAR_GEN3_BL33_GZIP == 1 + int ret; if ((mmio_read_32(BL33_COMP_BASE) & 0xffff) == 0x8b1f) { /* decompress gzip-compressed image */ ret = image_decompress(&bl_mem_params->image_info); @@ -514,7 +624,9 @@ int bl2_plat_handle_post_image_load(unsigned int image_id) #endif memcpy(¶ms->bl33_ep_info, &bl_mem_params->ep_info, sizeof(entry_point_info_t)); - break; + return 0; + default: + return 1; } return 0; diff --git a/tools/renesas/rcar_layout_create/sa6.c b/tools/renesas/rcar_layout_create/sa6.c index 8fafdaded..58881f971 100644 --- a/tools/renesas/rcar_layout_create/sa6.c +++ b/tools/renesas/rcar_layout_create/sa6.c @@ -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 */ @@ -91,7 +91,7 @@ #define RCAR_BL31DST_ADDRESS (0x44000000U) #define RCAR_BL31DST_ADDRESSH (0x00000000U) /* Destination size for BL31 */ -#define RCAR_BL31DST_SIZE (0x00004000U) +#define RCAR_BL31DST_SIZE (0x0000F800U) /* Destination address for BL32 */ #define RCAR_BL32DST_ADDRESS (0x44100000U) #define RCAR_BL32DST_ADDRESSH (0x00000000U)