|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v3] x86/pv: inject #UD for entirely missing SYSCALL callbacks
In the case that no 64-bit SYSCALL callback is registered, the guest
will be crashed when 64-bit userspace executes a SYSCALL instruction,
which would be a userspace => kernel DoS. Similarly for 32-bit
userspace when no 32-bit SYSCALL callback was registered either.
This has been the case ever since the introduction of 64bit PV support,
but behaves unlike all other SYSCALL/SYSENTER callbacks in Xen, which
yield #GP/#UD in userspace before the callback is registered, and are
therefore safe by default.
This change does constitute a change in the PV ABI, for the corner case
of a PV guest kernel not registering a 64-bit callback (which has to be
considered a defacto requirement of the unwritten PV ABI, considering
there is no PV equivalent of EFER.SCE).
It brings the behaviour in line with PV32 SYSCALL/SYSENTER, and PV64
SYSENTER (safe by default, until explicitly enabled).
Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
Signed-off-by: Jan Beulich <JBeulich@xxxxxxxx>
---
v3:
* Split this change off of "x86/pv: Inject #UD for missing SYSCALL
callbacks", to allow the uncontroversial part of that change to go
in. Add conditional "rex64" for UREGS_rip adjustment. (Is branching
over just the REX prefix too much trickery even for an unlikely to be
taken code path?)
v2:
* Drop unnecessary instruction suffixes
* Don't truncate #UD entrypoint to 32 bits
--- a/xen/arch/x86/x86_64/entry.S
+++ b/xen/arch/x86/x86_64/entry.S
@@ -33,11 +33,27 @@ ENTRY(switch_to_kernel)
cmoveq VCPU_syscall32_addr(%rbx),%rax
testq %rax,%rax
cmovzq VCPU_syscall_addr(%rbx),%rax
- movq %rax,TRAPBOUNCE_eip(%rdx)
/* TB_flags = VGCF_syscall_disables_events ? TBF_INTERRUPT : 0 */
btl $_VGCF_syscall_disables_events,VCPU_guest_context_flags(%rbx)
setc %cl
leal (,%rcx,TBF_INTERRUPT),%ecx
+
+ test %rax, %rax
+UNLIKELY_START(z, syscall_no_callback) /* TB_eip == 0 => #UD */
+ mov VCPU_trap_ctxt(%rbx), %rdi
+ movl $X86_EXC_UD, UREGS_entry_vector(%rsp)
+ cmpw $FLAT_USER_CS32, UREGS_cs(%rsp)
+ je 0f
+ rex64 # subl => subq
+0:
+ subl $2, UREGS_rip(%rsp)
+ mov X86_EXC_UD * TRAPINFO_sizeof + TRAPINFO_eip(%rdi), %rax
+ testb $4, X86_EXC_UD * TRAPINFO_sizeof + TRAPINFO_flags(%rdi)
+ setnz %cl
+ lea TBF_EXCEPTION(, %rcx, TBF_INTERRUPT), %ecx
+UNLIKELY_END(syscall_no_callback)
+
+ movq %rax, TRAPBOUNCE_eip(%rdx)
movb %cl,TRAPBOUNCE_flags(%rdx)
call create_bounce_frame
andl $~X86_EFLAGS_DF,UREGS_eflags(%rsp)
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |