Xen Security Advisory 426 v1 (CVE-2022-27672) - x86: Cross-Thread Return Address Predictions

Xen.org security team posted 1 patch 1 year, 2 months ago
Test gitlab-ci failed
Patches applied successfully (tree, apply log)
git fetch https://gitlab.com/xen-project/patchew/xen tags/patchew/E1pRze8-0007sq-Ni@xenbits.xenproject.org
Xen Security Advisory 426 v1 (CVE-2022-27672) - x86: Cross-Thread Return Address Predictions
Posted by Xen.org security team 1 year, 2 months ago
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

            Xen Security Advisory CVE-2022-27672 / XSA-426

             x86: Cross-Thread Return Address Predictions

ISSUE DESCRIPTION
=================

It has been discovered that on some AMD CPUs, the RAS (Return Address
Stack, also called RAP - Return Address Predictor - in some AMD
documentation, and RSB - Return Stack Buffer - in Intel terminology) is
dynamically partitioned between non-idle threads.  This allows an
attacker to control speculative execution on the adjacent thread.

For more details, see:
  https://www.amd.com/en/corporate/product-security/bulletin/amd-sb-1045

IMPACT
======

An attacker might be able to infer the contents of arbitrary host
memory, including memory assigned to other guests.

VULNERABLE SYSTEMS
==================

Only AMD CPUs are known to be potentially vulnerable.  CPUs from other
hardware vendors are not believed to be impacted.

Only the Zen1 and Zen2 microarchitectures are believed to be potentially
vulnerable.  Other microarchitectures are not believed to be vulnerable.

Only configurations with SMT activate are potentially vulnerable.  If
SMT is disabled by the firmware, or at runtime with `smt=0` on Xen's
command line, then the platform is not vulnerable.

Xen 4.17 and later contains an optimisation, specifically:

  c/s afab477fba3b ("x86/spec-ctrl: Skip RSB overwriting when safe to do so")

which in combination with disabling 32bit PV guests (either at compile
time with CONFIG_PV32=n, or at runtime with `pv=no-32` on the command
line) renders Xen vulnerable to attack from PV guests.

Note: multiple downstreams are known to have backported this
optimisation to older versions of Xen.  Consult your software vendor
documentation.

MITIGATION
==========

On otherwise-vulnerable configurations, the issue can be mitigated by
booting Xen with `spec-ctrl=rsb`, which will override the aforementioned
optimisation.

Alternatively, SMT can be disabled either in the firmware, or by booting
Xen with `smt=0`.

Alternatively, if 32bit PV guests are only runtime disabled in Xen, this
issue can also be mitigated by booting Xen with `pv=32` to enable
support 32bit PV guests.  It is not necessary for a 32bit PV guest to
actually be running in order to mitigate the issue.

RESOLUTION
==========

Applying the attached patch resolves this issue.

Note that patches for released versions are generally prepared to
apply to the stable branches, and may not apply cleanly to the most
recent release tarball.  Downstreams are encouraged to update to the
tip of the stable branch before applying these patches.

xsa426.patch          xen-unstable - Xen 4.17

$ sha256sum xsa426*
425b1d8931e02852afec9fe3d9f1d009f6d8a33c6387b2e8b3896f374732d470  xsa426.patch
$
-----BEGIN PGP SIGNATURE-----

iQFABAEBCAAqFiEEI+MiLBRfRHX6gGCng/4UyVfoK9kFAmPrzJoMHHBncEB4ZW4u
b3JnAAoJEIP+FMlX6CvZiqsIALrisP3l7ImoKe49Bmb1blNYmUv6UjYGdVF9acc9
++QYPLq4Mu+kJuIlgKnT21hj7BFczL4KSi8sVw/nLqU3x8R/ZJ6nxXLlCod6RqGw
4MYd6QmArx8a+hm3LC0288VEFVXFh0WTDA6PK15RkspiwcjsAZ4w7DA7cRk0FLP0
9KJMhSPOAj9wCDhvOckr7DnA+D6gOKjMH83NCL0rg6Xe8+Bv0qTVYe49FqAnbWwc
9RsYOKfRuZUci+Z+mALVRB97R7xvns5D9HnDvs55ADri506JWkxmdp1GvLtjezXV
3Zds6TOrr1i0RQGV9M6aouinrI+DQNrOFR8V6p98KYxAo+Y=
=T8Uh
-----END PGP SIGNATURE-----
From: Andrew Cooper <andrew.cooper3@citrix.com>
Subject: x86/spec-ctrl: Mitigate Cross-Thread Return Address Predictions

This is XSA-426 / CVE-2022-27672

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>

diff --git a/docs/misc/xen-command-line.pandoc b/docs/misc/xen-command-line.pandoc
index 923910f553c5..a2ff38cdebf2 100644
--- a/docs/misc/xen-command-line.pandoc
+++ b/docs/misc/xen-command-line.pandoc
@@ -2355,7 +2355,7 @@ guests to use.
   on entry and exit.  These blocks are necessary to virtualise support for
   guests and if disabled, guests will be unable to use IBRS/STIBP/SSBD/etc.
 * `rsb=` offers control over whether to overwrite the Return Stack Buffer /
-  Return Address Stack on entry to Xen.
+  Return Address Stack on entry to Xen and on idle.
 * `md-clear=` offers control over whether to use VERW to flush
   microarchitectural buffers on idle and exit from Xen.  *Note: For
   compatibility with development versions of this fix, `mds=` is also accepted
diff --git a/xen/arch/x86/include/asm/cpufeatures.h b/xen/arch/x86/include/asm/cpufeatures.h
index 865f1109866d..da0593de8542 100644
--- a/xen/arch/x86/include/asm/cpufeatures.h
+++ b/xen/arch/x86/include/asm/cpufeatures.h
@@ -35,7 +35,8 @@ XEN_CPUFEATURE(SC_RSB_HVM,        X86_SYNTH(19)) /* RSB overwrite needed for HVM
 XEN_CPUFEATURE(XEN_SELFSNOOP,     X86_SYNTH(20)) /* SELFSNOOP gets used by Xen itself */
 XEN_CPUFEATURE(SC_MSR_IDLE,       X86_SYNTH(21)) /* Clear MSR_SPEC_CTRL on idle */
 XEN_CPUFEATURE(XEN_LBR,           X86_SYNTH(22)) /* Xen uses MSR_DEBUGCTL.LBR */
-/* Bits 23,24 unused. */
+/* Bits 23 unused. */
+XEN_CPUFEATURE(SC_RSB_IDLE,       X86_SYNTH(24)) /* RSB overwrite needed for idle. */
 XEN_CPUFEATURE(SC_VERW_IDLE,      X86_SYNTH(25)) /* VERW used by Xen for idle */
 XEN_CPUFEATURE(XEN_SHSTK,         X86_SYNTH(26)) /* Xen uses CET Shadow Stacks */
 XEN_CPUFEATURE(XEN_IBT,           X86_SYNTH(27)) /* Xen uses CET Indirect Branch Tracking */
diff --git a/xen/arch/x86/include/asm/spec_ctrl.h b/xen/arch/x86/include/asm/spec_ctrl.h
index 6a77c3937844..391973ef6a28 100644
--- a/xen/arch/x86/include/asm/spec_ctrl.h
+++ b/xen/arch/x86/include/asm/spec_ctrl.h
@@ -159,6 +159,21 @@ static always_inline void spec_ctrl_enter_idle(struct cpu_info *info)
      */
     alternative_input("", "verw %[sel]", X86_FEATURE_SC_VERW_IDLE,
                       [sel] "m" (info->verw_sel));
+
+    /*
+     * Cross-Thread Return Address Predictions:
+     *
+     * On vulnerable systems, the return predictions (RSB/RAS) are statically
+     * partitioned between active threads.  When entering idle, our entries
+     * are re-partitioned to allow the other threads to use them.
+     *
+     * In some cases, we might still have guest entries in the RAS, so flush
+     * them before injecting them sideways to our sibling thread.
+     *
+     * (ab)use alternative_input() to specify clobbers.
+     */
+    alternative_input("", "DO_OVERWRITE_RSB", X86_FEATURE_SC_RSB_IDLE,
+                      : "rax", "rcx");
 }
 
 /* WARNING! `ret`, `call *`, `jmp *` not safe before this call. */
diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c
index a320b81947c8..e80e2a5ed1a9 100644
--- a/xen/arch/x86/spec_ctrl.c
+++ b/xen/arch/x86/spec_ctrl.c
@@ -1327,13 +1327,38 @@ void __init init_speculation_mitigations(void)
      * 3) Some CPUs have RSBs which are not full width, which allow the
      *    attacker's entries to alias Xen addresses.
      *
+     * 4) Some CPUs have RSBs which are re-partitioned based on thread
+     *    idleness, which allows an attacker to inject entries into the other
+     *    thread.  We still active the optimisation in this case, and mitigate
+     *    in the idle path which has lower overhead.
+     *
      * It is safe to turn off RSB stuffing when Xen is using SMEP itself, and
      * 32bit PV guests are disabled, and when the RSB is full width.
      */
     BUILD_BUG_ON(RO_MPT_VIRT_START != PML4_ADDR(256));
-    if ( opt_rsb_pv == -1 && boot_cpu_has(X86_FEATURE_XEN_SMEP) &&
-         !opt_pv32 && rsb_is_full_width() )
-        opt_rsb_pv = 0;
+    if ( opt_rsb_pv == -1 )
+    {
+        opt_rsb_pv = (opt_pv32 || !boot_cpu_has(X86_FEATURE_XEN_SMEP) ||
+                      !rsb_is_full_width());
+
+        /*
+         * Cross-Thread Return Address Predictions.
+         *
+         * Vulnerable systems are Zen1/Zen2 uarch, which is AMD Fam17 / Hygon
+         * Fam18, when SMT is active.
+         *
+         * To mitigate, we must flush the RSB/RAS/RAP once between entering
+         * Xen and going idle.
+         *
+         * Most cases flush on entry to Xen anyway.  The one case where we
+         * don't is when using the SMEP optimisation for PV guests.  Flushing
+         * before going idle is less overhead than flushing on PV entry.
+         */
+        if ( !opt_rsb_pv && hw_smt_enabled &&
+             (boot_cpu_data.x86_vendor & (X86_VENDOR_AMD|X86_VENDOR_HYGON)) &&
+             (boot_cpu_data.x86 == 0x17 || boot_cpu_data.x86 == 0x18) )
+            setup_force_cpu_cap(X86_FEATURE_SC_RSB_IDLE);
+    }
 
     if ( opt_rsb_pv )
     {