fix(memory sharing): validate specified total page count

Validate that page count specified in the memory region composite
structure, aligns with the calculated total of its consituents.

Change-Id: Iddaf59b9f83b0f7a0a7e8d45ab3eb1323f95f490
Signed-off-by: J-Alves <joao.alves@arm.com>
diff --git a/src/ffa_memory.c b/src/ffa_memory.c
index 92648e8..1c68ebb 100644
--- a/src/ffa_memory.c
+++ b/src/ffa_memory.c
@@ -808,15 +808,17 @@
 	struct vm_locked from_locked,
 	struct ffa_memory_region_constituent **fragments,
 	uint32_t *fragment_constituent_counts, uint32_t fragment_count,
-	uint32_t share_func, struct ffa_memory_access *receivers,
-	uint32_t receivers_count, struct mpool *page_pool, bool clear,
-	uint32_t *orig_from_mode_ret)
+	uint32_t composite_total_page_count, uint32_t share_func,
+	struct ffa_memory_access *receivers, uint32_t receivers_count,
+	struct mpool *page_pool, bool clear, uint32_t *orig_from_mode_ret)
 {
 	uint32_t i;
+	uint32_t j;
 	uint32_t orig_from_mode;
 	uint32_t from_mode;
 	struct mpool local_page_pool;
 	struct ffa_value ret;
+	uint32_t constituents_total_page_count = 0;
 
 	/*
 	 * Make sure constituents are properly aligned to a 64-bit boundary. If
@@ -827,6 +829,17 @@
 			dlog_verbose("Constituents not aligned.\n");
 			return ffa_error(FFA_INVALID_PARAMETERS);
 		}
+		for (j = 0; j < fragment_constituent_counts[i]; ++j) {
+			constituents_total_page_count +=
+				fragments[i][j].page_count;
+		}
+	}
+
+	if (constituents_total_page_count != composite_total_page_count) {
+		dlog_verbose(
+			"Composite page count differs from calculated page "
+			"count from constituents.\n");
+		return ffa_error(FFA_INVALID_PARAMETERS);
 	}
 
 	/*
@@ -1112,18 +1125,23 @@
 	uint32_t *orig_from_mode_ret)
 {
 	struct ffa_memory_region *memory_region = share_state->memory_region;
+	struct ffa_composite_memory_region *composite;
 	struct ffa_value ret;
 
 	/* Lock must be held. */
 	assert(share_states.share_states != NULL);
+	assert(memory_region != NULL);
+	composite = ffa_memory_region_get_composite(memory_region, 0);
+	assert(composite != NULL);
 
 	/* Check that state is valid in sender page table and update. */
 	ret = ffa_send_check_update(
 		from_locked, share_state->fragments,
 		share_state->fragment_constituent_counts,
-		share_state->fragment_count, share_state->share_func,
-		memory_region->receivers, memory_region->receiver_count,
-		page_pool, memory_region->flags & FFA_MEMORY_REGION_FLAG_CLEAR,
+		share_state->fragment_count, composite->page_count,
+		share_state->share_func, memory_region->receivers,
+		memory_region->receiver_count, page_pool,
+		memory_region->flags & FFA_MEMORY_REGION_FLAG_CLEAR,
 		orig_from_mode_ret);
 	if (ret.func != FFA_SUCCESS_32) {
 		/*