mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-07-28 12:36:47 +00:00
cr-exec: check syscall's number right before injecting it
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@virtuozzo.com> Cc: Andrew Vagin <avagin@virtuozzo.com> Cc: Cyrill Gorcunov <gorcunov@openvz.org> Signed-off-by: Dmitry Safonov <dsafonov@virtuozzo.com> Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com> Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
This commit is contained in:
parent
8f6800db83
commit
5141d3238a
2 changed files with 13 additions and 20 deletions
|
|
@ -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, __always_unused struct parasite_ctl *ctl)
|
||||
{
|
||||
return find_syscall_table(name, sc_exec_table_32);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,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 __always_unused *ctl)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
@ -135,12 +135,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;
|
||||
|
||||
|
|
@ -178,6 +172,12 @@ 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");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue