[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [linux-2.6.18-xen] x86: don't corrupt %eip when returning from a signal handler
# HG changeset patch # User David Vrabel <david.vrabel@xxxxxxxxxx> # Date 1350662240 -7200 # Node ID f695483240db110763b89c6821a2357929f2ec1e # Parent 0dbf07f0bdbfea42ba2f43a7e4786394ece74515 x86: don't corrupt %eip when returning from a signal handler In 32 bit guests, if a userspace process has %eax == -ERESTARTSYS (-512) or -ERESTARTNOINTR (-513) when it is interrupted by an event /and/ the process has a pending signal then %eip (and %eax) are corrupted when returning to the main process after handling the signal. The application may then crash with SIGSEGV or a SIGILL or it may have subtly incorrect behaviour (depending on what instruction it returned to). The occurs because handle_signal() is incorrectly thinking that there is a system call that needs to restarted so it adjusts %eip and %eax to re-execute the system call instruction (even though user space had not done a system call). If %eax == -514 (-ERESTARTNOHAND (-514) or -ERESTART_RESTARTBLOCK (-516) then handle_signal() only corrupted %eax (by setting it to -EINTR). This may cause the application to crash or have incorrect behaviour. handle_signal() assumes that regs->orig_ax >= 0 means a system call so any kernel entry point that is not for a system call must push a negative value for orig_ax. For example, for physical interrupts on bare metal the inverse of the vector is pushed and page_fault() sets regs->orig_ax to -1, overwriting the hardware provided error code. xen_hypervisor_callback() was incorrectly pushing 0 for orig_ax instead of -1. Classic Xen kernels pushed %eax which works as %eax cannot be both non-negative and -RESTARTSYS (etc.), but using -1 is consistent with other non-system call entry points. There were similar bugs in xen_failsafe_callback(), if the fault was corrected and normal return path was used. 64 bit guests would push 0 which is broken. 32 bit guests would push %eax which is safe (see previous paragraph), but for consistency this is also changed to -1. Signed-off-by: David Vrabel <david.vrabel@xxxxxxxxxx> Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx> While on x86-64 the situation is the same for the forward port code, on ix86 it is inverse to the description above (which isn't correct either, as that v2 patch modified the wrong push) - the failsafe callback is broken, while the "normal" callback is being changed only for consistency. Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> Committed-by: Jan Beulich <jbeulich@xxxxxxxx> --- diff -r 0dbf07f0bdbf -r f695483240db arch/i386/kernel/entry-xen.S --- a/arch/i386/kernel/entry-xen.S Fri Oct 19 17:46:12 2012 +0200 +++ b/arch/i386/kernel/entry-xen.S Fri Oct 19 17:57:20 2012 +0200 @@ -787,7 +787,7 @@ error_code: # so we can simply throw away the new one. ENTRY(hypervisor_callback) RING0_INT_FRAME - pushl %eax + pushl $-1 CFI_ADJUST_CFA_OFFSET 4 SAVE_ALL testb $2,CS(%esp) @@ -877,7 +877,7 @@ 4: mov 16(%esp),%gs jmp iret_exc 5: addl $16,%esp # EAX == 0 => Category 1 (Bad segment) RING0_INT_FRAME - pushl $0 + pushl $-1 SAVE_ALL jmp ret_from_exception .section .fixup,"ax"; \ diff -r 0dbf07f0bdbf -r f695483240db arch/x86_64/kernel/entry-xen.S --- a/arch/x86_64/kernel/entry-xen.S Fri Oct 19 17:46:12 2012 +0200 +++ b/arch/x86_64/kernel/entry-xen.S Fri Oct 19 17:57:20 2012 +0200 @@ -1032,7 +1032,7 @@ 1: /* Segment mismatch => Category 1 (Ba CFI_RESTORE r11 addq $0x30,%rsp CFI_ADJUST_CFA_OFFSET -0x30 - pushq $0 + pushq $-1 CFI_ADJUST_CFA_OFFSET 8 SAVE_ALL jmp error_exit _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |