Information disclosure
Description
The commit fixes an information-disclosure vulnerability in the KVM arm64 FFA_VERSION host-call path. Previously, kvm_host_ffa_handler declared a local stack variable 'res' of type struct arm_smccc_1_2_regs without initializing it when the compiler did not automatically zero-initialize stack variables. The host call path could return residual data from the hypervisor stack to the guest via FFA_VERSION, leaking sensitive hypervisor/stack contents across the host-guest boundary. The patch changes the local 'res' declaration to zero-initialize it (struct arm_smccc_1_2_regs res = {0};), ensuring no residual data is leaked in the return data. This is a genuine security fix addressing information disclosure at the KVM/ARM64 host-guest boundary.
Proof of Concept
PoC outline (high level, lab verification only):
1) Use an ARM64 host with KVM and an ARM64 guest (e.g., via QEMU) and boot a kernel around v7.0-rc6 (pre-fix).
2) Trigger an FFA_VERSION host call from the guest that goes through the kvm_host_ffa_handler path in arch/arm64/kvm/hyp/nvhe/ffa.c.
3) Observe host-side behavior:
- In vulnerable versions, the local 'res' on the stack is not zero-initialized, so after the FFA call the return data may include residual hypervisor/stack content. This could be exposed to the guest via the FFA_VERSION return data, or captured in kernel logs if instrumentation is enabled.
- In a controlled lab, enable a kernel printk/logging path to print the contents of 'res' after the FFA call (or capture the memory region used to hold the response) to verify non-zero residual data.
4) Apply the patch from this commit (struct arm_smccc_1_2_regs res = {0};) and re-run the same guest call.
5) Re-check the host-call return data; with the patch, the previously observed residual data should be zeroed, demonstrating the vulnerability fix.
Notes:
- This PoC is non-trivial to automate end-to-end due to the need for kernel instrumentation or debug-printing around the kvm_host_ffa_handler. The core verification is observing whether the 'res' structure contains non-zero (residual) data on entry/exit of the FFA_VERSION path in pre-fix kernels vs post-fix kernels. If you enable a one-off debug print of the memory backing the 'res' structure in kvm_host_ffa_handler, you can compare the output with and without the patch to observe the leakage before the fix and the zeroed data after the fix.
Commit Details
Author: Sebastian Ene
Date: 2026-07-02 10:38 UTC
Message:
KVM: arm64: Zero out the stack initialized data in the FFA handler
Don't leak hypervisor stack data when using the FFA_VERSION call.
When the compiler doesn't support -ftrivial-auto-var-init=zero option
we need to zero out the stack initialized variable before returning data
to the host caller.
Closes:
https://lore.kernel.org/all/20260616160016.C62C81F000E9@smtp.kernel.org/
Reported-by: Sashiko AI <sashiko-bot@kernel.org>
Fixes: c9c012625e12 ("KVM: arm64: Trap FFA_VERSION host call in pKVM")
Reviewed-by: Vincent Donnefort <vdonnefort@google.com>
Link: https://lore.kernel.org/all/20260616160016.C62C81F000E9@smtp.kernel.org/
Signed-off-by: Sebastian Ene <sebastianene@google.com>
Link: https://patch.msgid.link/20260702103848.1647249-7-sebastianene@google.com
Signed-off-by: Marc Zyngier <maz@kernel.org>
Triage Assessment
Vulnerability Type: Information disclosure
Confidence: HIGH
Reasoning:
The change zeroes out a stack-initialized local (structure res) to prevent leaking residual hypervisor stack data to the host caller via FFA_VERSION when the compiler lacks a zero-initialization flag. This addresses information disclosure from the host–guest boundary in KVM on arm64.
Verification Assessment
Vulnerability Type: Information disclosure
Confidence: HIGH
Affected Versions: v7.0-rc6 and earlier (arm64 KVM FFA_VERSION path)
Code Diff
diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
index 9c96e72e522e54..a327c2bbb6b64d 100644
--- a/arch/arm64/kvm/hyp/nvhe/ffa.c
+++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
@@ -880,7 +880,7 @@ static void do_ffa_part_get(struct arm_smccc_1_2_regs *res,
bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
{
- struct arm_smccc_1_2_regs res;
+ struct arm_smccc_1_2_regs res = {0};
/*
* There's no way we can tell what a non-standard SMC call might