![Denys Vlasenko](/assets/img/avatar_default.png)
This new test checks that all x86 registers are preserved across 32-bit syscalls. It tests syscalls through VDSO (if available) and through INT 0x80, normally and under ptrace. If kernel is a 64-bit one, high registers (r8..r15) are poisoned before the syscall is called and are checked afterwards. They must be either preserved, or cleared to zero (but r11 is special); r12..15 must be preserved for INT 0x80. EFLAGS is checked for changes too, but change there is not considered to be a bug (paravirt kernels do not preserve arithmetic flags). Run-tested on 64-bit kernel: $ ./test_syscall_vdso_32 [RUN] Executing 6-argument 32-bit syscall via VDSO [OK] Arguments are preserved across syscall [NOTE] R11 has changed:0000000000200ed7 - assuming clobbered by SYSRET insn [OK] R8..R15 did not leak kernel data [RUN] Executing 6-argument 32-bit syscall via INT 80 [OK] Arguments are preserved across syscall [OK] R8..R15 did not leak kernel data [RUN] Running tests under ptrace [RUN] Executing 6-argument 32-bit syscall via VDSO [OK] Arguments are preserved across syscall [OK] R8..R15 did not leak kernel data [RUN] Executing 6-argument 32-bit syscall via INT 80 [OK] Arguments are preserved across syscall [OK] R8..R15 did not leak kernel data On 32-bit paravirt kernel: $ ./test_syscall_vdso_32 [NOTE] Not a 64-bit kernel, won't test R8..R15 leaks [RUN] Executing 6-argument 32-bit syscall via VDSO [WARN] Flags before=0000000000200ed7 id 0 00 o d i s z 0 a 0 p 1 c [WARN] Flags after=0000000000200246 id 0 00 i z 0 0 p 1 [WARN] Flags change=0000000000000c91 0 00 o d s 0 a 0 0 c [OK] Arguments are preserved across syscall [RUN] Executing 6-argument 32-bit syscall via INT 80 [OK] Arguments are preserved across syscall [RUN] Running tests under ptrace [RUN] Executing 6-argument 32-bit syscall via VDSO [OK] Arguments are preserved across syscall [RUN] Executing 6-argument 32-bit syscall via INT 80 [OK] Arguments are preserved across syscall Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com> Acked-by: Andy Lutomirski <luto@amacapital.net> Cc: Alexei Starovoitov <ast@plumgrid.com> Cc: Borislav Petkov <bp@alien8.de> Cc: Brian Gerst <brgerst@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Kees Cook <keescook@chromium.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Shuah Khan <shuahkh@osg.samsung.com> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Will Drewry <wad@chromium.org> Cc: linux-kernel@vger.kernel.org Link: http://lkml.kernel.org/r/1442427809-2027-1-git-send-email-dvlasenk@redhat.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
56 lines
1.2 KiB
ArmAsm
56 lines
1.2 KiB
ArmAsm
/*
|
|
* thunks_32.S - assembly helpers for mixed-bitness code
|
|
* Copyright (c) 2015 Denys Vlasenko
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms and conditions of the GNU General Public License,
|
|
* version 2, as published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* These are little helpers that make it easier to switch bitness on
|
|
* the fly.
|
|
*/
|
|
|
|
.text
|
|
.code32
|
|
|
|
.global call64_from_32
|
|
.type call32_from_64, @function
|
|
|
|
// 4(%esp): function to call
|
|
call64_from_32:
|
|
// Fetch function address
|
|
mov 4(%esp), %eax
|
|
|
|
// Save registers which are callee-clobbered by 64-bit ABI
|
|
push %ecx
|
|
push %edx
|
|
push %esi
|
|
push %edi
|
|
|
|
// Switch to long mode
|
|
jmp $0x33,$1f
|
|
1: .code64
|
|
|
|
// Call the function
|
|
call *%rax
|
|
|
|
// Switch to compatibility mode
|
|
push $0x23 /* USER32_CS */
|
|
.code32; push $1f; .code64 /* hack: can't have X86_64_32S relocation in 32-bit ELF */
|
|
lretq
|
|
1: .code32
|
|
|
|
pop %edi
|
|
pop %esi
|
|
pop %edx
|
|
pop %ecx
|
|
|
|
ret
|
|
|
|
.size call64_from_32, .-call64_from_32
|