fix(memory share): check that lengths are 16-byte aligned
The fragment and total length must be 16-byte aligned. This ensures
that size of the constituents array is a multiple of sizeof(struct
ffa_memory_region_constituent) and that there will be no alignment
problems when dereferencing pointers.
Change-Id: I4e4ce76a1ad897d01e2fab1dad5e4e43dbd19832
Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
diff --git a/src/ffa_memory.c b/src/ffa_memory.c
index a7d94ec..85e8d62 100644
--- a/src/ffa_memory.c
+++ b/src/ffa_memory.c
@@ -1211,6 +1211,19 @@
return ffa_error(FFA_INVALID_PARAMETERS);
}
+ static_assert(sizeof(struct ffa_memory_region_constituent) == 16,
+ "struct ffa_memory_region_constituent must be 16 bytes");
+ if (!is_aligned(fragment_length,
+ sizeof(struct ffa_memory_region_constituent)) ||
+ !is_aligned(memory_share_length,
+ sizeof(struct ffa_memory_region_constituent))) {
+ dlog_verbose(
+ "Fragment length %u or total length %u"
+ " is not 16-byte aligned.\n",
+ fragment_length, memory_share_length);
+ return ffa_error(FFA_INVALID_PARAMETERS);
+ }
+
if (fragment_length > memory_share_length) {
dlog_verbose(
"Fragment length %u greater than total length %u.\n",
@@ -1657,6 +1670,16 @@
struct ffa_value ret;
struct ffa_memory_region *memory_region;
+ CHECK(is_aligned(fragment,
+ alignof(struct ffa_memory_region_constituent)));
+ if (fragment_length % sizeof(struct ffa_memory_region_constituent) !=
+ 0) {
+ dlog_verbose("Fragment length %u misaligned.\n",
+ fragment_length);
+ ret = ffa_error(FFA_INVALID_PARAMETERS);
+ goto out_free_fragment;
+ }
+
ret = ffa_memory_send_continue_validate(share_states, handle,
&share_state,
from_locked.vm->id, page_pool);