[CRIU] [PATCH 2/3] cr-exec: check syscall's number right before injecting it
Dmitry Safonov
dsafonov at virtuozzo.com
Wed Jul 6 06:48:18 PDT 2016
So, I made a mistake in find_syscall: it can't use arch_task_compatible
to find out in which mode the application is (native/compat).
The reason is that arch_task_compatible uses PTRACE_GETREGSET.
And at the moment of find_syscall we haven't yet seized the task.
In this patch I move syscall's number check right before injecting
a syscall, where we have parasite_ctl with all needed information
about task's mode.
This makes error-path for wrong syscall number longer and subtler
(includes curing now), but I think it's a corner-case, so as
it makes error-less path to execute_syscall shorter and without
additional ptrace syscalls, it's better.
Reported-by: Andrew Vagin <avagin at virtuozzo.com>
Cc: Andrew Vagin <avagin at virtuozzo.com>
Cc: Cyrill Gorcunov <gorcunov at openvz.org>
Signed-off-by: Dmitry Safonov <dsafonov at virtuozzo.com>
---
criu/arch/x86/sys-exec-tbl.c | 19 ++++++-------------
criu/cr-exec.c | 15 ++++++++-------
2 files changed, 14 insertions(+), 20 deletions(-)
diff --git a/criu/arch/x86/sys-exec-tbl.c b/criu/arch/x86/sys-exec-tbl.c
index b7f95b98e5a6..27e567063312 100644
--- a/criu/arch/x86/sys-exec-tbl.c
+++ b/criu/arch/x86/sys-exec-tbl.c
@@ -24,26 +24,19 @@ find_syscall_table(char *name, struct syscall_exec_desc *tbl)
return NULL;
}
-int __attribute__((weak)) arch_task_compatible(pid_t pid) { return false; }
#define ARCH_HAS_FIND_SYSCALL
/* overwrite default to search in two tables above */
#ifdef CONFIG_X86_64
-struct syscall_exec_desc * find_syscall(char *name, int pid)
+struct syscall_exec_desc * find_syscall(char *name, struct parasite_ctl *ctl)
{
- int err = arch_task_compatible(pid);
-
- switch(err) {
- case 0:
- return find_syscall_table(name, sc_exec_table_64);
- case 1:
- return find_syscall_table(name, sc_exec_table_32);
- default: /* Error */
- return NULL;
- }
+ if (seized_native(ctl))
+ return find_syscall_table(name, sc_exec_table_64);
+ else
+ return find_syscall_table(name, sc_exec_table_32);
}
#else
struct syscall_exec_desc *
-find_syscall(char *name, __attribute__((unused)) int pid)
+find_syscall(char *name, __attribute__((unused)) struct parasite_ctl *ctl)
{
return find_syscall_table(name, sc_exec_table_32);
}
diff --git a/criu/cr-exec.c b/criu/cr-exec.c
index a4c07e2f05a5..e8177388686b 100644
--- a/criu/cr-exec.c
+++ b/criu/cr-exec.c
@@ -19,7 +19,7 @@ struct syscall_exec_desc {
#ifndef ARCH_HAS_FIND_SYSCALL
struct syscall_exec_desc *
-find_syscall(char *name, int __attribute__((unused)) pid)
+find_syscall(char *name, struct parasite_ctl __attribute__((unused)) *ctl)
{
int i;
@@ -125,12 +125,6 @@ int cr_exec(int pid, char **opt)
goto out;
}
- si = find_syscall(sys_name, pid);
- if (!si) {
- pr_err("Unknown syscall [%s]\n", sys_name);
- goto out;
- }
-
if (seize_catch_task(pid))
goto out;
@@ -159,10 +153,17 @@ int cr_exec(int pid, char **opt)
goto out_unseize;
}
+ si = find_syscall(sys_name, ctl);
+ if (!si) {
+ pr_err("Unknown syscall [%s]\n", sys_name);
+ goto out_cure;
+ }
+
ret = execute_syscall(ctl, si, opt + 1);
if (ret < 0)
pr_err("Can't execute syscall remotely\n");
+out_cure:
parasite_cure_seized(ctl);
out_unseize:
unseize_task(pid, prev_state, prev_state);
--
2.9.0
More information about the CRIU
mailing list