Re: [PATCH v7 4/7] KVM: arm64: Fix bounds checking in do_ffa_mem_reclaim()
Vincent Donnefort via OP-TEE <[email protected]> Thu, 18 Jun 2026 17:19:20 +0100
| Newsgroups | org.trustedfirmware.lists.op-tee,dev.linux.lists.kvmarm,org.infradead.lists.linux-arm-kernel,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
On Wed, Jun 17, 2026 at 02:51:27PM +0000, Sebastian Ene wrote: > From: Mostafa Saleh <[email protected]> > > Sashiko (locally) reports out of bound write possiblity if SPMD > returns an invalid data. > > While SPMD is considered trusted, pKVM does some basic checks, > for offset to be less than or equal len. > > However, that is incorrect as even if the offset is smaller than > len pKVM can still access out of bound memory in the next > ffa_host_unshare_ranges(). > > Split this check into 2: > 1- Check that the fixed portion of the descriptor fits. > 2- After getting reg, check the variable array size addr_range_cnt > fits. > > Also, drop the WARN_ONs as that will panic the kernel and in the > next checks there are no WARNs, so that makes it consistent. > > Fixes: 0a9f15fd5674 ("KVM: arm64: pkvm: Add support for fragmented FF-A descriptors") > Signed-off-by: Mostafa Saleh <[email protected]> > Signed-off-by: Sebastian Ene <[email protected]> FTR, I believe the comment about composite_off in include/linux/arm_ffa.h is incorrect. It is an offset to a ffa_composite_mem_region (not a ffa_mem_region_addr_range) Reviewed-by: Vincent Donnefort <[email protected]> > --- > arch/arm64/kvm/hyp/nvhe/ffa.c | 12 +++++++++--- > 1 file changed, 9 insertions(+), 3 deletions(-) > > diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c > index 1af722771178..2d211661952e 100644 > --- a/arch/arm64/kvm/hyp/nvhe/ffa.c > +++ b/arch/arm64/kvm/hyp/nvhe/ffa.c > @@ -607,8 +607,8 @@ static void do_ffa_mem_reclaim(struct arm_smccc_1_2_regs *res, > * check that we end up with something that doesn't look _completely_ > * bogus. > */ > - if (WARN_ON(offset > len || > - fraglen > KVM_FFA_MBOX_NR_PAGES * PAGE_SIZE)) { > + if (offset + CONSTITUENTS_OFFSET(0) > len || > + fraglen > KVM_FFA_MBOX_NR_PAGES * PAGE_SIZE) { > ret = FFA_RET_ABORTED; > ffa_rx_release(res); > goto out_unlock; > @@ -636,11 +636,17 @@ static void do_ffa_mem_reclaim(struct arm_smccc_1_2_regs *res, > ffa_rx_release(res); > } > > + reg = (void *)buf + offset; > + if (offset + CONSTITUENTS_OFFSET(reg->addr_range_cnt) > len) { > + ret = FFA_RET_ABORTED; > + ffa_rx_release(res); > + goto out_unlock; > + } > + > ffa_mem_reclaim(res, handle_lo, handle_hi, flags); > if (res->a0 != FFA_SUCCESS) > goto out_unlock; > > - reg = (void *)buf + offset; > /* If the SPMD was happy, then we should be too. */ > WARN_ON(ffa_host_unshare_ranges(reg->constituents, > reg->addr_range_cnt)); > -- > 2.54.0.1136.gdb2ca164c4-goog >