diff options
author | Joanna Farley <joanna.farley@arm.com> | 2022-11-10 13:46:33 +0100 |
---|---|---|
committer | TrustedFirmware Code Review <review@review.trustedfirmware.org> | 2022-11-10 13:46:33 +0100 |
commit | 7eb6fa4a2200f7f2218ce16fe342c239a39bbc75 (patch) | |
tree | fd36ed98520020dd0a1beb090dc0cbd4d9e361d9 /services | |
parent | 0d41e17400ba55ff007154dfd55ea59fd838c360 (diff) | |
parent | eed15e4310a7bcd90bf6d66b00037e05186329bb (diff) | |
download | arm-trusted-firmware-7eb6fa4a2200f7f2218ce16fe342c239a39bbc75.tar.gz |
Merge changes from topic "ffa_el3_spmc_fixes" into integration
* changes:
fix(el3-spmc): check descriptor size for overflow
fix(el3-spmc): fix location of fragment length check
fix(el3-spmc): fix detection of overlapping memory regions
fix(el3-spmc): fix incomplete reclaim validation
Diffstat (limited to 'services')
-rw-r--r-- | services/std_svc/spm/el3_spmc/spmc_shared_mem.c | 34 |
1 files changed, 25 insertions, 9 deletions
diff --git a/services/std_svc/spm/el3_spmc/spmc_shared_mem.c b/services/std_svc/spm/el3_spmc/spmc_shared_mem.c index 1da2efc14..89d7b3177 100644 --- a/services/std_svc/spm/el3_spmc/spmc_shared_mem.c +++ b/services/std_svc/spm/el3_spmc/spmc_shared_mem.c @@ -72,13 +72,23 @@ spmc_shmem_obj_alloc(struct spmc_shmem_obj_state *state, size_t desc_size) { struct spmc_shmem_obj *obj; size_t free = state->data_size - state->allocated; + size_t obj_size; if (state->data == NULL) { ERROR("Missing shmem datastore!\n"); return NULL; } - if (spmc_shmem_obj_size(desc_size) > free) { + obj_size = spmc_shmem_obj_size(desc_size); + + /* Ensure the obj size has not overflowed. */ + if (obj_size < desc_size) { + WARN("%s(0x%zx) desc_size overflow\n", + __func__, desc_size); + return NULL; + } + + if (obj_size > free) { WARN("%s(0x%zx) failed, free 0x%zx\n", __func__, desc_size, free); return NULL; @@ -88,7 +98,7 @@ spmc_shmem_obj_alloc(struct spmc_shmem_obj_state *state, size_t desc_size) obj->desc_size = desc_size; obj->desc_filled = 0; obj->in_use = 0; - state->allocated += spmc_shmem_obj_size(desc_size); + state->allocated += obj_size; return obj; } @@ -330,10 +340,9 @@ overlapping_memory_regions(struct ffa_comp_mrd *region1, PAGE_SIZE_4KB; region2_end = region2_start + region2_size; - if ((region1_start >= region2_start && - region1_start < region2_end) || - (region1_end > region2_start - && region1_end < region2_end)) { + /* Check if regions are not overlapping. */ + if (!((region2_end <= region1_start) || + (region1_end <= region2_start))) { WARN("Overlapping mem regions 0x%lx-0x%lx & 0x%lx-0x%lx\n", region1_start, region1_end, region2_start, region2_end); @@ -886,9 +895,6 @@ static long spmc_ffa_fill_desc(struct mailbox *mbox, goto err_arg; } - memcpy((uint8_t *)&obj->desc + obj->desc_filled, - (uint8_t *) mbox->tx_buffer, fragment_length); - if (fragment_length > obj->desc_size - obj->desc_filled) { WARN("%s: bad fragment size %u > %zu remaining\n", __func__, fragment_length, obj->desc_size - obj->desc_filled); @@ -896,6 +902,9 @@ static long spmc_ffa_fill_desc(struct mailbox *mbox, goto err_arg; } + memcpy((uint8_t *)&obj->desc + obj->desc_filled, + (uint8_t *) mbox->tx_buffer, fragment_length); + /* Ensure that the sender ID resides in the normal world. */ if (ffa_is_secure_world_id(obj->desc.sender_id)) { WARN("%s: Invalid sender ID 0x%x.\n", @@ -1828,6 +1837,13 @@ int spmc_ffa_mem_reclaim(uint32_t smc_fid, goto err_unlock; } + if (obj->desc_filled != obj->desc_size) { + WARN("%s: incomplete object desc filled %zu < size %zu\n", + __func__, obj->desc_filled, obj->desc_size); + ret = FFA_ERROR_INVALID_PARAMETER; + goto err_unlock; + } + /* Allow for platform specific operations to be performed. */ ret = plat_spmc_shmem_reclaim(&obj->desc); if (ret != 0) { |