2
0
mirror of https://github.com/checkpoint-restore/criu synced 2025-08-31 14:25:49 +00:00

restore: Don't unmap vdso proxy on final cleanup

In case if we need to use vdso proxy the memory area
which holds restorer also has a place for vdso proxy
code itself, so on final pass we should not unmap it,
otherwise any call to vdso function will cause sigsegv.

IOW, the memory before final "cleanup" pass of restorer
might look as

    +-----------+---------+     +-------------+------+
    | bootstrap | rt-vdso | ... | application | vdso |
    +-----------+---------+     +-------------+------+
                       ^                         |
                       `-------------------------+

and we have redirected "vdso" code to jump to "rt-vdso".
After final pass the memory must look as

                +---------+     +-------------+------+
                | rt-vdso | ... | application | vdso |
                +---------+     +-------------+------+
                       ^                         |
                       `-------------------------+

I noticed this problem during container migration
testing, the container itself was suspended on 2.6.32
OpenVZ kernel with apache running inside, and any attempt
to connect to apache caused apache to crash.

Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
Cyrill Gorcunov
2013-10-30 16:30:57 +04:00
committed by Pavel Emelyanov
parent e55acdd986
commit 0707df7745
3 changed files with 5 additions and 1 deletions

View File

@@ -2382,6 +2382,7 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
task_args->bootstrap_start = bootstrap_start;
task_args->bootstrap_len = restore_bootstrap_len;
task_args->vdso_rt_size = vdso_rt_size;
/*
* Get a reference to shared memory area which is

View File

@@ -119,6 +119,7 @@ struct task_restore_core_args {
void *bootstrap_start;
unsigned long bootstrap_len;
unsigned long vdso_rt_size;
struct itimerval itimers[3];

View File

@@ -513,10 +513,11 @@ static void restore_posix_timers(struct task_restore_core_args *args)
}
static void *bootstrap_start;
static unsigned int bootstrap_len;
static unsigned long vdso_rt_size;
void __export_unmap(void)
{
sys_munmap(bootstrap_start, bootstrap_len);
sys_munmap(bootstrap_start, bootstrap_len - vdso_rt_size);
/*
* sys_munmap must not return here. The controll process must
* trap us on the exit from sys_munmap.
@@ -590,6 +591,7 @@ long __export_restore_task(struct task_restore_core_args *args)
bootstrap_start = args->bootstrap_start;
bootstrap_len = args->bootstrap_len;
vdso_rt_size = args->vdso_rt_size;
task_entries = args->task_entries;