x86/pv: Avoid double exception injection
authorAndrew Cooper <andrew.cooper3@citrix.com>
Tue, 22 Sep 2020 14:12:44 +0000 (16:12 +0200)
committerJan Beulich <jbeulich@suse.com>
Tue, 22 Sep 2020 14:12:44 +0000 (16:12 +0200)
commiteb4a543a47df33038f4f6e915375ea898670c7dc
tree422450e1bb18a4cf9ea30a411f961f7a91e4dbc9
parente417504febf4ef5cc3442ebaa00da1a5c7939b22
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 <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
xen/arch/x86/x86_64/compat/entry.S
xen/arch/x86/x86_64/entry.S