x86_32, entry: Store badsys error code in %eax 66/43466/3
authorSven Wegener <sven.wegener@stealer.net>
Tue, 22 Jul 2014 08:26:06 +0000 (10:26 +0200)
committerSeokYeon Hwang <syeon.hwang@samsung.com>
Mon, 20 Jul 2015 07:16:33 +0000 (00:16 -0700)
commitd76e255a54d3b21cd5b9a7202e4cfe552e2efdb4
tree7b5a282fa2495a7ecb48516954e0dd038954308f
parente07c81dc9d145b706cc5e137ebb64dc663500ad9
x86_32, entry: Store badsys error code in %eax

commit 8142b215501f8b291a108a202b3a053a265b03dd upstream.

Commit 554086d ("x86_32, entry: Do syscall exit work on badsys
(CVE-2014-4508)") introduced a regression in the x86_32 syscall entry
code, resulting in syscall() not returning proper errors for undefined
syscalls on CPUs supporting the sysenter feature.

The following code:

> int result = syscall(666);
> printf("result=%d errno=%d error=%s\n", result, errno, strerror(errno));

results in:

> result=666 errno=0 error=Success

Obviously, the syscall return value is the called syscall number, but it
should have been an ENOSYS error. When run under ptrace it behaves
correctly, which makes it hard to debug in the wild:

> result=-1 errno=38 error=Function not implemented

The %eax register is the return value register. For debugging via ptrace
the syscall entry code stores the complete register context on the
stack. The badsys handlers only store the ENOSYS error code in the
ptrace register set and do not set %eax like a regular syscall handler
would. The old resume_userspace call chain contains code that clobbers
%eax and it restores %eax from the ptrace registers afterwards. The same
goes for the ptrace-enabled call chain. When ptrace is not used, the
syscall return value is the passed-in syscall number from the untouched
%eax register.

Use %eax as the return value register in syscall_badsys and
sysenter_badsys, like a real syscall handler does, and have the caller
push the value onto the stack for ptrace access.

Signed-off-by: Sven Wegener <sven.wegener@stealer.net>
Link: http://lkml.kernel.org/r/alpine.LNX.2.11.1407221022380.31021@titan.int.lan.stealer.net
Reviewed-and-tested-by: Andy Lutomirski <luto@amacapital.net>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Origin: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=8142b215501f8b291a108a202b3a053a265b03dd
Backported-by: Maciej Wereski <m.wereski@partner.samsung.com>
Signed-off-by: Maciej Wereski <m.wereski@partner.samsung.com>
Change-Id: I5ecc413a86a49ee59a6bd3a55dc582dafd73d827
arch/x86/kernel/entry_32.S