* [PATCH v2 0/2] KVM: arm64: KVM: arm64: Fix potential leak in hyp_trace_buffer_alloc_bpages_backing
@ 2026-07-10 11:48 Vincent Donnefort
2026-07-10 11:48 ` [PATCH v2 1/2] " Vincent Donnefort
2026-07-10 11:48 ` [PATCH v2 2/2] KVM: arm64: Fix hyp_trace_desc allocation size in hyp_trace_load() Vincent Donnefort
0 siblings, 2 replies; 6+ messages in thread
From: Vincent Donnefort @ 2026-07-10 11:48 UTC (permalink / raw)
To: maz, oupton, kvmarm, linux-arm-kernel
Cc: joey.gouly, seiden, suzuki.poulose, yuzenghui, catalin.marinas,
will, kernel-team, tabba, Vincent Donnefort
This series provides two fixes for the nVHE/pKVM hyp trace remote buffer
allocation.
Changelog:
v2:
- Added patch: "KVM: arm64: Fix hyp_trace_desc allocation size in
hyp_trace_load()"
- Collected Reviewed-by and Tested-by tags from Fuad Tabba for the
leak fix
- Do not set bpages_backing_* on __map_hyp() failure (Fuad)
v1: https://lore.kernel.org/all/20260707165029.3410701-1-vdonnefort@google.com/
Vincent Donnefort (2):
KVM: arm64: Fix potential leak in
hyp_trace_buffer_alloc_bpages_backing
KVM: arm64: Fix hyp_trace_desc allocation size in hyp_trace_load()
arch/arm64/kvm/hyp_trace.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
base-commit: 8cdeaa50eae8dad34885515f62559ee83e7e8dda
--
2.55.0.795.g602f6c329a-goog
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 1/2] KVM: arm64: Fix potential leak in hyp_trace_buffer_alloc_bpages_backing
2026-07-10 11:48 [PATCH v2 0/2] KVM: arm64: KVM: arm64: Fix potential leak in hyp_trace_buffer_alloc_bpages_backing Vincent Donnefort
@ 2026-07-10 11:48 ` Vincent Donnefort
2026-07-10 11:48 ` [PATCH v2 2/2] KVM: arm64: Fix hyp_trace_desc allocation size in hyp_trace_load() Vincent Donnefort
1 sibling, 0 replies; 6+ messages in thread
From: Vincent Donnefort @ 2026-07-10 11:48 UTC (permalink / raw)
To: maz, oupton, kvmarm, linux-arm-kernel
Cc: joey.gouly, seiden, suzuki.poulose, yuzenghui, catalin.marinas,
will, kernel-team, tabba, Vincent Donnefort, Sashiko, Fuad Tabba
In the very unlikely event of a failure in __map_hyp, the allocated
backing pages are leaked in hyp_trace_buffer_alloc_bpages_backing(). Fix
this by freeing the pages on error.
Fixes: 3aed038aac8d ("KVM: arm64: Add trace remote for the nVHE/pKVM hyp")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Reviewed-by: Fuad Tabba <fuad.tabba@linux.dev>
Tested-by: Fuad Tabba <fuad.tabba@linux.dev>
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
diff --git a/arch/arm64/kvm/hyp_trace.c b/arch/arm64/kvm/hyp_trace.c
index 2411b4c32932..a7237aca6898 100644
--- a/arch/arm64/kvm/hyp_trace.c
+++ b/arch/arm64/kvm/hyp_trace.c
@@ -160,6 +160,7 @@ static int hyp_trace_buffer_alloc_bpages_backing(struct hyp_trace_buffer *trace_
int nr_bpages = (PAGE_ALIGN(size) / PAGE_SIZE) + 1;
size_t backing_size;
void *start;
+ int ret;
backing_size = PAGE_ALIGN(sizeof(struct simple_buffer_page) * nr_bpages *
num_possible_cpus());
@@ -168,10 +169,16 @@ static int hyp_trace_buffer_alloc_bpages_backing(struct hyp_trace_buffer *trace_
if (!start)
return -ENOMEM;
+ ret = __map_hyp(start, backing_size);
+ if (ret) {
+ free_pages_exact(start, backing_size);
+ return ret;
+ }
+
trace_buffer->desc->bpages_backing_start = (unsigned long)start;
trace_buffer->desc->bpages_backing_size = backing_size;
- return __map_hyp(start, backing_size);
+ return ret;
}
static void hyp_trace_buffer_free_bpages_backing(struct hyp_trace_buffer *trace_buffer)
--
2.55.0.795.g602f6c329a-goog
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v2 2/2] KVM: arm64: Fix hyp_trace_desc allocation size in hyp_trace_load()
2026-07-10 11:48 [PATCH v2 0/2] KVM: arm64: KVM: arm64: Fix potential leak in hyp_trace_buffer_alloc_bpages_backing Vincent Donnefort
2026-07-10 11:48 ` [PATCH v2 1/2] " Vincent Donnefort
@ 2026-07-10 11:48 ` Vincent Donnefort
2026-07-10 12:02 ` sashiko-bot
2026-07-12 15:56 ` Fuad Tabba
1 sibling, 2 replies; 6+ messages in thread
From: Vincent Donnefort @ 2026-07-10 11:48 UTC (permalink / raw)
To: maz, oupton, kvmarm, linux-arm-kernel
Cc: joey.gouly, seiden, suzuki.poulose, yuzenghui, catalin.marinas,
will, kernel-team, tabba, Vincent Donnefort, Sashiko
The footprint calculated for struct hyp_trace_desc sizes only
trace_buffer_desc and do not take into account the other fields. It
worked so far thanks to the follow-up PAGE_ALIGN().
Fix the descriptor size and while at it, enforce an overflow check after
PAGE_ALIGN().
Reported-by: Sashiko <sashiko-bot@kernel.org>
Fixes: 3aed038aac8d ("KVM: arm64: Add trace remote for the nVHE/pKVM hyp")
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
diff --git a/arch/arm64/kvm/hyp_trace.c b/arch/arm64/kvm/hyp_trace.c
index a7237aca6898..22437c5e1e7b 100644
--- a/arch/arm64/kvm/hyp_trace.c
+++ b/arch/arm64/kvm/hyp_trace.c
@@ -235,18 +235,22 @@ static int hyp_trace_buffer_share_hyp(struct hyp_trace_buffer *trace_buffer)
static struct trace_buffer_desc *hyp_trace_load(unsigned long size, void *priv)
{
struct hyp_trace_buffer *trace_buffer = priv;
+ size_t desc_size, tb_desc_size;
struct hyp_trace_desc *desc;
- size_t desc_size;
int ret;
if (WARN_ON(trace_buffer->desc))
return ERR_PTR(-EINVAL);
- desc_size = trace_buffer_desc_size(size, num_possible_cpus());
+ tb_desc_size = trace_buffer_desc_size(size, num_possible_cpus());
+ desc_size = size_add(tb_desc_size, offsetof(struct hyp_trace_desc, trace_buffer_desc));
if (desc_size == SIZE_MAX)
return ERR_PTR(-E2BIG);
desc_size = PAGE_ALIGN(desc_size);
+ if (!desc_size)
+ return ERR_PTR(-E2BIG);
+
desc = (struct hyp_trace_desc *)alloc_pages_exact(desc_size, GFP_KERNEL);
if (!desc)
return ERR_PTR(-ENOMEM);
@@ -262,7 +266,7 @@ static struct trace_buffer_desc *hyp_trace_load(unsigned long size, void *priv)
if (ret)
goto err_free_desc;
- ret = trace_remote_alloc_buffer(&desc->trace_buffer_desc, desc_size, size,
+ ret = trace_remote_alloc_buffer(&desc->trace_buffer_desc, tb_desc_size, size,
cpu_possible_mask);
if (ret)
goto err_free_backing;
--
2.55.0.795.g602f6c329a-goog
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v2 2/2] KVM: arm64: Fix hyp_trace_desc allocation size in hyp_trace_load()
2026-07-10 11:48 ` [PATCH v2 2/2] KVM: arm64: Fix hyp_trace_desc allocation size in hyp_trace_load() Vincent Donnefort
@ 2026-07-10 12:02 ` sashiko-bot
2026-07-10 13:19 ` Vincent Donnefort
2026-07-12 15:56 ` Fuad Tabba
1 sibling, 1 reply; 6+ messages in thread
From: sashiko-bot @ 2026-07-10 12:02 UTC (permalink / raw)
To: Vincent Donnefort; +Cc: kvmarm, Oliver Upton, Marc Zyngier
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [Critical] Incorrect bounds calculation due to pointer arithmetic on struct pointers leads to bounds check bypass and critical TOCTOU vulnerability.
--
--- Patch [2]: [PATCH v2 2/2] KVM: arm64: Fix hyp_trace_desc allocation size in hyp_trace_load() ---
commit 6dde5b05614b22025af630cb338d61676ac3c7d8
Author: Vincent Donnefort <vdonnefort@google.com>
KVM: arm64: Fix hyp_trace_desc allocation size in hyp_trace_load()
The footprint calculated for struct hyp_trace_desc sizes only
trace_buffer_desc and do not take into account the other fields. It
worked so far thanks to the follow-up PAGE_ALIGN().
> diff --git a/arch/arm64/kvm/hyp_trace.c b/arch/arm64/kvm/hyp_trace.c
> index a7237aca68989..22437c5e1e7bc 100644
> --- a/arch/arm64/kvm/hyp_trace.c
> +++ b/arch/arm64/kvm/hyp_trace.c
[ ... ]
> @@ -262,7 +266,7 @@ static struct trace_buffer_desc *hyp_trace_load(unsigned long size, void *priv)
> if (ret)
> goto err_free_desc;
>
> - ret = trace_remote_alloc_buffer(&desc->trace_buffer_desc, desc_size, size,
> + ret = trace_remote_alloc_buffer(&desc->trace_buffer_desc, tb_desc_size, size,
> cpu_possible_mask);
[Severity: Critical]
This is a pre-existing issue, but does the bounds check in
trace_remote_alloc_buffer() calculate desc_end correctly?
In kernel/trace/trace_remote.c:trace_remote_alloc_buffer(), desc_end is
calculated as:
void *desc_end = desc + desc_size;
Since desc is a typed pointer (struct trace_buffer_desc *), this pointer
arithmetic scales desc_size by sizeof(struct trace_buffer_desc), inflating
the bounds check and bypassing the intended protection.
A similar issue appears to exist in arch/arm64/kvm/hyp/nvhe/trace.c inside
hyp_trace_desc_is_valid(), where pointer arithmetic scales desc_size by
sizeof(struct hyp_trace_desc). This could potentially allow EL2 to read
un-donated host memory, opening a TOCTOU vulnerability if the host modifies
bounds after the validation check.
Should these pointers be cast to a byte-sized type like (void *) or (u8 *)
before adding the size?
> if (ret)
> goto err_free_backing;
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260710114819.2689386-1-vdonnefort@google.com?part=2
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 2/2] KVM: arm64: Fix hyp_trace_desc allocation size in hyp_trace_load()
2026-07-10 12:02 ` sashiko-bot
@ 2026-07-10 13:19 ` Vincent Donnefort
0 siblings, 0 replies; 6+ messages in thread
From: Vincent Donnefort @ 2026-07-10 13:19 UTC (permalink / raw)
To: sashiko-reviews; +Cc: kvmarm, Oliver Upton, Marc Zyngier
On Fri, Jul 10, 2026 at 12:02:54PM +0000, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
>
> Pre-existing issues:
> - [Critical] Incorrect bounds calculation due to pointer arithmetic on struct pointers leads to bounds check bypass and critical TOCTOU vulnerability.
> --
>
> --- Patch [2]: [PATCH v2 2/2] KVM: arm64: Fix hyp_trace_desc allocation size in hyp_trace_load() ---
> commit 6dde5b05614b22025af630cb338d61676ac3c7d8
> Author: Vincent Donnefort <vdonnefort@google.com>
>
> KVM: arm64: Fix hyp_trace_desc allocation size in hyp_trace_load()
>
> The footprint calculated for struct hyp_trace_desc sizes only
> trace_buffer_desc and do not take into account the other fields. It
> worked so far thanks to the follow-up PAGE_ALIGN().
>
> > diff --git a/arch/arm64/kvm/hyp_trace.c b/arch/arm64/kvm/hyp_trace.c
> > index a7237aca68989..22437c5e1e7bc 100644
> > --- a/arch/arm64/kvm/hyp_trace.c
> > +++ b/arch/arm64/kvm/hyp_trace.c
> [ ... ]
> > @@ -262,7 +266,7 @@ static struct trace_buffer_desc *hyp_trace_load(unsigned long size, void *priv)
> > if (ret)
> > goto err_free_desc;
> >
> > - ret = trace_remote_alloc_buffer(&desc->trace_buffer_desc, desc_size, size,
> > + ret = trace_remote_alloc_buffer(&desc->trace_buffer_desc, tb_desc_size, size,
> > cpu_possible_mask);
>
> [Severity: Critical]
> This is a pre-existing issue, but does the bounds check in
> trace_remote_alloc_buffer() calculate desc_end correctly?
>
> In kernel/trace/trace_remote.c:trace_remote_alloc_buffer(), desc_end is
> calculated as:
>
> void *desc_end = desc + desc_size;
>
> Since desc is a typed pointer (struct trace_buffer_desc *), this pointer
> arithmetic scales desc_size by sizeof(struct trace_buffer_desc), inflating
> the bounds check and bypassing the intended protection.
This is already part of this fix: https://lore.kernel.org/all/20260709160017.1729517-3-vdonnefort@google.com/
>
> A similar issue appears to exist in arch/arm64/kvm/hyp/nvhe/trace.c inside
> hyp_trace_desc_is_valid(), where pointer arithmetic scales desc_size by
> sizeof(struct hyp_trace_desc). This could potentially allow EL2 to read
> un-donated host memory, opening a TOCTOU vulnerability if the host modifies
> bounds after the validation check.
I don't see any issue in hyp_trace_desc_is_valid() though.
>
> Should these pointers be cast to a byte-sized type like (void *) or (u8 *)
> before adding the size?
>
> > if (ret)
> > goto err_free_backing;
>
> --
> Sashiko AI review · https://sashiko.dev/#/patchset/20260710114819.2689386-1-vdonnefort@google.com?part=2
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 2/2] KVM: arm64: Fix hyp_trace_desc allocation size in hyp_trace_load()
2026-07-10 11:48 ` [PATCH v2 2/2] KVM: arm64: Fix hyp_trace_desc allocation size in hyp_trace_load() Vincent Donnefort
2026-07-10 12:02 ` sashiko-bot
@ 2026-07-12 15:56 ` Fuad Tabba
1 sibling, 0 replies; 6+ messages in thread
From: Fuad Tabba @ 2026-07-12 15:56 UTC (permalink / raw)
To: Vincent Donnefort
Cc: maz, oupton, kvmarm, linux-arm-kernel, joey.gouly, seiden,
suzuki.poulose, yuzenghui, catalin.marinas, will, kernel-team,
Sashiko
On Fri, 10 Jul 2026 at 12:48, Vincent Donnefort <vdonnefort@google.com> wrote:
>
> The footprint calculated for struct hyp_trace_desc sizes only
> trace_buffer_desc and do not take into account the other fields. It
> worked so far thanks to the follow-up PAGE_ALIGN().
>
> Fix the descriptor size and while at it, enforce an overflow check after
> PAGE_ALIGN().
>
> Reported-by: Sashiko <sashiko-bot@kernel.org>
> Fixes: 3aed038aac8d ("KVM: arm64: Add trace remote for the nVHE/pKVM hyp")
> Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
Applied both patches on v7.2-rc2 and confirmed
arch/arm64/kvm/hyp_trace.c compiles (CONFIG_NVHE_EL2_TRACING=y).
Booted protected and non-protected VMs. To exercise hyp_trace_load()
directly I enabled the hypervisor trace remote via tracefs
(remotes/hypervisor/tracing_on) at the default 7KiB and reloaded at
512KiB, so the reworked desc_size/tb_desc_size split and the
alloc/map/share/__tracing_load path all ran fine.
Reviewed-by: Fuad Tabba <fuad.tabba@linux.dev>
Tested-by: Fuad Tabba < fuad.tabba@linux.dev>
Cheers,
/fuad
>
> diff --git a/arch/arm64/kvm/hyp_trace.c b/arch/arm64/kvm/hyp_trace.c
> index a7237aca6898..22437c5e1e7b 100644
> --- a/arch/arm64/kvm/hyp_trace.c
> +++ b/arch/arm64/kvm/hyp_trace.c
> @@ -235,18 +235,22 @@ static int hyp_trace_buffer_share_hyp(struct hyp_trace_buffer *trace_buffer)
> static struct trace_buffer_desc *hyp_trace_load(unsigned long size, void *priv)
> {
> struct hyp_trace_buffer *trace_buffer = priv;
> + size_t desc_size, tb_desc_size;
> struct hyp_trace_desc *desc;
> - size_t desc_size;
> int ret;
>
> if (WARN_ON(trace_buffer->desc))
> return ERR_PTR(-EINVAL);
>
> - desc_size = trace_buffer_desc_size(size, num_possible_cpus());
> + tb_desc_size = trace_buffer_desc_size(size, num_possible_cpus());
> + desc_size = size_add(tb_desc_size, offsetof(struct hyp_trace_desc, trace_buffer_desc));
> if (desc_size == SIZE_MAX)
> return ERR_PTR(-E2BIG);
>
> desc_size = PAGE_ALIGN(desc_size);
> + if (!desc_size)
> + return ERR_PTR(-E2BIG);
> +
> desc = (struct hyp_trace_desc *)alloc_pages_exact(desc_size, GFP_KERNEL);
> if (!desc)
> return ERR_PTR(-ENOMEM);
> @@ -262,7 +266,7 @@ static struct trace_buffer_desc *hyp_trace_load(unsigned long size, void *priv)
> if (ret)
> goto err_free_desc;
>
> - ret = trace_remote_alloc_buffer(&desc->trace_buffer_desc, desc_size, size,
> + ret = trace_remote_alloc_buffer(&desc->trace_buffer_desc, tb_desc_size, size,
> cpu_possible_mask);
> if (ret)
> goto err_free_backing;
> --
> 2.55.0.795.g602f6c329a-goog
>
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-07-12 15:57 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-10 11:48 [PATCH v2 0/2] KVM: arm64: KVM: arm64: Fix potential leak in hyp_trace_buffer_alloc_bpages_backing Vincent Donnefort
2026-07-10 11:48 ` [PATCH v2 1/2] " Vincent Donnefort
2026-07-10 11:48 ` [PATCH v2 2/2] KVM: arm64: Fix hyp_trace_desc allocation size in hyp_trace_load() Vincent Donnefort
2026-07-10 12:02 ` sashiko-bot
2026-07-10 13:19 ` Vincent Donnefort
2026-07-12 15:56 ` Fuad Tabba
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.