summaryrefslogtreecommitdiff
path: root/services/std_svc
diff options
context:
space:
mode:
authorOlivier Deprez <olivier.deprez@arm.com>2023-06-20 16:07:36 +0200
committerTrustedFirmware Code Review <review@review.trustedfirmware.org>2023-06-20 16:07:36 +0200
commite779c1afe23dc087d93f5b8af4c9a9240cab98a3 (patch)
tree23c2751eb2a47445336fe49539bcfa85a28e0e85 /services/std_svc
parent1f58063bf998c4d77573006b2e323a06ded471b9 (diff)
parent794c409f48497dd4cd87a21893fd35ecc7243404 (diff)
Merge changes Ic58f4966,Ib7b438b8,I400f0f1f into integration
* changes: refactor(el3-spmc): add comments refactor(el3-spmc): move checks after loop refactor(el3-spmc): validate alignment earlier
Diffstat (limited to 'services/std_svc')
-rw-r--r--services/std_svc/spm/el3_spmc/spmc_shared_mem.c139
1 files changed, 70 insertions, 69 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 8183a0a29..15c7e91da 100644
--- a/services/std_svc/spm/el3_spmc/spmc_shared_mem.c
+++ b/services/std_svc/spm/el3_spmc/spmc_shared_mem.c
@@ -777,10 +777,16 @@ emad_advance(const struct ffa_emad_v1_0 *emad, size_t offset)
static int spmc_shmem_check_obj(struct spmc_shmem_obj *obj,
uint32_t ffa_version)
{
+ uint64_t total_page_count;
const struct ffa_emad_v1_0 *first_emad;
const struct ffa_emad_v1_0 *end_emad;
size_t emad_size;
uint32_t comp_mrd_offset = 0;
+ size_t header_emad_size;
+ size_t size;
+ size_t count;
+ size_t expected_size;
+ struct ffa_comp_mrd *comp;
if (obj->desc_filled != obj->desc_size) {
ERROR("BUG: %s called on incomplete object (%zu != %zu)\n",
@@ -798,22 +804,14 @@ static int spmc_shmem_check_obj(struct spmc_shmem_obj *obj,
first_emad = spmc_shmem_obj_get_emad(&obj->desc, 0,
ffa_version, &emad_size);
end_emad = emad_advance(first_emad, obj->desc.emad_count * emad_size);
+ comp_mrd_offset = first_emad->comp_mrd_offset;
/* Loop through the endpoint descriptors, validating each of them. */
for (const struct ffa_emad_v1_0 *emad = first_emad;
emad < end_emad;
emad = emad_advance(emad, emad_size)) {
- size_t size;
- size_t count;
- size_t expected_size;
- uint64_t total_page_count;
- size_t header_emad_size;
- uint32_t offset;
- struct ffa_comp_mrd *comp;
ffa_endpoint_id16_t ep_id;
- 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
@@ -831,82 +829,85 @@ static int spmc_shmem_check_obj(struct spmc_shmem_obj *obj,
/*
* The offset provided to the composite memory region descriptor
- * should be consistent across endpoint descriptors. Store the
- * first entry and compare against subsequent entries.
+ * should be consistent across endpoint descriptors.
*/
- if (comp_mrd_offset == 0) {
- comp_mrd_offset = offset;
- } else {
- if (comp_mrd_offset != offset) {
- ERROR("%s: mismatching offsets provided, %u != %u\n",
- __func__, offset, comp_mrd_offset);
- return FFA_ERROR_INVALID_PARAMETER;
- }
- continue; /* Remainder only executed on first iteration. */
+ if (comp_mrd_offset != emad->comp_mrd_offset) {
+ ERROR("%s: mismatching offsets provided, %u != %u\n",
+ __func__, emad->comp_mrd_offset, comp_mrd_offset);
+ return FFA_ERROR_INVALID_PARAMETER;
}
+ }
- header_emad_size = (size_t)((uint8_t *)emad - (uint8_t *)&obj->desc) +
- (obj->desc.emad_count * emad_size);
+ header_emad_size = (size_t)((const uint8_t *)end_emad -
+ (const uint8_t *)&obj->desc);
- if (offset < header_emad_size) {
- WARN("%s: invalid object, offset %u < header + emad %zu\n",
- __func__, offset, header_emad_size);
- return FFA_ERROR_INVALID_PARAMETER;
- }
+ /*
+ * Check that the composite descriptor
+ * is after the endpoint descriptors.
+ */
+ if (comp_mrd_offset < header_emad_size) {
+ WARN("%s: invalid object, offset %u < header + emad %zu\n",
+ __func__, comp_mrd_offset, header_emad_size);
+ return FFA_ERROR_INVALID_PARAMETER;
+ }
- size = obj->desc_size;
+ /* Ensure the composite descriptor offset is aligned. */
+ if (!is_aligned(comp_mrd_offset, 16)) {
+ WARN("%s: invalid object, unaligned composite memory "
+ "region descriptor offset %u.\n",
+ __func__, comp_mrd_offset);
+ return FFA_ERROR_INVALID_PARAMETER;
+ }
- if (offset > size) {
- WARN("%s: invalid object, offset %u > total size %zu\n",
- __func__, offset, obj->desc_size);
- return FFA_ERROR_INVALID_PARAMETER;
- }
- size -= offset;
+ size = obj->desc_size;
- if (size < sizeof(struct ffa_comp_mrd)) {
- WARN("%s: invalid object, offset %u, total size %zu, no header space.\n",
- __func__, offset, obj->desc_size);
- return FFA_ERROR_INVALID_PARAMETER;
- }
- size -= sizeof(struct ffa_comp_mrd);
+ /* Check that the composite descriptor is in bounds. */
+ if (comp_mrd_offset > size) {
+ WARN("%s: invalid object, offset %u > total size %zu\n",
+ __func__, comp_mrd_offset, obj->desc_size);
+ return FFA_ERROR_INVALID_PARAMETER;
+ }
+ size -= comp_mrd_offset;
- count = size / sizeof(struct ffa_cons_mrd);
+ if (size < sizeof(struct ffa_comp_mrd)) {
+ WARN("%s: invalid object, offset %u, total size %zu, no header space.\n",
+ __func__, comp_mrd_offset, obj->desc_size);
+ return FFA_ERROR_INVALID_PARAMETER;
+ }
+ size -= sizeof(struct ffa_comp_mrd);
- comp = spmc_shmem_obj_get_comp_mrd(obj, ffa_version);
+ count = size / sizeof(struct ffa_cons_mrd);
- if (comp == NULL) {
- WARN("%s: invalid comp_mrd offset\n", __func__);
- return FFA_ERROR_INVALID_PARAMETER;
- }
+ comp = spmc_shmem_obj_get_comp_mrd(obj, ffa_version);
- if (comp->address_range_count != count) {
- WARN("%s: invalid object, desc count %u != %zu\n",
- __func__, comp->address_range_count, count);
- return FFA_ERROR_INVALID_PARAMETER;
- }
+ if (comp->address_range_count != count) {
+ WARN("%s: invalid object, desc count %u != %zu\n",
+ __func__, comp->address_range_count, count);
+ return FFA_ERROR_INVALID_PARAMETER;
+ }
- expected_size = offset + sizeof(*comp) +
- count * sizeof(struct ffa_cons_mrd);
+ expected_size = comp_mrd_offset + sizeof(*comp) +
+ count * sizeof(struct ffa_cons_mrd);
- if (expected_size != obj->desc_size) {
- WARN("%s: invalid object, computed size %zu != size %zu\n",
- __func__, expected_size, obj->desc_size);
- return FFA_ERROR_INVALID_PARAMETER;
- }
+ if (expected_size != obj->desc_size) {
+ WARN("%s: invalid object, computed size %zu != size %zu\n",
+ __func__, expected_size, obj->desc_size);
+ return FFA_ERROR_INVALID_PARAMETER;
+ }
- total_page_count = 0;
+ total_page_count = 0;
- for (size_t i = 0; i < count; i++) {
- total_page_count +=
- comp->address_range_array[i].page_count;
- }
- if (comp->total_page_count != total_page_count) {
- WARN("%s: invalid object, desc total_page_count %u != %" PRIu64 "\n",
- __func__, comp->total_page_count,
- total_page_count);
- return FFA_ERROR_INVALID_PARAMETER;
- }
+ for (size_t i = 0; i < count; i++) {
+ total_page_count +=
+ comp->address_range_array[i].page_count;
+ }
+ if (comp->total_page_count != total_page_count) {
+ WARN("%s: invalid object, desc total_page_count %u != %" PRIu64 "\n",
+ __func__, comp->total_page_count,
+ total_page_count);
+ return FFA_ERROR_INVALID_PARAMETER;
}
+
return 0;
}