Merge changes Ia052c7f9,If598680a,Ieae11722 into integration

* changes:
  refactor(el3-spmc): move function call out of loop
  refactor(el3-spmc): crash instead of reading OOB
  fix(el3-spmc): prevent total_page_count overflow
This commit is contained in:
Manish Pandey 2023-06-06 16:43:53 +02:00 committed by TrustedFirmware Code Review
commit f4c913630d

View file

@ -787,40 +787,64 @@ spmc_validate_mtd_start(struct ffa_mtd *desc, uint32_t ffa_version,
static int spmc_shmem_check_obj(struct spmc_shmem_obj *obj,
uint32_t ffa_version)
{
const struct ffa_emad_v1_0 *emad;
size_t emad_size;
uint32_t comp_mrd_offset = 0;
if (obj->desc.emad_count == 0U) {
WARN("%s: unsupported attribute desc count %u.\n",
__func__, obj->desc.emad_count);
return -EINVAL;
if (obj->desc_filled != obj->desc_size) {
ERROR("BUG: %s called on incomplete object (%zu != %zu)\n",
__func__, obj->desc_filled, obj->desc_size);
panic();
}
if (spmc_validate_mtd_start(&obj->desc, ffa_version,
obj->desc_filled, obj->desc_size)) {
ERROR("BUG: %s called on object with corrupt memory region descriptor\n",
__func__);
panic();
}
emad = spmc_shmem_obj_get_emad(&obj->desc, 0,
ffa_version, &emad_size);
for (size_t emad_num = 0; emad_num < obj->desc.emad_count; emad_num++) {
size_t size;
size_t count;
size_t expected_size;
size_t total_page_count;
size_t emad_size;
uint64_t total_page_count;
size_t header_emad_size;
uint32_t offset;
struct ffa_comp_mrd *comp;
struct ffa_emad_v1_0 *emad;
emad = spmc_shmem_obj_get_emad(&obj->desc, emad_num,
ffa_version, &emad_size);
ffa_endpoint_id16_t ep_id;
/*
* Validate the calculated emad address resides within the
* descriptor.
*/
if ((uintptr_t) emad >=
(uintptr_t)((uint8_t *) &obj->desc + obj->desc_size)) {
WARN("Invalid emad access.\n");
return -EINVAL;
if ((uintptr_t) emad >
((uintptr_t) &obj->desc + obj->desc_size - emad_size)) {
ERROR("BUG: Invalid emad access not detected earlier.\n");
panic();
}
emad = (const struct ffa_emad_v1_0 *)((const uint8_t *)emad + emad_size);
offset = emad->comp_mrd_offset;
/*
* If a partition ID resides in the secure world validate that
* the partition ID is for a known partition. Ignore any
* partition ID belonging to the normal world as it is assumed
* the Hypervisor will have validated these.
*/
ep_id = emad->mapd.endpoint_id;
if (ffa_is_secure_world_id(ep_id)) {
if (spmc_get_sp_ctx(ep_id) == NULL) {
WARN("%s: Invalid receiver id 0x%x\n",
__func__, ep_id);
return -EINVAL;
}
}
/*
* The offset provided to the composite memory region descriptor
* should be consistent across endpoint descriptors. Store the
@ -894,7 +918,7 @@ static int spmc_shmem_check_obj(struct spmc_shmem_obj *obj,
comp->address_range_array[i].page_count;
}
if (comp->total_page_count != total_page_count) {
WARN("%s: invalid object, desc total_page_count %u != %zu\n",
WARN("%s: invalid object, desc total_page_count %u != %" PRIu64 "\n",
__func__, comp->total_page_count,
total_page_count);
return -EINVAL;
@ -1048,28 +1072,6 @@ static long spmc_ffa_fill_desc(struct mailbox *mbox,
goto err_bad_desc;
}
/*
* If a partition ID resides in the secure world validate that the
* partition ID is for a known partition. Ignore any partition ID
* belonging to the normal world as it is assumed the Hypervisor will
* have validated these.
*/
for (size_t i = 0; i < obj->desc.emad_count; i++) {
emad = spmc_shmem_obj_get_emad(&obj->desc, i, ffa_version,
&emad_size);
ffa_endpoint_id16_t ep_id = emad->mapd.endpoint_id;
if (ffa_is_secure_world_id(ep_id)) {
if (spmc_get_sp_ctx(ep_id) == NULL) {
WARN("%s: Invalid receiver id 0x%x\n",
__func__, ep_id);
ret = FFA_ERROR_INVALID_PARAMETER;
goto err_bad_desc;
}
}
}
/* Ensure partition IDs are not duplicated. */
for (size_t i = 0; i < obj->desc.emad_count; i++) {
emad = spmc_shmem_obj_get_emad(&obj->desc, i, ffa_version,