]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commit - arch/x86/kernel/process_64.c
x86/asm/entry: Fix execve() and sigreturn() syscalls to always return via IRET
authorBrian Gerst <brgerst@gmail.com>
Sat, 21 Mar 2015 22:54:21 +0000 (18:54 -0400)
committerIngo Molnar <mingo@kernel.org>
Mon, 23 Mar 2015 07:52:46 +0000 (08:52 +0100)
commit1daeaa315164c60b937f56fe3848d4328c358eba
tree07db9e9d5b52cc23c2a839a597832136afca2c24
parentc38e503804b0402c510f82437069f7769fa0cea9
x86/asm/entry: Fix execve() and sigreturn() syscalls to always return via IRET

Both the execve() and sigreturn() family of syscalls have the
ability to change registers in ways that may not be compatabile
with the syscall path they were called from.

In particular, SYSRET and SYSEXIT can't handle non-default %cs and %ss,
and some bits in eflags.

These syscalls have stubs that are hardcoded to jump to the IRET path,
and not return to the original syscall path.

The following commit:

   76f5df43cab5e76 ("Always allocate a complete "struct pt_regs" on the kernel stack")

recently changed this for some 32-bit compat syscalls, but introduced a bug where
execve from a 32-bit program to a 64-bit program would fail because it still returned
via SYSRETL. This caused Wine to fail when built for both 32-bit and 64-bit.

This patch sets TIF_NOTIFY_RESUME for execve() and sigreturn() so
that the IRET path is always taken on exit to userspace.

Signed-off-by: Brian Gerst <brgerst@gmail.com>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: http://lkml.kernel.org/r/1426978461-32089-1-git-send-email-brgerst@gmail.com
[ Improved the changelog and comments. ]
Signed-off-by: Ingo Molnar <mingo@kernel.org>
arch/x86/ia32/ia32_signal.c
arch/x86/include/asm/ptrace.h
arch/x86/include/asm/thread_info.h
arch/x86/kernel/process_32.c
arch/x86/kernel/process_64.c
arch/x86/kernel/signal.c