[Devel] [PATCH RHEL7 COMMIT] ms/x86/coredump: Always use user_regs_struct for compat_elf_gregset_t
Konstantin Khorenko
khorenko at virtuozzo.com
Fri Nov 25 06:30:37 PST 2016
The commit is pushed to "branch-rh7-3.10.0-327.36.1.vz7.20.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-327.36.1.vz7.20.3
------>
commit 8b91c39348766ffa72cd310463657978ff5c1dcf
Author: Dmitry Safonov <dsafonov at virtuozzo.com>
Date: Fri Nov 25 18:30:37 2016 +0400
ms/x86/coredump: Always use user_regs_struct for compat_elf_gregset_t
Commit:
90954e7b9407 ("x86/coredump: Use pr_reg size, rather that TIF_IA32 flag")
changed the coredumping code to construct the elf coredump file according
to register set size - and that's good: if binary crashes with 32-bit code
selector, generate 32-bit ELF core, otherwise - 64-bit core.
That was made for restoring 32-bit applications on x86_64: we want
32-bit application after restore to generate 32-bit ELF dump on crash.
All was quite good and recently I started reworking 32-bit applications
dumping part of CRIU: now it has two parasites (32 and 64) for seizing
compat/native tasks, after rework it'll have one parasite, working in
64-bit mode, to which 32-bit prologue long-jumps during infection.
And while it has worked for my work machine, in VM with
!CONFIG_X86_X32_ABI during reworking I faced that segfault in 32-bit
binary, that has long-jumped to 64-bit mode results in dereference
of garbage:
32-victim[19266]: segfault at f775ef65 ip 00000000f775ef65 sp 00000000f776aa50 error 14
BUG: unable to handle kernel paging request at ffffffffffffffff
IP: [<ffffffff81332ce0>] strlen+0x0/0x20
[...]
Call Trace:
[] elf_core_dump+0x11a9/0x1480
[] do_coredump+0xa6b/0xe60
[] get_signal+0x1a8/0x5c0
[] do_signal+0x23/0x660
[] exit_to_usermode_loop+0x34/0x65
[] prepare_exit_to_usermode+0x2f/0x40
[] retint_user+0x8/0x10
That's because we have 64-bit registers set (with according total size)
and we're writing it to elf_thread_core_info which has smaller size
on !CONFIG_X86_X32_ABI. That lead to overwriting ELF notes part.
Tested on 32-, 64-bit ELF crashes and on 32-bit binaries that have
jumped with 64-bit code selector - all is readable with gdb.
Signed-off-by: Dmitry Safonov <dsafonov at virtuozzo.com>
Cc: Andy Lutomirski <luto at kernel.org>
Cc: Andy Lutomirski <luto at kernel.org>
Cc: Borislav Petkov <bp at alien8.de>
Cc: Brian Gerst <brgerst at gmail.com>
Cc: Denys Vlasenko <dvlasenk at redhat.com>
Cc: H. Peter Anvin <hpa at zytor.com>
Cc: Linus Torvalds <torvalds at linux-foundation.org>
Cc: Peter Zijlstra <peterz at infradead.org>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: Josh Poimboeuf <jpoimboe at redhat.com>
Cc: Linus Torvalds <torvalds at linux-foundation.org>
Cc: Oleg Nesterov <oleg at redhat.com>
Cc: Peter Zijlstra <peterz at infradead.org>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: linux-mm at kvack.org
Fixes: 90954e7b9407 ("x86/coredump: Use pr_reg size, rather that TIF_IA32 flag")
Signed-off-by: Ingo Molnar <mingo at kernel.org>
[applied from x86 git-tip for v4.9]
Gitweb: http://git.kernel.org/tip/7b2dd3682896bcf1abbbbe870885728db2832a3c
Signed-off-by: Dmitry Safonov <dsafonov at virtuozzo.com>
---
arch/x86/include/asm/compat.h | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/arch/x86/include/asm/compat.h b/arch/x86/include/asm/compat.h
index 6a07267..6ea296d 100644
--- a/arch/x86/include/asm/compat.h
+++ b/arch/x86/include/asm/compat.h
@@ -261,7 +261,6 @@ struct compat_shmid64_ds {
/*
* The type of struct elf_prstatus.pr_reg in compatible core dumps.
*/
-#ifdef CONFIG_X86_X32_ABI
typedef struct user_regs_struct compat_elf_gregset_t;
/* Full regset -- prstatus on x32, otherwise on ia32 */
@@ -270,10 +269,9 @@ typedef struct user_regs_struct compat_elf_gregset_t;
do { *(int *) (((void *) &((S)->pr_reg)) + R) = (V); } \
while (0)
+#ifdef CONFIG_X86_X32_ABI
#define COMPAT_USE_64BIT_TIME \
(!!(task_pt_regs(current)->orig_ax & __X32_SYSCALL_BIT))
-#else
-typedef struct user_regs_struct32 compat_elf_gregset_t;
#endif
/*
More information about the Devel
mailing list