Commit 0707df77 authored by Cyrill Gorcunov's avatar Cyrill Gorcunov Committed by Pavel Emelyanov

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: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent e55acdd9
...@@ -2382,6 +2382,7 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core) ...@@ -2382,6 +2382,7 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
task_args->bootstrap_start = bootstrap_start; task_args->bootstrap_start = bootstrap_start;
task_args->bootstrap_len = restore_bootstrap_len; task_args->bootstrap_len = restore_bootstrap_len;
task_args->vdso_rt_size = vdso_rt_size;
/* /*
* Get a reference to shared memory area which is * Get a reference to shared memory area which is
......
...@@ -119,6 +119,7 @@ struct task_restore_core_args { ...@@ -119,6 +119,7 @@ struct task_restore_core_args {
void *bootstrap_start; void *bootstrap_start;
unsigned long bootstrap_len; unsigned long bootstrap_len;
unsigned long vdso_rt_size;
struct itimerval itimers[3]; struct itimerval itimers[3];
......
...@@ -513,10 +513,11 @@ static void restore_posix_timers(struct task_restore_core_args *args) ...@@ -513,10 +513,11 @@ static void restore_posix_timers(struct task_restore_core_args *args)
} }
static void *bootstrap_start; static void *bootstrap_start;
static unsigned int bootstrap_len; static unsigned int bootstrap_len;
static unsigned long vdso_rt_size;
void __export_unmap(void) 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 * sys_munmap must not return here. The controll process must
* trap us on the exit from sys_munmap. * trap us on the exit from sys_munmap.
...@@ -590,6 +591,7 @@ long __export_restore_task(struct task_restore_core_args *args) ...@@ -590,6 +591,7 @@ long __export_restore_task(struct task_restore_core_args *args)
bootstrap_start = args->bootstrap_start; bootstrap_start = args->bootstrap_start;
bootstrap_len = args->bootstrap_len; bootstrap_len = args->bootstrap_len;
vdso_rt_size = args->vdso_rt_size;
task_entries = args->task_entries; task_entries = args->task_entries;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment