with shadow paging + tracing (XSA-477) xsa477.patch - bsc#1256747 - VUL-0: CVE-2026-23553: xen: x86: incomplete IBPB for vCPU isolation (XSA-479) xsa479.patch - Drop x86-ioapic-ack-default.patch Upstream changes make this patch unnecessary. OBS-URL: https://build.opensuse.org/package/show/Virtualization/xen?expand=0&rev=906
106 lines
3.8 KiB
Diff
106 lines
3.8 KiB
Diff
From: Jan Beulich <jbeulich@suse.com>
|
|
Subject: x86/shadow: don't overrun trace_emul_write_val
|
|
|
|
Guests can do wider-than-PTE-size writes on page tables. The tracing
|
|
helper variable, however, only offers space for a single PTE (and it is
|
|
being switched to the more correct type right here). Therefore bound
|
|
incoming write sizes to the amount of space available.
|
|
|
|
To not leave dead code (which is a Misra concern), drop the now unused
|
|
guest_pa_t as well.
|
|
|
|
Also move and adjust GUEST_PTE_SIZE: Derive it rather than using hard-
|
|
coded numbers, and put it in the sole source file where it's actually
|
|
needed. This then also addresses a Misra rule 20.9 ("All identifiers
|
|
used in the controlling expression of #if or #elif preprocessing
|
|
directives shall be #define'd before evaluation") violation:
|
|
GUEST_PAGING_LEVELS is #define'd only in multi.c.
|
|
|
|
This is XSA-477 / CVE-2025-58150.
|
|
|
|
Fixes: 9a86ac1aa3d2 ("xentrace 5/7: Additional tracing for the shadow code")
|
|
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
|
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
|
|
|
--- a/xen/arch/x86/mm/shadow/multi.c
|
|
+++ b/xen/arch/x86/mm/shadow/multi.c
|
|
@@ -1970,15 +1970,15 @@ static void sh_prefetch(struct vcpu *v,
|
|
|
|
#if GUEST_PAGING_LEVELS == 4
|
|
typedef u64 guest_va_t;
|
|
-typedef u64 guest_pa_t;
|
|
#elif GUEST_PAGING_LEVELS == 3
|
|
typedef u32 guest_va_t;
|
|
-typedef u64 guest_pa_t;
|
|
#else
|
|
typedef u32 guest_va_t;
|
|
-typedef u32 guest_pa_t;
|
|
#endif
|
|
|
|
+/* Size (in bytes) of a guest PTE */
|
|
+#define GUEST_PTE_SIZE sizeof(guest_l1e_t)
|
|
+
|
|
/* Shadow trace event with GUEST_PAGING_LEVELS folded into the event field. */
|
|
static void sh_trace(uint32_t event, unsigned int extra, const void *extra_data)
|
|
{
|
|
@@ -2048,11 +2048,14 @@ static void __maybe_unused sh_trace_gfn_
|
|
static DEFINE_PER_CPU(guest_va_t,trace_emulate_initial_va);
|
|
static DEFINE_PER_CPU(int,trace_extra_emulation_count);
|
|
#endif
|
|
-static DEFINE_PER_CPU(guest_pa_t,trace_emulate_write_val);
|
|
+static DEFINE_PER_CPU(guest_l1e_t, trace_emulate_write_val);
|
|
|
|
static void cf_check trace_emulate_write_val(
|
|
const void *ptr, unsigned long vaddr, const void *src, unsigned int bytes)
|
|
{
|
|
+ if ( bytes > sizeof(this_cpu(trace_emulate_write_val)) )
|
|
+ bytes = sizeof(this_cpu(trace_emulate_write_val));
|
|
+
|
|
#if GUEST_PAGING_LEVELS == 3
|
|
if ( vaddr == this_cpu(trace_emulate_initial_va) )
|
|
memcpy(&this_cpu(trace_emulate_write_val), src, bytes);
|
|
@@ -2077,13 +2080,16 @@ static inline void sh_trace_emulate(gues
|
|
/*
|
|
* For GUEST_PAGING_LEVELS=3 (PAE paging), guest_l1e is 64 while
|
|
* guest_va is 32. Put it first to avoid padding.
|
|
+ *
|
|
+ * Note: .write_val is an arbitrary set of written bytes, possibly
|
|
+ * misaligned and possibly spanning the next gl1e.
|
|
*/
|
|
guest_l1e_t gl1e, write_val;
|
|
guest_va_t va;
|
|
uint32_t flags:29, emulation_count:3;
|
|
} d = {
|
|
.gl1e = gl1e,
|
|
- .write_val.l1 = this_cpu(trace_emulate_write_val),
|
|
+ .write_val = this_cpu(trace_emulate_write_val),
|
|
.va = va,
|
|
#if GUEST_PAGING_LEVELS == 3
|
|
.emulation_count = this_cpu(trace_extra_emulation_count),
|
|
@@ -2672,7 +2677,7 @@ static int cf_check sh_page_fault(
|
|
paging_unlock(d);
|
|
put_gfn(d, gfn_x(gfn));
|
|
|
|
- this_cpu(trace_emulate_write_val) = 0;
|
|
+ this_cpu(trace_emulate_write_val) = (guest_l1e_t){};
|
|
|
|
#if SHADOW_OPTIMIZATIONS & SHOPT_FAST_EMULATION
|
|
early_emulation:
|
|
--- a/xen/arch/x86/mm/shadow/private.h
|
|
+++ b/xen/arch/x86/mm/shadow/private.h
|
|
@@ -120,14 +120,6 @@ enum {
|
|
TRCE_SFLAG_OOS_FIXUP_EVICT,
|
|
};
|
|
|
|
-
|
|
-/* Size (in bytes) of a guest PTE */
|
|
-#if GUEST_PAGING_LEVELS >= 3
|
|
-# define GUEST_PTE_SIZE 8
|
|
-#else
|
|
-# define GUEST_PTE_SIZE 4
|
|
-#endif
|
|
-
|
|
/******************************************************************************
|
|
* Auditing routines
|
|
*/
|