From 2aa583b45bc35ad23afe2be69c96e78e722df5b8 Mon Sep 17 00:00:00 2001 From: Dmitry Safonov Date: Tue, 12 Apr 2016 19:10:51 +0300 Subject: [PATCH] x86/crtools: rework arch_task_compatible Detect task's personality by the size of register set, returned by ptrace call with PTRACE_GETREGSET (more reliable). The same approach uses strace from 4.8 version: https://sourceforge.net/projects/strace/files/strace/4.8/ Signed-off-by: Dmitry Safonov Acked-by: Cyrill Gorcunov Signed-off-by: Pavel Emelyanov Signed-off-by: Andrei Vagin --- criu/arch/x86/crtools.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/criu/arch/x86/crtools.c b/criu/arch/x86/crtools.c index 0b85aab2c..85f2f54ed 100644 --- a/criu/arch/x86/crtools.c +++ b/criu/arch/x86/crtools.c @@ -58,9 +58,24 @@ void parasite_setup_regs(unsigned long new_ip, void *stack, user_regs_struct_t * ~(X86_EFLAGS_TF | X86_EFLAGS_DF | X86_EFLAGS_IF)); } +int ptrace_get_regs(pid_t pid, user_regs_struct_t *regs); int arch_task_compatible(pid_t pid) { - unsigned long cs, ds; + user_regs_struct_t r; + int ret = ptrace_get_regs(pid, &r); + + if (ret) + return -1; + + return !r.is_native; +} + +#define USER32_CS 0x23 +#define USER_CS 0x33 + +static bool ldt_task_selectors(pid_t pid) +{ + unsigned long cs; errno = 0; /* @@ -73,15 +88,7 @@ int arch_task_compatible(pid_t pid) return -1; } - errno = 0; - ds = ptrace(PTRACE_PEEKUSER, pid, offsetof(user_regs_struct64, ds), 0); - if (errno != 0) { - pr_perror("Can't get DS register for %d", pid); - return -1; - } - - /* It's x86-32 or x32 */ - return cs != 0x33 || ds == 0x2b; + return cs != USER_CS && cs != USER32_CS; } bool arch_can_dump_task(struct parasite_ctl *ctl) @@ -94,6 +101,11 @@ bool arch_can_dump_task(struct parasite_ctl *ctl) return false; } + if (ldt_task_selectors(pid)) { + pr_err("Can't dump task %d with LDT descriptors\n", pid); + return false; + } + return true; }