From b752e05e41b353dc47da242323285a5c968a151c Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Thu, 14 Feb 2013 20:26:29 +0400 Subject: [PATCH] dump: Make sure we're dumping task not running in compat mode It's been reported that we do not test if the tracee is 32bit task running kn 64bit kernel. This patch adds such test. https://bugzilla.openvz.org/show_bug.cgi?id=2505 Signed-off-by: Cyrill Gorcunov Signed-off-by: Pavel Emelyanov --- arch/arm/crtools.c | 7 +++++++ arch/x86/crtools.c | 22 ++++++++++++++++++++++ include/parasite-syscall.h | 1 + parasite-syscall.c | 5 +++++ 4 files changed, 35 insertions(+) diff --git a/arch/arm/crtools.c b/arch/arm/crtools.c index c1ee5dc1d..8428e15b8 100644 --- a/arch/arm/crtools.c +++ b/arch/arm/crtools.c @@ -47,6 +47,13 @@ void parasite_setup_regs(unsigned long new_ip, user_regs_struct_t *regs) regs->ARM_cpsr &= PSR_f | PSR_s | PSR_x | PSR_T_BIT | MODE32_BIT; } +int task_in_compat_mode(pid_t pid) +{ + /* + * TODO: Add proper check here + */ + return 0; +} int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret, unsigned long arg1, diff --git a/arch/x86/crtools.c b/arch/x86/crtools.c index 605979e7b..dcb8f55f0 100644 --- a/arch/x86/crtools.c +++ b/arch/x86/crtools.c @@ -45,6 +45,28 @@ void parasite_setup_regs(unsigned long new_ip, user_regs_struct_t *regs) regs->flags &= ~(X86_EFLAGS_TF | X86_EFLAGS_DF | X86_EFLAGS_IF); } +int task_in_compat_mode(pid_t pid) +{ + unsigned long cs, ds; + + errno = 0; + cs = ptrace(PTRACE_PEEKUSER, pid, offsetof(user_regs_struct_t, cs), 0); + if (errno != 0) { + perror("Can't get CS register"); + return -1; + } + + errno = 0; + ds = ptrace(PTRACE_PEEKUSER, pid, offsetof(user_regs_struct_t, ds), 0); + if (errno != 0) { + perror("Can't get DS register"); + return -1; + } + + /* It's x86-32 or x32 */ + return cs != 0x33 || ds == 0x2b; +} + int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret, unsigned long arg1, unsigned long arg2, diff --git a/include/parasite-syscall.h b/include/parasite-syscall.h index 0c222fb54..2f32d03c6 100644 --- a/include/parasite-syscall.h +++ b/include/parasite-syscall.h @@ -71,5 +71,6 @@ int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret, unsigned long arg6); extern int __parasite_execute(struct parasite_ctl *ctl, pid_t pid, user_regs_struct_t *regs); +extern int task_in_compat_mode(pid_t pid); #endif /* __CR_PARASITE_SYSCALL_H__ */ diff --git a/parasite-syscall.c b/parasite-syscall.c index 0941c3912..c86307f8a 100644 --- a/parasite-syscall.c +++ b/parasite-syscall.c @@ -713,6 +713,11 @@ struct parasite_ctl *parasite_prep_ctl(pid_t pid, struct list_head *vma_area_lis struct parasite_ctl *ctl = NULL; struct vma_area *vma_area; + if (task_in_compat_mode(pid)) { + pr_err("Can't checkpoint task running in compat mode\n"); + goto err; + } + /* * Control block early setup. */