fix(el3-spmc): check descriptor size for overflow

Ensure that the provided descriptor size used when reserving space
for a memory descriptor does not overflow to prevent scope for
memory corruption. Reported by Matt Oh, Google Android Red Team.

Reported-by: mattoh@google.com
Signed-off-by: Marc Bonnici <marc.bonnici@arm.com>
Change-Id: If06985c4de9a88ff82ce60d10e346da948ed383f
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 d4d0407..89d7b31 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 @@
 {
 	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 @@
 	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;
 }