[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


  • To: xen-changelog@xxxxxxxxxxxxxxxxxxx
  • From: Xen patchbot-linux-2.6.18-xen <patchbot@xxxxxxx>
  • Date: Fri, 19 Oct 2012 16:00:09 +0000
  • Delivery-date: Fri, 19 Oct 2012 16:00:19 +0000
  • List-id: "Change log for Mercurial \(receive only\)" <xen-changelog.lists.xen.org>

# 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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.