]>
x86/emul: Fix extable registration in invoke_stub() master staging
authorAndrew Cooper <andrew.cooper3@citrix.com>
Thu, 15 May 2025 18:01:33 +0000 (19:01 +0100)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Tue, 1 Jul 2025 11:56:59 +0000 (12:56 +0100)
For exception recovery in the stubs, the registered address for fixup is the
return address of the CALL entering the stub.

In invoke_stub(), the '.Lret%=:' label is the wrong side of the 'post'
parameter.  The 'post' parameter is non-empty in cases where the arithmetic
flags of the operation need recovering.

Split the line to separate 'pre' and 'post', making it more obvious that the
return address label was in the wrong position.

However, in the case that an exception did occur, we want to skip 'post' as
it's logically part of the operation which had already failed.  Therefore, add
a new skip label and use that for the exception recovery path.

This is XSA-470 / CVE-2025-27465

Fixes: 79903e50dba9 ("x86emul: catch exceptions occurring in stubs")
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
xen/arch/x86/x86_emulate/private.h

index f6130c7cf5261b0a28202a9fd77640640ad3e503..940087987011f98c1634f581e19af616d7f6337f 100644 (file)
@@ -716,12 +716,15 @@ struct stub_exn {
     stub_exn.info = (union stub_exception_token) { .raw = ~0 };         \
     stub_exn.line = __LINE__; /* Utility outweighs livepatching cost */ \
     block_speculation(); /* SCSB */                                     \
-    asm volatile ( pre "\n\tINDIRECT_CALL %[stub]\n\t" post "\n"        \
+    asm volatile ( pre "\n\t"                                           \
+                   "INDIRECT_CALL %[stub]\n"                            \
                    ".Lret%=:\n\t"                                       \
+                   post "\n\t"                                          \
+                   ".Lskip%=:\n\t"                                      \
                    ".pushsection .fixup,\"ax\"\n"                       \
                    ".Lfix%=:\n\t"                                       \
                    "pop %[exn]\n\t"                                     \
-                   "jmp .Lret%=\n\t"                                    \
+                   "jmp .Lskip%=\n\t"                                   \
                    ".popsection\n\t"                                    \
                    _ASM_EXTABLE(.Lret%=, .Lfix%=)                       \
                    : [exn] "+g" (stub_exn.info) ASM_CALL_CONSTRAINT,    \