mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-26 14:55:16 +00:00
Merge changes I907f3862,Ie749ff06,If8da2bb1,I457deb0b into integration
* changes: fix(el3-spmc): validate shmem descriptor alignment refactor(el3-spmc): avoid using EINVAL fix(el3-spmc): avoid descriptor size calc overflow fix(el3-spmc): use uint64_t for 64-bit type
This commit is contained in:
commit
396ea00a83
1 changed files with 36 additions and 34 deletions
|
@ -80,6 +80,13 @@ spmc_shmem_obj_alloc(struct spmc_shmem_obj_state *state, size_t desc_size)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Ensure that descriptor size is aligned */
|
||||||
|
if (!is_aligned(desc_size, 16)) {
|
||||||
|
WARN("%s(0x%zx) desc_size not 16-byte aligned\n",
|
||||||
|
__func__, desc_size);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
obj_size = spmc_shmem_obj_size(desc_size);
|
obj_size = spmc_shmem_obj_size(desc_size);
|
||||||
|
|
||||||
/* Ensure the obj size has not overflowed. */
|
/* Ensure the obj size has not overflowed. */
|
||||||
|
@ -352,10 +359,10 @@ overlapping_memory_regions(struct ffa_comp_mrd *region1,
|
||||||
*
|
*
|
||||||
* Return: the size required to store the descriptor store in the v1.1 format.
|
* Return: the size required to store the descriptor store in the v1.1 format.
|
||||||
*/
|
*/
|
||||||
static size_t
|
static uint64_t
|
||||||
spmc_shm_get_v1_1_descriptor_size(struct ffa_mtd_v1_0 *orig, size_t desc_size)
|
spmc_shm_get_v1_1_descriptor_size(struct ffa_mtd_v1_0 *orig, size_t desc_size)
|
||||||
{
|
{
|
||||||
size_t size = 0;
|
uint64_t size = 0;
|
||||||
struct ffa_comp_mrd *mrd;
|
struct ffa_comp_mrd *mrd;
|
||||||
struct ffa_emad_v1_0 *emad_array = orig->emad;
|
struct ffa_emad_v1_0 *emad_array = orig->emad;
|
||||||
|
|
||||||
|
@ -372,11 +379,7 @@ spmc_shm_get_v1_1_descriptor_size(struct ffa_mtd_v1_0 *orig, size_t desc_size)
|
||||||
mrd = (struct ffa_comp_mrd *) ((uint8_t *) orig +
|
mrd = (struct ffa_comp_mrd *) ((uint8_t *) orig +
|
||||||
emad_array[0].comp_mrd_offset);
|
emad_array[0].comp_mrd_offset);
|
||||||
|
|
||||||
/* Check the calculated address is within the memory descriptor. */
|
/* Add the size of the memory region descriptors. */
|
||||||
if (((uintptr_t) mrd + sizeof(struct ffa_comp_mrd)) >
|
|
||||||
(uintptr_t)((uint8_t *) orig + desc_size)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
size += mrd->address_range_count * sizeof(struct ffa_cons_mrd);
|
size += mrd->address_range_count * sizeof(struct ffa_cons_mrd);
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
|
@ -762,8 +765,8 @@ spmc_validate_mtd_start(struct ffa_mtd *desc, uint32_t ffa_version,
|
||||||
* @obj: Object containing ffa_memory_region_descriptor.
|
* @obj: Object containing ffa_memory_region_descriptor.
|
||||||
* @ffa_version: FF-A version of the provided descriptor.
|
* @ffa_version: FF-A version of the provided descriptor.
|
||||||
*
|
*
|
||||||
* Return: 0 if object is valid, -EINVAL if constituent_memory_region_descriptor
|
* Return: 0 if object is valid, FFA_ERROR_INVALID_PARAMETER if
|
||||||
* offset or count is invalid.
|
* constituent_memory_region_descriptor offset or count is invalid.
|
||||||
*/
|
*/
|
||||||
static int spmc_shmem_check_obj(struct spmc_shmem_obj *obj,
|
static int spmc_shmem_check_obj(struct spmc_shmem_obj *obj,
|
||||||
uint32_t ffa_version)
|
uint32_t ffa_version)
|
||||||
|
@ -822,7 +825,7 @@ static int spmc_shmem_check_obj(struct spmc_shmem_obj *obj,
|
||||||
if (spmc_get_sp_ctx(ep_id) == NULL) {
|
if (spmc_get_sp_ctx(ep_id) == NULL) {
|
||||||
WARN("%s: Invalid receiver id 0x%x\n",
|
WARN("%s: Invalid receiver id 0x%x\n",
|
||||||
__func__, ep_id);
|
__func__, ep_id);
|
||||||
return -EINVAL;
|
return FFA_ERROR_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -837,7 +840,7 @@ static int spmc_shmem_check_obj(struct spmc_shmem_obj *obj,
|
||||||
if (comp_mrd_offset != offset) {
|
if (comp_mrd_offset != offset) {
|
||||||
ERROR("%s: mismatching offsets provided, %u != %u\n",
|
ERROR("%s: mismatching offsets provided, %u != %u\n",
|
||||||
__func__, offset, comp_mrd_offset);
|
__func__, offset, comp_mrd_offset);
|
||||||
return -EINVAL;
|
return FFA_ERROR_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
continue; /* Remainder only executed on first iteration. */
|
continue; /* Remainder only executed on first iteration. */
|
||||||
}
|
}
|
||||||
|
@ -848,7 +851,7 @@ static int spmc_shmem_check_obj(struct spmc_shmem_obj *obj,
|
||||||
if (offset < header_emad_size) {
|
if (offset < header_emad_size) {
|
||||||
WARN("%s: invalid object, offset %u < header + emad %zu\n",
|
WARN("%s: invalid object, offset %u < header + emad %zu\n",
|
||||||
__func__, offset, header_emad_size);
|
__func__, offset, header_emad_size);
|
||||||
return -EINVAL;
|
return FFA_ERROR_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
size = obj->desc_size;
|
size = obj->desc_size;
|
||||||
|
@ -856,14 +859,14 @@ static int spmc_shmem_check_obj(struct spmc_shmem_obj *obj,
|
||||||
if (offset > size) {
|
if (offset > size) {
|
||||||
WARN("%s: invalid object, offset %u > total size %zu\n",
|
WARN("%s: invalid object, offset %u > total size %zu\n",
|
||||||
__func__, offset, obj->desc_size);
|
__func__, offset, obj->desc_size);
|
||||||
return -EINVAL;
|
return FFA_ERROR_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
size -= offset;
|
size -= offset;
|
||||||
|
|
||||||
if (size < sizeof(struct ffa_comp_mrd)) {
|
if (size < sizeof(struct ffa_comp_mrd)) {
|
||||||
WARN("%s: invalid object, offset %u, total size %zu, no header space.\n",
|
WARN("%s: invalid object, offset %u, total size %zu, no header space.\n",
|
||||||
__func__, offset, obj->desc_size);
|
__func__, offset, obj->desc_size);
|
||||||
return -EINVAL;
|
return FFA_ERROR_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
size -= sizeof(struct ffa_comp_mrd);
|
size -= sizeof(struct ffa_comp_mrd);
|
||||||
|
|
||||||
|
@ -873,13 +876,13 @@ static int spmc_shmem_check_obj(struct spmc_shmem_obj *obj,
|
||||||
|
|
||||||
if (comp == NULL) {
|
if (comp == NULL) {
|
||||||
WARN("%s: invalid comp_mrd offset\n", __func__);
|
WARN("%s: invalid comp_mrd offset\n", __func__);
|
||||||
return -EINVAL;
|
return FFA_ERROR_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (comp->address_range_count != count) {
|
if (comp->address_range_count != count) {
|
||||||
WARN("%s: invalid object, desc count %u != %zu\n",
|
WARN("%s: invalid object, desc count %u != %zu\n",
|
||||||
__func__, comp->address_range_count, count);
|
__func__, comp->address_range_count, count);
|
||||||
return -EINVAL;
|
return FFA_ERROR_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
expected_size = offset + sizeof(*comp) +
|
expected_size = offset + sizeof(*comp) +
|
||||||
|
@ -888,7 +891,7 @@ static int spmc_shmem_check_obj(struct spmc_shmem_obj *obj,
|
||||||
if (expected_size != obj->desc_size) {
|
if (expected_size != obj->desc_size) {
|
||||||
WARN("%s: invalid object, computed size %zu != size %zu\n",
|
WARN("%s: invalid object, computed size %zu != size %zu\n",
|
||||||
__func__, expected_size, obj->desc_size);
|
__func__, expected_size, obj->desc_size);
|
||||||
return -EINVAL;
|
return FFA_ERROR_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
total_page_count = 0;
|
total_page_count = 0;
|
||||||
|
@ -901,7 +904,7 @@ static int spmc_shmem_check_obj(struct spmc_shmem_obj *obj,
|
||||||
WARN("%s: invalid object, desc total_page_count %u != %" PRIu64 "\n",
|
WARN("%s: invalid object, desc total_page_count %u != %" PRIu64 "\n",
|
||||||
__func__, comp->total_page_count,
|
__func__, comp->total_page_count,
|
||||||
total_page_count);
|
total_page_count);
|
||||||
return -EINVAL;
|
return FFA_ERROR_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -914,7 +917,8 @@ static int spmc_shmem_check_obj(struct spmc_shmem_obj *obj,
|
||||||
* the memory is not in a valid state for lending.
|
* the memory is not in a valid state for lending.
|
||||||
* @obj: Object containing ffa_memory_region_descriptor.
|
* @obj: Object containing ffa_memory_region_descriptor.
|
||||||
*
|
*
|
||||||
* Return: 0 if object is valid, -EINVAL if invalid memory state.
|
* Return: 0 if object is valid, FFA_ERROR_INVALID_PARAMETER if invalid memory
|
||||||
|
* state.
|
||||||
*/
|
*/
|
||||||
static int spmc_shmem_check_state_obj(struct spmc_shmem_obj *obj,
|
static int spmc_shmem_check_state_obj(struct spmc_shmem_obj *obj,
|
||||||
uint32_t ffa_version)
|
uint32_t ffa_version)
|
||||||
|
@ -927,7 +931,7 @@ static int spmc_shmem_check_state_obj(struct spmc_shmem_obj *obj,
|
||||||
ffa_version);
|
ffa_version);
|
||||||
|
|
||||||
if (requested_mrd == NULL) {
|
if (requested_mrd == NULL) {
|
||||||
return -EINVAL;
|
return FFA_ERROR_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
inflight_obj = spmc_shmem_obj_get_next(&spmc_shmem_obj_state,
|
inflight_obj = spmc_shmem_obj_get_next(&spmc_shmem_obj_state,
|
||||||
|
@ -943,11 +947,11 @@ static int spmc_shmem_check_state_obj(struct spmc_shmem_obj *obj,
|
||||||
other_mrd = spmc_shmem_obj_get_comp_mrd(inflight_obj,
|
other_mrd = spmc_shmem_obj_get_comp_mrd(inflight_obj,
|
||||||
FFA_VERSION_COMPILED);
|
FFA_VERSION_COMPILED);
|
||||||
if (other_mrd == NULL) {
|
if (other_mrd == NULL) {
|
||||||
return -EINVAL;
|
return FFA_ERROR_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
if (overlapping_memory_regions(requested_mrd,
|
if (overlapping_memory_regions(requested_mrd,
|
||||||
other_mrd)) {
|
other_mrd)) {
|
||||||
return -EINVAL;
|
return FFA_ERROR_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -977,9 +981,10 @@ static long spmc_ffa_fill_desc(struct mailbox *mbox,
|
||||||
goto err_arg;
|
goto err_arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fragment_length > mbox->rxtx_page_count * PAGE_SIZE_4KB) {
|
CASSERT(sizeof(mbox->rxtx_page_count) == 4, assert_bogus_page_count);
|
||||||
WARN("%s: bad fragment size %u > %u buffer size\n", __func__,
|
if (fragment_length > (uint64_t)mbox->rxtx_page_count * PAGE_SIZE_4KB) {
|
||||||
fragment_length, mbox->rxtx_page_count * PAGE_SIZE_4KB);
|
WARN("%s: bad fragment size %u > %" PRIu64 " buffer size\n", __func__,
|
||||||
|
fragment_length, (uint64_t)mbox->rxtx_page_count * PAGE_SIZE_4KB);
|
||||||
ret = FFA_ERROR_INVALID_PARAMETER;
|
ret = FFA_ERROR_INVALID_PARAMETER;
|
||||||
goto err_arg;
|
goto err_arg;
|
||||||
}
|
}
|
||||||
|
@ -1048,7 +1053,6 @@ static long spmc_ffa_fill_desc(struct mailbox *mbox,
|
||||||
|
|
||||||
ret = spmc_shmem_check_obj(obj, ffa_version);
|
ret = spmc_shmem_check_obj(obj, ffa_version);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
ret = FFA_ERROR_INVALID_PARAMETER;
|
|
||||||
goto err_bad_desc;
|
goto err_bad_desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1075,7 +1079,6 @@ static long spmc_ffa_fill_desc(struct mailbox *mbox,
|
||||||
ret = spmc_shmem_check_state_obj(obj, ffa_version);
|
ret = spmc_shmem_check_state_obj(obj, ffa_version);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
ERROR("%s: invalid memory region descriptor.\n", __func__);
|
ERROR("%s: invalid memory region descriptor.\n", __func__);
|
||||||
ret = FFA_ERROR_INVALID_PARAMETER;
|
|
||||||
goto err_bad_desc;
|
goto err_bad_desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1088,19 +1091,18 @@ static long spmc_ffa_fill_desc(struct mailbox *mbox,
|
||||||
uint64_t mem_handle;
|
uint64_t mem_handle;
|
||||||
|
|
||||||
/* Calculate the size that the v1.1 descriptor will required. */
|
/* Calculate the size that the v1.1 descriptor will required. */
|
||||||
size_t v1_1_desc_size =
|
uint64_t v1_1_desc_size =
|
||||||
spmc_shm_get_v1_1_descriptor_size((void *) &obj->desc,
|
spmc_shm_get_v1_1_descriptor_size((void *) &obj->desc,
|
||||||
obj->desc_size);
|
obj->desc_size);
|
||||||
|
|
||||||
if (v1_1_desc_size == 0U) {
|
if (v1_1_desc_size > UINT32_MAX) {
|
||||||
ERROR("%s: cannot determine size of descriptor.\n",
|
ret = FFA_ERROR_NO_MEMORY;
|
||||||
__func__);
|
|
||||||
goto err_arg;
|
goto err_arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get a new obj to store the v1.1 descriptor. */
|
/* Get a new obj to store the v1.1 descriptor. */
|
||||||
v1_1_obj =
|
v1_1_obj =
|
||||||
spmc_shmem_obj_alloc(&spmc_shmem_obj_state, v1_1_desc_size);
|
spmc_shmem_obj_alloc(&spmc_shmem_obj_state, (size_t)v1_1_desc_size);
|
||||||
|
|
||||||
if (!v1_1_obj) {
|
if (!v1_1_obj) {
|
||||||
ret = FFA_ERROR_NO_MEMORY;
|
ret = FFA_ERROR_NO_MEMORY;
|
||||||
|
@ -1108,8 +1110,8 @@ static long spmc_ffa_fill_desc(struct mailbox *mbox,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Perform the conversion from v1.0 to v1.1. */
|
/* Perform the conversion from v1.0 to v1.1. */
|
||||||
v1_1_obj->desc_size = v1_1_desc_size;
|
v1_1_obj->desc_size = (uint32_t)v1_1_desc_size;
|
||||||
v1_1_obj->desc_filled = v1_1_desc_size;
|
v1_1_obj->desc_filled = (uint32_t)v1_1_desc_size;
|
||||||
if (!spmc_shm_convert_shmem_obj_from_v1_0(v1_1_obj, obj)) {
|
if (!spmc_shm_convert_shmem_obj_from_v1_0(v1_1_obj, obj)) {
|
||||||
ERROR("%s: Could not convert mtd!\n", __func__);
|
ERROR("%s: Could not convert mtd!\n", __func__);
|
||||||
spmc_shmem_obj_free(&spmc_shmem_obj_state, v1_1_obj);
|
spmc_shmem_obj_free(&spmc_shmem_obj_state, v1_1_obj);
|
||||||
|
|
Loading…
Add table
Reference in a new issue