[CRIU] [PATCH 15/15] x86/crtools: rework arch_task_compatible

Dmitry Safonov dsafonov at virtuozzo.com
Mon Apr 11 05:19:29 PDT 2016


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 <dsafonov at virtuozzo.com>
---
 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 d259fc0269a5..172c534306a3 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(pid_t pid)
@@ -92,6 +99,11 @@ bool arch_can_dump_task(pid_t pid)
 		return false;
 	}
 
+	if (ldt_task_selectors(pid)) {
+		pr_err("Can't dump task %d with LDT descriptors\n", pid);
+		return false;
+	}
+
 	return true;
 }
 
-- 
2.8.0



More information about the CRIU mailing list