diff options
author | David Vrabel <david.vrabel@citrix.com> | 2012-10-19 17:29:07 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-10-28 10:56:11 -0700 |
commit | 43a9e5c3f04f3ee1c5b0bf2c81d8e2fdf9a83668 (patch) | |
tree | a231f8312346feaefb5a7cac428e202ffde6c7ed /drivers/usb/class/cdc-acm.c | |
parent | 54ce8ce298f382a06186cb4672ad6aa090b050b6 (diff) | |
download | linux-stable-43a9e5c3f04f3ee1c5b0bf2c81d8e2fdf9a83668.tar.gz linux-stable-43a9e5c3f04f3ee1c5b0bf2c81d8e2fdf9a83668.tar.bz2 linux-stable-43a9e5c3f04f3ee1c5b0bf2c81d8e2fdf9a83668.zip |
xen/x86: don't corrupt %eip when returning from a signal handler
commit a349e23d1cf746f8bdc603dcc61fae9ee4a695f6 upstream.
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 and avoids some of the tests in
handle_signal().
There were similar bugs in xen_failsafe_callback() of both 32 and
64-bit guests. If the fault was corrected and the normal return path
was used then 0 was incorrectly pushed as the value for orig_ax.
Signed-off-by: David Vrabel <david.vrabel@citrix.com>
Acked-by: Jan Beulich <JBeulich@suse.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/class/cdc-acm.c')
0 files changed, 0 insertions, 0 deletions