[CRIU] [PATCH] restore: Don't unmap vdso proxy on final cleanup

Cyrill Gorcunov gorcunov at openvz.org
Tue Oct 29 13:54:11 PDT 2013


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 at openvz.org>
---
 cr-restore.c       | 1 +
 include/restorer.h | 1 +
 pie/restorer.c     | 4 +++-
 3 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/cr-restore.c b/cr-restore.c
index e219bca..eca540a 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -2395,6 +2395,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
diff --git a/include/restorer.h b/include/restorer.h
index 18a82d8..1ee1539 100644
--- a/include/restorer.h
+++ b/include/restorer.h
@@ -127,6 +127,7 @@ struct task_restore_core_args {
 
 	void				*bootstrap_start;
 	unsigned long			bootstrap_len;
+	unsigned long			vdso_rt_size;
 
 	struct itimerval		itimers[3];
 
diff --git a/pie/restorer.c b/pie/restorer.c
index a8706d9..43cb8f1 100644
--- a/pie/restorer.c
+++ b/pie/restorer.c
@@ -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.
@@ -589,6 +590,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;
 
-- 
1.8.3.1



More information about the CRIU mailing list