summaryrefslogtreecommitdiff
path: root/opt/xen-tools/xsa477.patch
diff options
context:
space:
mode:
Diffstat (limited to 'opt/xen-tools/xsa477.patch')
-rw-r--r--opt/xen-tools/xsa477.patch105
1 files changed, 105 insertions, 0 deletions
diff --git a/opt/xen-tools/xsa477.patch b/opt/xen-tools/xsa477.patch
new file mode 100644
index 0000000..48a9484
--- /dev/null
+++ b/opt/xen-tools/xsa477.patch
@@ -0,0 +1,105 @@
+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
+ */