All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Fuad Tabba" <fuad.tabba@linux.dev>
Cc: kvmarm@lists.linux.dev, "Oliver Upton" <oupton@kernel.org>,
	"Marc Zyngier" <maz@kernel.org>
Subject: Re: [PATCH v2 11/11] KVM: arm64: Tag host-VA hypercall parameters __kern
Date: Mon, 03 Aug 2026 13:44:33 +0000	[thread overview]
Message-ID: <20260803134435.D34A41F00A3F@smtp.kernel.org> (raw)
In-Reply-To: <20260803124220.332248-12-fuad.tabba@linux.dev>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:

New issues:
- [Medium] The `kern_hyp_va_host()` macro strips the `__kern` tag using `(__force void *)` and returns a plain pointer, undermining the static analysis guarantees for both misapplied unwraps and subsequent TOCTOU bugs.

Pre-existing issues:
- [Critical] Always-on hypercalls (e.g., `__vgic_v3_save_aprs`, `__kvm_adjust_pc`) accept host VAs, translate them via `kern_hyp_va_host()`, and read/write to them without validating physical page ownership, enabling a Confused Deputy arbitrary memory corruption attack.
--

--- Patch [11]: [PATCH v2 11/11] KVM: arm64: Tag host-VA hypercall parameters __kern ---
commit 0acf480afb506d5122464f1024574511fad649b3
Author: Fuad Tabba <fuad.tabba@linux.dev>

KVM: arm64: Tag host-VA hypercall parameters __kern

The nVHE hypervisor takes host virtual addresses as hypercall arguments
and translates each with kern_hyp_va() before use. This patch adds a __kern 
sparse address space for EL2 code to tag host-VA parameters and introduces 
kern_hyp_va_host() to unwrap them.

> diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
> index 6eae7e7e2a684..57f65257bb56d 100644
> --- a/arch/arm64/include/asm/kvm_mmu.h
> +++ b/arch/arm64/include/asm/kvm_mmu.h
[ ... ]
> @@ -140,6 +142,14 @@ static __always_inline unsigned long __kern_hyp_va(unsigned long v)
>  
>  #define kern_hyp_va(v) 	((typeof(v))(__kern_hyp_va((unsigned long)(v))))
>  
> +/*
> + * Translate a __kern-tagged host VA, dropping the tag: the only sanctioned
> + * unwrap. Translation only, no ownership or bounds validation; the result
> + * carries the pointee type stripped of the tag and of any cv-qualifiers.
> + */
> +#define kern_hyp_va_host(v)						\
> +	((TYPEOF_UNQUAL(*(v)) *)__kern_hyp_va((unsigned long)(__force void *)(v)))

[Severity: Medium]
Since the __force void * cast unconditionally strips all sparse address space
information, does this suppress warnings if the macro is accidentally applied
to an untagged EL2 private-VA-range pointer?

Additionally, because the returned pointer has no address space tag, doesn't
this prevent sparse from warning if a developer directly double-fetches or acts
on the translated untrusted host memory instead of copying it first?

For example, in __pkvm_init_vm(), host_kvm is passed as a plain pointer and
loses its sparse static analysis protection despite still aliasing untrusted
memory.

[ ... ]
> diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> index 6986ce55fd9ef..f8ea1661b3166 100644
> --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
[ ... ]
> @@ -500,15 +500,15 @@ DEFINE_KVM_HOST_HCALL0_VOID(__vgic_v3_init_lrs)
>  }
>  
>  DEFINE_KVM_HOST_HCALL_VOID(__vgic_v3_save_aprs,
> -	struct vgic_v3_cpu_if *, cpu_if)
> +	struct vgic_v3_cpu_if __kern *, cpu_if)
>  {
> -	__vgic_v3_save_aprs(kern_hyp_va(cpu_if));
> +	__vgic_v3_save_aprs(kern_hyp_va_host(cpu_if));
>  }

[Severity: Critical]
This is a pre-existing issue, but by retaining the lack of bounds validation
through kern_hyp_va_host(), can the host EL1 trigger an arbitrary memory
corruption in the hypervisor?

Since kern_hyp_va_host() explicitly performs no ownership or bounds validation,
it appears the host kernel could provide a forged pointer that translates to a
physical page owned by EL2.

The hypervisor then passes this pointer directly to __vgic_v3_save_aprs()
after unvalidated translation:

arch/arm64/kvm/hyp/vgic-v3-sr.c:__vgic_v3_save_aprs() {
    ...
    cpu_if->vgic_ap0r[3] = __vgic_v3_read_ap0rn(3);
    ...
}

which directly writes to the untrusted pointer, potentially allowing the host
to corrupt EL2 private memory and bypass isolation.

[ ... ]

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260803124220.332248-1-fuad.tabba@linux.dev?part=11

  reply	other threads:[~2026-08-03 13:44 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-03 12:42 [PATCH v2 00/11] KVM: arm64: Restore type-checking across the host/hyp hypercall boundary Fuad Tabba
2026-08-03 12:42 ` [PATCH v2 01/11] tracing: Include linux/types.h in trace_remote_event.h Fuad Tabba
2026-08-03 12:42 ` [PATCH v2 02/11] KVM: arm64: nVHE: Share the stacktrace per-CPU declarations with EL2 Fuad Tabba
2026-08-03 12:42 ` [PATCH v2 03/11] KVM: arm64: nVHE: Declare the hyp event IDs before defining them Fuad Tabba
2026-08-03 12:42 ` [PATCH v2 04/11] KVM: arm64: nVHE: Use NULL to reset the trace buffer backing pointer Fuad Tabba
2026-08-03 12:42 ` [PATCH v2 05/11] KVM: arm64: nVHE: Run the source checker under C=2 Fuad Tabba
2026-08-03 12:42 ` [PATCH v2 06/11] arm64: pi: Run the source checker on the libfdt objects " Fuad Tabba
2026-08-03 12:42 ` [PATCH v2 07/11] KVM: arm64: nVHE: Pass host VA arguments as pointers Fuad Tabba
2026-08-03 12:42 ` [PATCH v2 08/11] KVM: arm64: Move the host hypercall interface to its own header Fuad Tabba
2026-08-03 12:42 ` [PATCH v2 09/11] KVM: arm64: Type-check hypercall arguments at the caller Fuad Tabba
2026-08-03 17:59   ` Marc Zyngier
2026-08-03 18:33     ` Fuad Tabba
2026-08-03 12:42 ` [PATCH v2 10/11] KVM: arm64: nVHE: Check hypercall handlers against the declared ABI Fuad Tabba
2026-08-03 18:03   ` Marc Zyngier
2026-08-03 18:34     ` Fuad Tabba
2026-08-04  8:47       ` Marc Zyngier
2026-08-04  8:50         ` Fuad Tabba
2026-08-03 12:42 ` [PATCH v2 11/11] KVM: arm64: Tag host-VA hypercall parameters __kern Fuad Tabba
2026-08-03 13:44   ` sashiko-bot [this message]
2026-08-03 13:49     ` Fuad Tabba

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260803134435.D34A41F00A3F@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=fuad.tabba@linux.dev \
    --cc=kvmarm@lists.linux.dev \
    --cc=maz@kernel.org \
    --cc=oupton@kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.