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

Cyrill Gorcunov gorcunov at openvz.org
Fri Oct 24 03:10:47 PDT 2014


This would allow to restore parameters with user namespaces
enabled.

Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 pie/restorer.c | 65 +++++++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 46 insertions(+), 19 deletions(-)

diff --git a/pie/restorer.c b/pie/restorer.c
index 7196a3ed5803..93dc05be1eac 100644
--- a/pie/restorer.c
+++ b/pie/restorer.c
@@ -754,6 +754,7 @@ long __export_restore_task(struct task_restore_args *args)
 	unsigned long va;
 
 	struct rt_sigframe *rt_sigframe;
+	struct prctl_mm_map prctl_map;
 	unsigned long new_sp;
 	k_rtsigset_t to_block;
 	pid_t my_pid = sys_getpid();
@@ -921,30 +922,56 @@ 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.
+	 * New kernel interface with @PR_SET_MM_MAP will become
+	 * more widespread once kernel get deployed over the world.
+	 * Thus lets be opportunistic and use new inteface as a try.
 	 */
-	ret = restore_self_exe_late(args);
+	prctl_map = (struct prctl_mm_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		= (void *)args->mm_saved_auxv,
+		.auxv_size	= args->mm_saved_auxv_size,
+		.exe_fd		= args->fd_exe_link,
+	};
+	ret = sys_prctl(PR_SET_MM, PR_SET_MM_MAP, (long)&prctl_map, sizeof(prctl_map), 0);
+	if (ret == -EINVAL) {
+		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);
+	} else
+		sys_close(args->fd_exe_link);
+
 	if (ret)
 		goto core_restore_end;
 
-- 
1.9.3



More information about the CRIU mailing list