* [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.