[CRIU] [PATCH 4/4] prctl: restore -- Use new PR_SET_MM_MAP if kernel supports

Cyrill Gorcunov gorcunov at openvz.org
Fri Oct 10 04:09:38 PDT 2014


This would allow to restore parameters with user namespaces
enabled.

Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 cr-restore.c       |  2 ++
 include/restorer.h |  1 +
 pie/restorer.c     | 63 ++++++++++++++++++++++++++++++++++++------------------
 3 files changed, 45 insertions(+), 21 deletions(-)

diff --git a/cr-restore.c b/cr-restore.c
index c8cb4289d5b4..7ca80ba2c197 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -2769,6 +2769,8 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
 	if (rlims_nr)
 		task_args->rlims = rst_mem_remap_ptr(rlims_cpos, RM_PRIVATE);
 
+	task_args->prctl_may_use_mm_map = kerndat_prctl_may_use_mm_map();
+
 	/*
 	 * Fill up per-thread data.
 	 */
diff --git a/include/restorer.h b/include/restorer.h
index 2d9af0d085c1..458171978ccc 100644
--- a/include/restorer.h
+++ b/include/restorer.h
@@ -149,6 +149,7 @@ struct task_restore_args {
 	int				tcp_socks_nr;
 
 	int				fd_last_pid; /* sys.ns_last_pid for threads rst */
+	int				prctl_may_use_mm_map;
 
 	pid_t				*helpers /* the TASK_HELPERS to wait on at the end of restore */;
 	int				n_helpers;
diff --git a/pie/restorer.c b/pie/restorer.c
index 6c9d0a318c73..32c20ffb8fd6 100644
--- a/pie/restorer.c
+++ b/pie/restorer.c
@@ -931,30 +931,51 @@ long __export_restore_task(struct task_restore_args *args)
 	/*
 	 * Tune up the task fields.
 	 */
-	ret |= sys_prctl_safe(PR_SET_NAME, (long)args->comm, 0, 0);
-
-	ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_START_CODE,	(long)args->mm.mm_start_code, 0);
-	ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_END_CODE,	(long)args->mm.mm_end_code, 0);
-	ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_START_DATA,	(long)args->mm.mm_start_data, 0);
-	ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_END_DATA,	(long)args->mm.mm_end_data, 0);
-	ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_START_STACK,	(long)args->mm.mm_start_stack, 0);
-	ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_START_BRK,	(long)args->mm.mm_start_brk, 0);
-	ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_BRK,		(long)args->mm.mm_brk, 0);
-	ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_ARG_START,	(long)args->mm.mm_arg_start, 0);
-	ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_ARG_END,	(long)args->mm.mm_arg_end, 0);
-	ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_ENV_START,	(long)args->mm.mm_env_start, 0);
-	ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_ENV_END,	(long)args->mm.mm_env_end, 0);
-	ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_AUXV,	(long)args->mm_saved_auxv, args->mm_saved_auxv_size);
+	ret = sys_prctl_safe(PR_SET_NAME, (long)args->comm, 0, 0);
 	if (ret)
 		goto core_restore_end;
 
-	/*
-	 * Because of requirements applied from kernel side
-	 * we need to restore /proc/pid/exe symlink late,
-	 * after old existing VMAs are superseded with
-	 * new ones from image file.
-	 */
-	ret = restore_self_exe_late(args);
+	if (args->prctl_may_use_mm_map) {
+		struct prctl_mm_map prctl_map = {
+			.start_code	= args->mm.mm_start_code,
+			.end_code	= args->mm.mm_end_code,
+			.start_data	= args->mm.mm_start_data,
+			.end_data	= args->mm.mm_end_data,
+			.start_stack	= args->mm.mm_start_stack,
+			.start_brk	= args->mm.mm_start_brk,
+			.brk		= args->mm.mm_brk,
+			.arg_start	= args->mm.mm_arg_start,
+			.arg_end	= args->mm.mm_arg_end,
+			.env_start	= args->mm.mm_env_start,
+			.env_end	= args->mm.mm_env_end,
+			.auxv_size	= args->mm_saved_auxv_size,
+			.auxv		= args->mm_saved_auxv,
+			.exe_fd		= args->fd_exe_link,
+		};
+		ret = sys_prctl_safe(PR_SET_MM, PR_SET_MM_MAP, (long)&prctl_map, sizeof(prctl_map));
+		sys_close(args->fd_exe_link);
+	} else {
+		ret  = sys_prctl_safe(PR_SET_MM, PR_SET_MM_START_CODE,	(long)args->mm.mm_start_code, 0);
+		ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_END_CODE,	(long)args->mm.mm_end_code, 0);
+		ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_START_DATA,	(long)args->mm.mm_start_data, 0);
+		ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_END_DATA,	(long)args->mm.mm_end_data, 0);
+		ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_START_STACK,	(long)args->mm.mm_start_stack, 0);
+		ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_START_BRK,	(long)args->mm.mm_start_brk, 0);
+		ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_BRK,		(long)args->mm.mm_brk, 0);
+		ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_ARG_START,	(long)args->mm.mm_arg_start, 0);
+		ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_ARG_END,	(long)args->mm.mm_arg_end, 0);
+		ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_ENV_START,	(long)args->mm.mm_env_start, 0);
+		ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_ENV_END,	(long)args->mm.mm_env_end, 0);
+		ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_AUXV,	(long)args->mm_saved_auxv, args->mm_saved_auxv_size);
+
+		/*
+		 * Because of requirements applied from kernel side
+		 * we need to restore /proc/pid/exe symlink late,
+		 * after old existing VMAs are superseded with
+		 * new ones from image file.
+		 */
+		ret |= restore_self_exe_late(args);
+	}
 	if (ret)
 		goto core_restore_end;
 
-- 
1.9.3



More information about the CRIU mailing list