Skip to content

Commit 65ffe80

Browse files
committed
core: spmc: reject too small mem_access_size
The endpoint memory access descriptor array in an FF-A memory transaction is described by mem_access_size, mem_access_count and mem_access_offs, read from a normal-world (or SP) descriptor. spmc_read_mem_transaction() checks that the array fits in the fragment but does not bound mem_access_size from below. Each array element is dereferenced as struct ffa_mem_access_common by its users: get_acc_perms(), spmc_sp_add_share() and ffa_mem_retrieve(). With mem_access_size smaller than that structure the array-fit check no longer keeps each element read in range; with mem_access_size 0 and mem_access_offs equal to frag_len the read lands past the mapped buffer, an out-of-bounds read in the SPMC. Check mem_access_size against sizeof(struct ffa_mem_access_common) in each user of the descriptor, so every site validates the stride is large enough for what it reads. Signed-off-by: Guled Hasan <Law.Zoldyck@proton.me>
1 parent a85cb55 commit 65ffe80

2 files changed

Lines changed: 13 additions & 0 deletions

File tree

core/arch/arm/kernel/spmc_sp_handler.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,11 @@ int spmc_sp_add_share(struct ffa_mem_transaction_x *mem_trans,
344344
goto cleanup;
345345
}
346346

347+
if (mem_acc_size < sizeof(struct ffa_mem_access_common)) {
348+
res = FFA_INVALID_PARAMETERS;
349+
goto cleanup;
350+
}
351+
347352
/* Store the ffa_mem_transaction */
348353
smem->sender_id = sender_id;
349354
smem->mem_reg_attr = mem_trans->mem_reg_attr;
@@ -672,6 +677,11 @@ static void ffa_mem_retrieve(struct thread_smc_1_2_regs *args,
672677
if (ret)
673678
goto err_set;
674679

680+
if (mem_trans.mem_access_size < sizeof(struct ffa_mem_access_common)) {
681+
ret = FFA_INVALID_PARAMETERS;
682+
goto err_set;
683+
}
684+
675685
smem = sp_mem_lookup_and_read_lock(mem_trans.global_handle);
676686
if (!smem) {
677687
DMSG("Incorrect handle");

core/arch/arm/kernel/thread_spmc.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1078,6 +1078,9 @@ static int get_acc_perms(vaddr_t mem_acc_base, unsigned int mem_access_size,
10781078
struct ffa_mem_access_perm *descr = NULL;
10791079
unsigned int n = 0;
10801080

1081+
if (mem_access_size < sizeof(struct ffa_mem_access_common))
1082+
return FFA_INVALID_PARAMETERS;
1083+
10811084
for (n = 0; n < mem_access_count; n++) {
10821085
mem_acc = (void *)(mem_acc_base + mem_access_size * n);
10831086
descr = &mem_acc->access_perm;

0 commit comments

Comments
 (0)