[CRIU] [PATCH 3/3] cr-exec: initialize kdat.task_size on criu exec

Dmitry Safonov dsafonov at virtuozzo.com
Wed Jul 6 06:48:19 PDT 2016


For `criu exec` we are searching for a place for syscall injection.
While searching for a VMA with PROT_EXEC and with needed size,
we check that VMA is lower than task_size.
The callpath for it is:
cr_exec => parasite_prep_ctl => get_vma_by_ip

Firstly, I thought to omit kdat.task_size checking if it's not inited:
> if (vma_area->e->start >= kdat.task_size && kdat.task_size)
but I think it's a hack then a proper solution.
Besides, this code still can choose VMA over task_size on ARM
and try to inject syscall there (IIRC, ARM has kernel-mapped
VMA in that area).

So, lets init kdat.task_size for `criu exec`.

Cc: Christopher Covington <cov at codeaurora.org>
Cc: Andrew Vagin <avagin at virtuozzo.com>
Cc: Cyrill Gorcunov <gorcunov at openvz.org>
Signed-off-by: Dmitry Safonov <dsafonov at virtuozzo.com>
---
 criu/cr-exec.c         | 6 ++++++
 criu/include/kerndat.h | 1 +
 criu/kerndat.c         | 6 +++---
 3 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/criu/cr-exec.c b/criu/cr-exec.c
index e8177388686b..53a8aa77278c 100644
--- a/criu/cr-exec.c
+++ b/criu/cr-exec.c
@@ -7,6 +7,7 @@
 #include "vma.h"
 #include "log.h"
 #include "util.h"
+#include "kerndat.h"
 
 struct syscall_exec_desc {
 	char *name;
@@ -125,6 +126,11 @@ int cr_exec(int pid, char **opt)
 		goto out;
 	}
 
+	if (kerndat_init_task_size()) {
+		pr_err("Cannot find task_size\n");
+		goto out;
+	}
+
 	if (seize_catch_task(pid))
 		goto out;
 
diff --git a/criu/include/kerndat.h b/criu/include/kerndat.h
index e1bf7ad043c6..ecbaaef923a7 100644
--- a/criu/include/kerndat.h
+++ b/criu/include/kerndat.h
@@ -15,6 +15,7 @@ extern int kerndat_init_rst(void);
 extern int kerndat_get_dirty_track(void);
 extern int kerndat_fdinfo_has_lock(void);
 extern int kerndat_loginuid(bool only_dump);
+extern int kerndat_init_task_size(void);
 
 enum pagemap_func {
 	PM_UNKNOWN,
diff --git a/criu/kerndat.c b/criu/kerndat.c
index 07f848e7bae0..b726416a42d7 100644
--- a/criu/kerndat.c
+++ b/criu/kerndat.c
@@ -348,7 +348,7 @@ static bool kerndat_has_memfd_create(void)
 	return 0;
 }
 
-static int get_task_size(void)
+int kerndat_init_task_size(void)
 {
 	kdat.task_size = task_size();
 	pr_debug("Found task size of %lx\n", kdat.task_size);
@@ -476,7 +476,7 @@ int kerndat_init(void)
 	if (!ret)
 		ret = kerndat_fdinfo_has_lock();
 	if (!ret)
-		ret = get_task_size();
+		ret = kerndat_init_task_size();
 	if (!ret)
 		ret = get_ipv6();
 	if (!ret)
@@ -507,7 +507,7 @@ int kerndat_init_rst(void)
 	if (!ret)
 		ret = kerndat_has_memfd_create();
 	if (!ret)
-		ret = get_task_size();
+		ret = kerndat_init_task_size();
 	if (!ret)
 		ret = get_ipv6();
 	if (!ret)
-- 
2.9.0



More information about the CRIU mailing list