From c22f60e6e55f1bf300dd76d2222a93911f3b2bb2 Mon Sep 17 00:00:00 2001 From: CoprDistGit Date: Thu, 12 Oct 2023 04:00:49 +0000 Subject: automatic import of xen --- xsa339.patch | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 xsa339.patch (limited to 'xsa339.patch') diff --git a/xsa339.patch b/xsa339.patch new file mode 100644 index 0000000..4a67286 --- /dev/null +++ b/xsa339.patch @@ -0,0 +1,71 @@ +x86/pv: Avoid double exception injection + +There is at least one path (SYSENTER with NT set, Xen converts to #GP) which +ends up injecting the #GP fault twice, first in compat_sysenter(), and then a +second time in compat_test_all_events(), due to the stale TBF_EXCEPTION left +in TRAPBOUNCE_flags. + +The guest kernel sees the second fault first, which is a kernel level #GP +pointing at the head of the #GP handler, and is therefore a userspace +trigger-able DoS. + +This particular bug has bitten us several times before, so rearrange +{compat_,}create_bounce_frame() to clobber TRAPBOUNCE on success, rather than +leaving this task to one area of code which isn't used uniformly. + +Other scenarios which might result in a double injection (e.g. two calls +directly to compat_create_bounce_frame) will now crash the guest, which is far +more obvious than letting the kernel run with corrupt state. + +This is XSA-339. + +Fixes: fdac9515607b ("x86: clear EFLAGS.NT in SYSENTER entry path") +Signed-off-by: Andrew Cooper +Reviewed-by: Jan Beulich + +--- a/xen/arch/x86/x86_64/compat/entry.S ++++ b/xen/arch/x86/x86_64/compat/entry.S +@@ -78,7 +78,6 @@ compat_process_softirqs: + sti + .Lcompat_bounce_exception: + call compat_create_bounce_frame +- movb $0, TRAPBOUNCE_flags(%rdx) + jmp compat_test_all_events + + ALIGN +@@ -349,7 +348,13 @@ __UNLIKELY_END(compat_bounce_null_select + movl %eax,UREGS_cs+8(%rsp) + movl TRAPBOUNCE_eip(%rdx),%eax + movl %eax,UREGS_rip+8(%rsp) ++ ++ /* Trapbounce complete. Clobber state to avoid an erroneous second injection. */ ++ xor %eax, %eax ++ mov %ax, TRAPBOUNCE_cs(%rdx) ++ mov %al, TRAPBOUNCE_flags(%rdx) + ret ++ + .section .fixup,"ax" + .Lfx13: + xorl %edi,%edi +--- a/xen/arch/x86/x86_64/entry.S ++++ b/xen/arch/x86/x86_64/entry.S +@@ -90,7 +90,6 @@ process_softirqs: + sti + .Lbounce_exception: + call create_bounce_frame +- movb $0, TRAPBOUNCE_flags(%rdx) + jmp test_all_events + + ALIGN +@@ -495,6 +494,11 @@ UNLIKELY_START(z, create_bounce_frame_ba + jmp asm_domain_crash_synchronous /* Does not return */ + __UNLIKELY_END(create_bounce_frame_bad_bounce_ip) + movq %rax,UREGS_rip+8(%rsp) ++ ++ /* Trapbounce complete. Clobber state to avoid an erroneous second injection. */ ++ xor %eax, %eax ++ mov %rax, TRAPBOUNCE_eip(%rdx) ++ mov %al, TRAPBOUNCE_flags(%rdx) + ret + + .pushsection .fixup, "ax", @progbits -- cgit v1.2.3