* [PATCH v4 0/5] arm_ffa, KVM: Fix FF-A emad offset calculations
@ 2026-05-20 20:49 Mostafa Saleh
2026-05-20 20:49 ` [PATCH v4 1/5] optee: ffa: Add NULL check in optee_ffa_lend_protmem Mostafa Saleh
` (4 more replies)
0 siblings, 5 replies; 11+ messages in thread
From: Mostafa Saleh @ 2026-05-20 20:49 UTC (permalink / raw)
To: op-tee, linux-kernel, kvmarm, linux-arm-kernel
Cc: maz, oupton, joey.gouly, suzuki.poulose, catalin.marinas,
jens.wiklander, sumit.garg, sebastianene, vdonnefort,
sudeep.holla, Mostafa Saleh
Hi all,
This series fixes the Endpoint Memory Access Descriptor (EMAD) offset
calculations and adds the necessary bounds checks for both the core
FF-A driver and the pKVM hypervisor.
Prior to FF-A version 1.1, the memory region header didn't specify an
explicit offset for the EMADs, leading to the assumption that they
immediately follow the header.
However, from v1.1 onwards, the specification dictates using the
ep_mem_offset` field to determine the start of the memory access
array.
The patches in this series address this by:
1. Updating the core `arm_ffa` firmware driver to correctly calculate the descriptor
offset using `ep_mem_offset` rather than defaulting to `sizeof(struct ffa_mem_region)`.
It also introduces bounds checking against `max_fragsize`.
2. Enhancing the pKVM hypervisor validation logic to no longer strictly enforce that
the descriptor strictly follows the header, aligning it with the driver behavior
and the FF-A specification, while also ensuring the offset falls within the mailbox
buffer bounds.
While addressing these bugs, Sashiko uncovered other issues that were
fixed in the same series.
Changelog
#########
v3 -> v4:
- Address review comments and fix Sashiko bugs
v2 -> v3:
- Fixed typo in nvhe/ffa.c (missing sizeof)
v1 -> v2:
- For pKVM, removed the strict placement enforcement for `ep_mem_offset` as it is not
compliant with the spec, and avoids making assumptions about the driver's memory
layout.
Link to:
########
v3: https://lore.kernel.org/all/20260512124442.1899107-1-sebastianene@google.com/
v2: https://lore.kernel.org/all/20260430160241.1934777-1-sebastianene@google.com/
v1: https://lore.kernel.org/all/ae9KN9nkOgDYJcGP@google.com/T/#t
Mostafa Saleh (3):
optee: ffa: Add NULL check in optee_ffa_lend_protmem
firmware: arm_ffa: Fix out-of-bound writes in ffa_setup_and_transmit()
KVM: arm64: Fix bounds checking in do_ffa_mem_reclaim()
Sebastian Ene (2):
firmware: arm_ffa: Fix Endpoint Memory Access Descriptor offset
calculation
KVM: arm64: Validate the offset to the mem access descriptor
arch/arm64/kvm/hyp/nvhe/ffa.c | 30 +++++++++++++++++++++++-------
drivers/firmware/arm_ffa/driver.c | 21 +++++++++++++--------
drivers/tee/optee/ffa_abi.c | 3 +++
include/linux/arm_ffa.h | 2 +-
4 files changed, 40 insertions(+), 16 deletions(-)
--
2.54.0.669.g59709faab0-goog
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v4 1/5] optee: ffa: Add NULL check in optee_ffa_lend_protmem
2026-05-20 20:49 [PATCH v4 0/5] arm_ffa, KVM: Fix FF-A emad offset calculations Mostafa Saleh
@ 2026-05-20 20:49 ` Mostafa Saleh
2026-05-20 20:49 ` [PATCH v4 2/5] firmware: arm_ffa: Fix out-of-bound writes in ffa_setup_and_transmit() Mostafa Saleh
` (3 subsequent siblings)
4 siblings, 0 replies; 11+ messages in thread
From: Mostafa Saleh @ 2026-05-20 20:49 UTC (permalink / raw)
To: op-tee, linux-kernel, kvmarm, linux-arm-kernel
Cc: maz, oupton, joey.gouly, suzuki.poulose, catalin.marinas,
jens.wiklander, sumit.garg, sebastianene, vdonnefort,
sudeep.holla, Mostafa Saleh
Sashiko (locally) reports a possible null dereference under memory
pressure due to the lack of validation of the allocated pointer.
Fix that by adding the missing check.
Signed-off-by: Mostafa Saleh <smostafa@google.com>
---
drivers/tee/optee/ffa_abi.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/tee/optee/ffa_abi.c b/drivers/tee/optee/ffa_abi.c
index b4372fa268d0..633715b98625 100644
--- a/drivers/tee/optee/ffa_abi.c
+++ b/drivers/tee/optee/ffa_abi.c
@@ -698,6 +698,9 @@ static int optee_ffa_lend_protmem(struct optee *optee, struct tee_shm *protmem,
int rc;
mem_attr = kzalloc_objs(*mem_attr, ma_count);
+ if (!mem_attr)
+ return -ENOMEM;
+
for (n = 0; n < ma_count; n++) {
mem_attr[n].receiver = mem_attrs[n] & U16_MAX;
mem_attr[n].attrs = mem_attrs[n] >> 16;
--
2.54.0.669.g59709faab0-goog
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v4 2/5] firmware: arm_ffa: Fix out-of-bound writes in ffa_setup_and_transmit()
2026-05-20 20:49 [PATCH v4 0/5] arm_ffa, KVM: Fix FF-A emad offset calculations Mostafa Saleh
2026-05-20 20:49 ` [PATCH v4 1/5] optee: ffa: Add NULL check in optee_ffa_lend_protmem Mostafa Saleh
@ 2026-05-20 20:49 ` Mostafa Saleh
2026-05-21 12:51 ` Sudeep Holla
2026-05-20 20:49 ` [PATCH v4 3/5] firmware: arm_ffa: Fix Endpoint Memory Access Descriptor offset calculation Mostafa Saleh
` (2 subsequent siblings)
4 siblings, 1 reply; 11+ messages in thread
From: Mostafa Saleh @ 2026-05-20 20:49 UTC (permalink / raw)
To: op-tee, linux-kernel, kvmarm, linux-arm-kernel
Cc: maz, oupton, joey.gouly, suzuki.poulose, catalin.marinas,
jens.wiklander, sumit.garg, sebastianene, vdonnefort,
sudeep.holla, Mostafa Saleh
Sashiko (locally) reports multiple out-of-bound issues in
ffa_setup_and_transmit:
1) Writing ep_mem_access->reserved can write out of bounds for FFA
versions < 1.2 as ffa_emad_size_get() returns 16 bytes in that case
while reserved has an offset of 24.
Instead of zeroing fields, memset the struct to zero first based on
the FFA version.
2) Make sure there is enough size to write constituents.
While at it, convert the only sizeof() in the driver that uses a
type instead of variable.
Signed-off-by: Mostafa Saleh <smostafa@google.com>
---
drivers/firmware/arm_ffa/driver.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
index eb2782848283..b700b2e93e72 100644
--- a/drivers/firmware/arm_ffa/driver.c
+++ b/drivers/firmware/arm_ffa/driver.c
@@ -697,11 +697,10 @@ ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize,
for (idx = 0; idx < args->nattrs; idx++) {
ep_mem_access = buffer +
ffa_mem_desc_offset(buffer, idx, drv_info->version);
+ memset(ep_mem_access, 0, ffa_emad_size_get(drv_info->version));
ep_mem_access->receiver = args->attrs[idx].receiver;
ep_mem_access->attrs = args->attrs[idx].attrs;
ep_mem_access->composite_off = composite_offset;
- ep_mem_access->flag = 0;
- ep_mem_access->reserved = 0;
ffa_emad_impdef_value_init(drv_info->version,
ep_mem_access->impdef_val,
args->attrs[idx].impdef_val);
@@ -741,7 +740,7 @@ ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize,
constituents = buffer;
}
- if ((void *)constituents - buffer > max_fragsize) {
+ if ((void *)constituents + sizeof(*constituents) - buffer > max_fragsize) {
pr_err("Memory Region Fragment > Tx Buffer size\n");
return -EFAULT;
}
@@ -750,7 +749,7 @@ ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize,
constituents->pg_cnt = args->sg->length / FFA_PAGE_SIZE;
constituents->reserved = 0;
constituents++;
- frag_len += sizeof(struct ffa_mem_region_addr_range);
+ frag_len += sizeof(*constituents);
} while ((args->sg = sg_next(args->sg)));
return ffa_transmit_fragment(func_id, addr, buf_sz, frag_len,
--
2.54.0.669.g59709faab0-goog
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v4 3/5] firmware: arm_ffa: Fix Endpoint Memory Access Descriptor offset calculation
2026-05-20 20:49 [PATCH v4 0/5] arm_ffa, KVM: Fix FF-A emad offset calculations Mostafa Saleh
2026-05-20 20:49 ` [PATCH v4 1/5] optee: ffa: Add NULL check in optee_ffa_lend_protmem Mostafa Saleh
2026-05-20 20:49 ` [PATCH v4 2/5] firmware: arm_ffa: Fix out-of-bound writes in ffa_setup_and_transmit() Mostafa Saleh
@ 2026-05-20 20:49 ` Mostafa Saleh
2026-05-20 20:49 ` [PATCH v4 4/5] KVM: arm64: Fix bounds checking in do_ffa_mem_reclaim() Mostafa Saleh
2026-05-20 20:49 ` [PATCH v4 5/5] KVM: arm64: Validate the offset to the mem access descriptor Mostafa Saleh
4 siblings, 0 replies; 11+ messages in thread
From: Mostafa Saleh @ 2026-05-20 20:49 UTC (permalink / raw)
To: op-tee, linux-kernel, kvmarm, linux-arm-kernel
Cc: maz, oupton, joey.gouly, suzuki.poulose, catalin.marinas,
jens.wiklander, sumit.garg, sebastianene, vdonnefort,
sudeep.holla, Mostafa Saleh
From: Sebastian Ene <sebastianene@google.com>
Use the descriptor's `ep_mem_offset` to calculate the start of the endpoint
memory access array and to comply with the FF-A spec instead of defaulting
to `sizeof(struct ffa_mem_region)`.
This requires moving `ffa_mem_region_additional_setup()` earlier in the setup
flow.
Also, add sanity checks to ensure the calculated descriptor offsets do not
exceed `max_fragsize`.
Signed-off-by: Sebastian Ene <sebastianene@google.com>
Signed-off-by: Mostafa Saleh <smostafa@google.com>
---
drivers/firmware/arm_ffa/driver.c | 16 +++++++++++-----
include/linux/arm_ffa.h | 2 +-
2 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
index b700b2e93e72..8573a7a6556e 100644
--- a/drivers/firmware/arm_ffa/driver.c
+++ b/drivers/firmware/arm_ffa/driver.c
@@ -685,19 +685,26 @@ ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize,
struct ffa_composite_mem_region *composite;
struct ffa_mem_region_addr_range *constituents;
struct ffa_mem_region_attributes *ep_mem_access;
- u32 idx, frag_len, length, buf_sz = 0, num_entries = sg_nents(args->sg);
+ u32 idx, frag_len, length, buf_sz = 0, num_entries = sg_nents(args->sg), ep_offset;
+ u32 emad_size = ffa_emad_size_get(drv_info->version);
mem_region->tag = args->tag;
mem_region->flags = args->flags;
mem_region->sender_id = drv_info->vm_id;
mem_region->attributes = ffa_memory_attributes_get(func_id);
+
+ ffa_mem_region_additional_setup(drv_info->version, mem_region);
composite_offset = ffa_mem_desc_offset(buffer, args->nattrs,
drv_info->version);
+ if (composite_offset + sizeof(*composite) > max_fragsize)
+ return -ENXIO;
for (idx = 0; idx < args->nattrs; idx++) {
- ep_mem_access = buffer +
- ffa_mem_desc_offset(buffer, idx, drv_info->version);
- memset(ep_mem_access, 0, ffa_emad_size_get(drv_info->version));
+ ep_offset = ffa_mem_desc_offset(buffer, idx, drv_info->version);
+ if (ep_offset + emad_size > max_fragsize)
+ return -ENXIO;
+ ep_mem_access = buffer + ep_offset;
+ memset(ep_mem_access, 0, emad_size);
ep_mem_access->receiver = args->attrs[idx].receiver;
ep_mem_access->attrs = args->attrs[idx].attrs;
ep_mem_access->composite_off = composite_offset;
@@ -707,7 +714,6 @@ ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize,
}
mem_region->handle = 0;
mem_region->ep_count = args->nattrs;
- ffa_mem_region_additional_setup(drv_info->version, mem_region);
composite = buffer + composite_offset;
composite->total_pg_cnt = ffa_get_num_pages_sg(args->sg);
diff --git a/include/linux/arm_ffa.h b/include/linux/arm_ffa.h
index 81e603839c4a..62d67dae8b70 100644
--- a/include/linux/arm_ffa.h
+++ b/include/linux/arm_ffa.h
@@ -445,7 +445,7 @@ ffa_mem_desc_offset(struct ffa_mem_region *buf, int count, u32 ffa_version)
if (!FFA_MEM_REGION_HAS_EP_MEM_OFFSET(ffa_version))
offset += offsetof(struct ffa_mem_region, ep_mem_offset);
else
- offset += sizeof(struct ffa_mem_region);
+ offset += buf->ep_mem_offset;
return offset;
}
--
2.54.0.669.g59709faab0-goog
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v4 4/5] KVM: arm64: Fix bounds checking in do_ffa_mem_reclaim()
2026-05-20 20:49 [PATCH v4 0/5] arm_ffa, KVM: Fix FF-A emad offset calculations Mostafa Saleh
` (2 preceding siblings ...)
2026-05-20 20:49 ` [PATCH v4 3/5] firmware: arm_ffa: Fix Endpoint Memory Access Descriptor offset calculation Mostafa Saleh
@ 2026-05-20 20:49 ` Mostafa Saleh
2026-05-21 8:28 ` Marc Zyngier
2026-05-20 20:49 ` [PATCH v4 5/5] KVM: arm64: Validate the offset to the mem access descriptor Mostafa Saleh
4 siblings, 1 reply; 11+ messages in thread
From: Mostafa Saleh @ 2026-05-20 20:49 UTC (permalink / raw)
To: op-tee, linux-kernel, kvmarm, linux-arm-kernel
Cc: maz, oupton, joey.gouly, suzuki.poulose, catalin.marinas,
jens.wiklander, sumit.garg, sebastianene, vdonnefort,
sudeep.holla, Mostafa Saleh
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.
Signed-off-by: Mostafa Saleh <smostafa@google.com>
---
arch/arm64/kvm/hyp/nvhe/ffa.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
index 1af722771178..e6aa2bfa63b1 100644
--- a/arch/arm64/kvm/hyp/nvhe/ffa.c
+++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
@@ -607,7 +607,7 @@ 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 ||
+ if (WARN_ON(offset + CONSTITUENTS_OFFSET(0) > len ||
fraglen > KVM_FFA_MBOX_NR_PAGES * PAGE_SIZE)) {
ret = FFA_RET_ABORTED;
ffa_rx_release(res);
@@ -641,6 +641,11 @@ static void do_ffa_mem_reclaim(struct arm_smccc_1_2_regs *res,
goto out_unlock;
reg = (void *)buf + offset;
+ if (WARN_ON(offset + CONSTITUENTS_OFFSET(reg->addr_range_cnt) > len)) {
+ ret = FFA_RET_ABORTED;
+ goto out_unlock;
+ }
+
/* 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.669.g59709faab0-goog
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v4 5/5] KVM: arm64: Validate the offset to the mem access descriptor
2026-05-20 20:49 [PATCH v4 0/5] arm_ffa, KVM: Fix FF-A emad offset calculations Mostafa Saleh
` (3 preceding siblings ...)
2026-05-20 20:49 ` [PATCH v4 4/5] KVM: arm64: Fix bounds checking in do_ffa_mem_reclaim() Mostafa Saleh
@ 2026-05-20 20:49 ` Mostafa Saleh
4 siblings, 0 replies; 11+ messages in thread
From: Mostafa Saleh @ 2026-05-20 20:49 UTC (permalink / raw)
To: op-tee, linux-kernel, kvmarm, linux-arm-kernel
Cc: maz, oupton, joey.gouly, suzuki.poulose, catalin.marinas,
jens.wiklander, sumit.garg, sebastianene, vdonnefort,
sudeep.holla, Mostafa Saleh
From: Sebastian Ene <sebastianene@google.com>
Prevent the pKVM hypervisor from making assumptions that the
endpoint memory access descriptor (EMAD) comes right after the
FF-A memory region header.
Prior to FF-A version 1.1 the header of the memory region
didn't contain an offset to the endpoint memory access descriptor.
The layout of a memory transaction looks like this from 1.1 onward:
Type | Field name | Offset
[ Header | ffa_mem_region | 0
EMAD 1 | ffa_mem_region_attributes) | ffa_mem_region.ep_mem_offset
]
Verify that the offset to the first endpoint memory access descriptor
is within the mailbox buffer bounds.
[@Mostafa, Add missing call to ffa_rx_release() and use fraglen
as the max buffer size as it is the only intialised part]
Signed-off-by: Sebastian Ene <sebastianene@google.com>
Signed-off-by: Mostafa Saleh <smostafa@google.com>
---
arch/arm64/kvm/hyp/nvhe/ffa.c | 23 +++++++++++++++++------
1 file changed, 17 insertions(+), 6 deletions(-)
diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
index e6aa2bfa63b1..38f35887e846 100644
--- a/arch/arm64/kvm/hyp/nvhe/ffa.c
+++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
@@ -479,7 +479,7 @@ static void __do_ffa_mem_xfer(const u64 func_id,
struct ffa_mem_region_attributes *ep_mem_access;
struct ffa_composite_mem_region *reg;
struct ffa_mem_region *buf;
- u32 offset, nr_ranges, checked_offset;
+ u32 offset, nr_ranges, checked_offset, em_mem_access_off;
int ret = 0;
if (addr_mbz || npages_mbz || fraglen > len ||
@@ -508,8 +508,13 @@ static void __do_ffa_mem_xfer(const u64 func_id,
buf = hyp_buffers.tx;
memcpy(buf, host_buffers.tx, fraglen);
- ep_mem_access = (void *)buf +
- ffa_mem_desc_offset(buf, 0, hyp_ffa_version);
+ em_mem_access_off = ffa_mem_desc_offset(buf, 0, hyp_ffa_version);
+ if (em_mem_access_off + sizeof(struct ffa_mem_region_attributes) > fraglen) {
+ ret = FFA_RET_INVALID_PARAMETERS;
+ goto out_unlock;
+ }
+
+ ep_mem_access = (void *)buf + em_mem_access_off;
offset = ep_mem_access->composite_off;
if (!offset || buf->ep_count != 1 || buf->sender_id != HOST_FFA_ID) {
ret = FFA_RET_INVALID_PARAMETERS;
@@ -576,7 +581,7 @@ static void do_ffa_mem_reclaim(struct arm_smccc_1_2_regs *res,
DECLARE_REG(u32, flags, ctxt, 3);
struct ffa_mem_region_attributes *ep_mem_access;
struct ffa_composite_mem_region *reg;
- u32 offset, len, fraglen, fragoff;
+ u32 offset, len, fraglen, fragoff, em_mem_access_off;
struct ffa_mem_region *buf;
int ret = 0;
u64 handle;
@@ -599,8 +604,14 @@ static void do_ffa_mem_reclaim(struct arm_smccc_1_2_regs *res,
len = res->a1;
fraglen = res->a2;
- ep_mem_access = (void *)buf +
- ffa_mem_desc_offset(buf, 0, hyp_ffa_version);
+ em_mem_access_off = ffa_mem_desc_offset(buf, 0, hyp_ffa_version);
+ if (em_mem_access_off + sizeof(struct ffa_mem_region_attributes) > fraglen) {
+ ret = FFA_RET_INVALID_PARAMETERS;
+ ffa_rx_release(res);
+ goto out_unlock;
+ }
+
+ ep_mem_access = (void *)buf + em_mem_access_off;
offset = ep_mem_access->composite_off;
/*
* We can trust the SPMD to get this right, but let's at least
--
2.54.0.669.g59709faab0-goog
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v4 4/5] KVM: arm64: Fix bounds checking in do_ffa_mem_reclaim()
2026-05-20 20:49 ` [PATCH v4 4/5] KVM: arm64: Fix bounds checking in do_ffa_mem_reclaim() Mostafa Saleh
@ 2026-05-21 8:28 ` Marc Zyngier
2026-05-21 10:30 ` Mostafa Saleh
0 siblings, 1 reply; 11+ messages in thread
From: Marc Zyngier @ 2026-05-21 8:28 UTC (permalink / raw)
To: Mostafa Saleh
Cc: op-tee, linux-kernel, kvmarm, linux-arm-kernel, oupton,
joey.gouly, suzuki.poulose, catalin.marinas, jens.wiklander,
sumit.garg, sebastianene, vdonnefort, sudeep.holla
On Wed, 20 May 2026 21:49:47 +0100,
Mostafa Saleh <smostafa@google.com> wrote:
>
> 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.
>
> Signed-off-by: Mostafa Saleh <smostafa@google.com>
> ---
> arch/arm64/kvm/hyp/nvhe/ffa.c | 7 ++++++-
> 1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
> index 1af722771178..e6aa2bfa63b1 100644
> --- a/arch/arm64/kvm/hyp/nvhe/ffa.c
> +++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
> @@ -607,7 +607,7 @@ 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 ||
> + if (WARN_ON(offset + CONSTITUENTS_OFFSET(0) > len ||
> fraglen > KVM_FFA_MBOX_NR_PAGES * PAGE_SIZE)) {
Do you really want to keep this a WARN_ON(), given that this results
in a panic in most pKVM configurations?
Thanks,
M.
--
Without deviation from the norm, progress is not possible.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v4 4/5] KVM: arm64: Fix bounds checking in do_ffa_mem_reclaim()
2026-05-21 8:28 ` Marc Zyngier
@ 2026-05-21 10:30 ` Mostafa Saleh
2026-05-21 10:43 ` Mostafa Saleh
0 siblings, 1 reply; 11+ messages in thread
From: Mostafa Saleh @ 2026-05-21 10:30 UTC (permalink / raw)
To: Marc Zyngier
Cc: op-tee, linux-kernel, kvmarm, linux-arm-kernel, oupton,
joey.gouly, suzuki.poulose, catalin.marinas, jens.wiklander,
sumit.garg, sebastianene, vdonnefort, sudeep.holla
Hi Marc,
On Thu, May 21, 2026 at 09:28:46AM +0100, Marc Zyngier wrote:
> On Wed, 20 May 2026 21:49:47 +0100,
> Mostafa Saleh <smostafa@google.com> wrote:
> >
> > 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.
> >
> > Signed-off-by: Mostafa Saleh <smostafa@google.com>
> > ---
> > arch/arm64/kvm/hyp/nvhe/ffa.c | 7 ++++++-
> > 1 file changed, 6 insertions(+), 1 deletion(-)
> >
> > diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
> > index 1af722771178..e6aa2bfa63b1 100644
> > --- a/arch/arm64/kvm/hyp/nvhe/ffa.c
> > +++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
> > @@ -607,7 +607,7 @@ 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 ||
> > + if (WARN_ON(offset + CONSTITUENTS_OFFSET(0) > len ||
> > fraglen > KVM_FFA_MBOX_NR_PAGES * PAGE_SIZE)) {
>
> Do you really want to keep this a WARN_ON(), given that this results
> in a panic in most pKVM configurations?
Which kind of configuration will that check fail on?
Does that mean at the moment pKVM does out-of-bound access for
the header?
Thanks,
Mostafa
>
> Thanks,
>
> M.
>
> --
> Without deviation from the norm, progress is not possible.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v4 4/5] KVM: arm64: Fix bounds checking in do_ffa_mem_reclaim()
2026-05-21 10:30 ` Mostafa Saleh
@ 2026-05-21 10:43 ` Mostafa Saleh
2026-05-21 12:12 ` Marc Zyngier
0 siblings, 1 reply; 11+ messages in thread
From: Mostafa Saleh @ 2026-05-21 10:43 UTC (permalink / raw)
To: Marc Zyngier
Cc: op-tee, linux-kernel, kvmarm, linux-arm-kernel, oupton,
joey.gouly, suzuki.poulose, catalin.marinas, jens.wiklander,
sumit.garg, sebastianene, vdonnefort, sudeep.holla
On Thu, May 21, 2026 at 11:30 AM Mostafa Saleh <smostafa@google.com> wrote:
>
> Hi Marc,
>
> On Thu, May 21, 2026 at 09:28:46AM +0100, Marc Zyngier wrote:
> > On Wed, 20 May 2026 21:49:47 +0100,
> > Mostafa Saleh <smostafa@google.com> wrote:
> > >
> > > 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.
> > >
> > > Signed-off-by: Mostafa Saleh <smostafa@google.com>
> > > ---
> > > arch/arm64/kvm/hyp/nvhe/ffa.c | 7 ++++++-
> > > 1 file changed, 6 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
> > > index 1af722771178..e6aa2bfa63b1 100644
> > > --- a/arch/arm64/kvm/hyp/nvhe/ffa.c
> > > +++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
> > > @@ -607,7 +607,7 @@ 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 ||
> > > + if (WARN_ON(offset + CONSTITUENTS_OFFSET(0) > len ||
> > > fraglen > KVM_FFA_MBOX_NR_PAGES * PAGE_SIZE)) {
> >
> > Do you really want to keep this a WARN_ON(), given that this results
> > in a panic in most pKVM configurations?
>
> Which kind of configuration will that check fail on?
> Does that mean at the moment pKVM does out-of-bound access for
> the header?
>
I might have misunderstood the point. I thought you meant the new
change would cause a panic on most configurations, or were you
suggesting just removing the WARN_ON?
I can do that, I just updated the current faulty check and left the
WARN_ON as is.
Thanks,
Mostafa
> Thanks,
> Mostafa
>
> >
> > Thanks,
> >
> > M.
> >
> > --
> > Without deviation from the norm, progress is not possible.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v4 4/5] KVM: arm64: Fix bounds checking in do_ffa_mem_reclaim()
2026-05-21 10:43 ` Mostafa Saleh
@ 2026-05-21 12:12 ` Marc Zyngier
0 siblings, 0 replies; 11+ messages in thread
From: Marc Zyngier @ 2026-05-21 12:12 UTC (permalink / raw)
To: Mostafa Saleh
Cc: op-tee, linux-kernel, kvmarm, linux-arm-kernel, oupton,
joey.gouly, suzuki.poulose, catalin.marinas, jens.wiklander,
sumit.garg, sebastianene, vdonnefort, sudeep.holla
On Thu, 21 May 2026 11:43:58 +0100,
Mostafa Saleh <smostafa@google.com> wrote:
>
> On Thu, May 21, 2026 at 11:30 AM Mostafa Saleh <smostafa@google.com> wrote:
> >
> > Hi Marc,
> >
> > On Thu, May 21, 2026 at 09:28:46AM +0100, Marc Zyngier wrote:
> > > On Wed, 20 May 2026 21:49:47 +0100,
> > > Mostafa Saleh <smostafa@google.com> wrote:
> > > >
> > > > 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.
> > > >
> > > > Signed-off-by: Mostafa Saleh <smostafa@google.com>
> > > > ---
> > > > arch/arm64/kvm/hyp/nvhe/ffa.c | 7 ++++++-
> > > > 1 file changed, 6 insertions(+), 1 deletion(-)
> > > >
> > > > diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
> > > > index 1af722771178..e6aa2bfa63b1 100644
> > > > --- a/arch/arm64/kvm/hyp/nvhe/ffa.c
> > > > +++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
> > > > @@ -607,7 +607,7 @@ 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 ||
> > > > + if (WARN_ON(offset + CONSTITUENTS_OFFSET(0) > len ||
> > > > fraglen > KVM_FFA_MBOX_NR_PAGES * PAGE_SIZE)) {
> > >
> > > Do you really want to keep this a WARN_ON(), given that this results
> > > in a panic in most pKVM configurations?
> >
> > Which kind of configuration will that check fail on?
> > Does that mean at the moment pKVM does out-of-bound access for
> > the header?
> >
> I might have misunderstood the point. I thought you meant the new
> change would cause a panic on most configurations, or were you
> suggesting just removing the WARN_ON?
Just dropping the WARN_ON(), because for most users, that means just
killing the machine (only configurations with debug will give you a
stack trace).
> I can do that, I just updated the current faulty check and left the
> WARN_ON as is.
I'd be all for that.
Thanks,
M.
--
Without deviation from the norm, progress is not possible.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v4 2/5] firmware: arm_ffa: Fix out-of-bound writes in ffa_setup_and_transmit()
2026-05-20 20:49 ` [PATCH v4 2/5] firmware: arm_ffa: Fix out-of-bound writes in ffa_setup_and_transmit() Mostafa Saleh
@ 2026-05-21 12:51 ` Sudeep Holla
0 siblings, 0 replies; 11+ messages in thread
From: Sudeep Holla @ 2026-05-21 12:51 UTC (permalink / raw)
To: Mostafa Saleh
Cc: op-tee, linux-kernel, Sudeep Holla, kvmarm, linux-arm-kernel, maz,
oupton, joey.gouly, suzuki.poulose, catalin.marinas,
jens.wiklander, sumit.garg, sebastianene, vdonnefort
On Wed, May 20, 2026 at 08:49:45PM +0000, Mostafa Saleh wrote:
> Sashiko (locally) reports multiple out-of-bound issues in
> ffa_setup_and_transmit:
> 1) Writing ep_mem_access->reserved can write out of bounds for FFA
> versions < 1.2 as ffa_emad_size_get() returns 16 bytes in that case
> while reserved has an offset of 24.
> Instead of zeroing fields, memset the struct to zero first based on
> the FFA version.
>
Neat, I clearly missed taking this approach when I added zero-ing of
member initially.
> 2) Make sure there is enough size to write constituents.
>
> While at it, convert the only sizeof() in the driver that uses a
> type instead of variable.
>
Reviewed-by: Sudeep Holla <sudeep.holla@kernel.org>
--
Regards,
Sudeep
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2026-05-21 12:51 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-20 20:49 [PATCH v4 0/5] arm_ffa, KVM: Fix FF-A emad offset calculations Mostafa Saleh
2026-05-20 20:49 ` [PATCH v4 1/5] optee: ffa: Add NULL check in optee_ffa_lend_protmem Mostafa Saleh
2026-05-20 20:49 ` [PATCH v4 2/5] firmware: arm_ffa: Fix out-of-bound writes in ffa_setup_and_transmit() Mostafa Saleh
2026-05-21 12:51 ` Sudeep Holla
2026-05-20 20:49 ` [PATCH v4 3/5] firmware: arm_ffa: Fix Endpoint Memory Access Descriptor offset calculation Mostafa Saleh
2026-05-20 20:49 ` [PATCH v4 4/5] KVM: arm64: Fix bounds checking in do_ffa_mem_reclaim() Mostafa Saleh
2026-05-21 8:28 ` Marc Zyngier
2026-05-21 10:30 ` Mostafa Saleh
2026-05-21 10:43 ` Mostafa Saleh
2026-05-21 12:12 ` Marc Zyngier
2026-05-20 20:49 ` [PATCH v4 5/5] KVM: arm64: Validate the offset to the mem access descriptor Mostafa Saleh
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox