[Devel] [PATCH] c/r: Save and restore task->personality (v2)

Dan Smith danms at us.ibm.com
Thu Apr 16 08:20:09 PDT 2009


This patch adds a spot in the task record to save the personality value
of the task_struct.

It also masks out READ_IMPLIES_EXEC before starting to avoid read-only
maps being restored as read-exec.  To avoid re-setting this flag too early,
it also introduces a "task_ctx" object to hold information that may be
collected when reading the task structure, but needs to be restored at a
later time (such as after the maps are read).  Since there may be additional
settings that need to be deferred until the end of task restore, I decided
to add the context object and a "cleanup" function to wrap things up.

Changes in v2:
  - Change __u64 to __u32 in the cr_task_hdr

Signed-off-by: Dan Smith <danms at us.ibm.com>
---
 checkpoint/ckpt_task.c         |    2 ++
 checkpoint/restart.c           |    8 ++++++++
 checkpoint/rstr_task.c         |   25 +++++++++++++++++++++++--
 include/linux/checkpoint_hdr.h |    2 ++
 4 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/checkpoint/ckpt_task.c b/checkpoint/ckpt_task.c
index 4d19e31..6a4118a 100644
--- a/checkpoint/ckpt_task.c
+++ b/checkpoint/ckpt_task.c
@@ -38,6 +38,8 @@ static int cr_write_task_struct(struct cr_ctx *ctx, struct task_struct *t)
 	hh->exit_code = t->exit_code;
 	hh->exit_signal = t->exit_signal;
 
+	hh->personality = current->personality;
+
 	hh->task_comm_len = TASK_COMM_LEN;
 
 	/* FIXME: save remaining relevant task_struct fields */
diff --git a/checkpoint/restart.c b/checkpoint/restart.c
index c6bcfac..2ad4b30 100644
--- a/checkpoint/restart.c
+++ b/checkpoint/restart.c
@@ -15,6 +15,7 @@
 #include <linux/magic.h>
 #include <linux/checkpoint.h>
 #include <linux/checkpoint_hdr.h>
+#include <linux/personality.h>
 #include <asm/syscall.h>
 
 #include "checkpoint_arch.h"
@@ -524,6 +525,13 @@ int do_restart(struct cr_ctx *ctx, pid_t pid)
 {
 	int ret;
 
+	/* Remove the READ_IMPLIES_EXEC flag from our personality
+	 * (if present) so that our restart logic doesn't change read
+	 * maps to read-execute.  If the task had this flag set at
+	 * checkpoint, it will be restored later.
+	 */
+	current->personality &= ~READ_IMPLIES_EXEC;
+
 	if (ctx)
 		ret = do_restart_root(ctx, pid);
 	else
diff --git a/checkpoint/rstr_task.c b/checkpoint/rstr_task.c
index fe5c059..bb09f99 100644
--- a/checkpoint/rstr_task.c
+++ b/checkpoint/rstr_task.c
@@ -20,8 +20,13 @@
 
 #include "checkpoint_arch.h"
 
+/* Per-task settings that need to be restored at the end of task restart */
+struct cr_task_ctx {
+	unsigned int personality;
+};
+
 /* read the task_struct into the current task */
-static int cr_read_task_struct(struct cr_ctx *ctx)
+static int cr_read_task_struct(struct cr_ctx *ctx, struct cr_task_ctx *tsk_ctx)
 {
 	struct cr_hdr_task *hh;
 	struct task_struct *t = current;
@@ -52,6 +57,8 @@ static int cr_read_task_struct(struct cr_ctx *ctx)
 	}
 	kfree(buf);
 
+	tsk_ctx->personality = hh->personality;
+
 	/* FIXME: restore remaining relevant task_struct fields */
  out:
 	cr_hbuf_put(ctx, sizeof(*hh));
@@ -314,12 +321,22 @@ static int cr_read_namespaces(struct cr_ctx *ctx)
 	return ret;
 }
 
+int cr_task_cleanup(struct cr_ctx *ctx, struct cr_task_ctx *tsk_ctx)
+{
+	current->personality = tsk_ctx->personality;
+
+	return 0;
+}
+
 /* read the entire state of the current task */
 int cr_read_task(struct cr_ctx *ctx)
 {
 	int ret;
+	struct cr_task_ctx tsk_ctx;
+
+	memset(&tsk_ctx, 0, sizeof(tsk_ctx));
 
-	ret = cr_read_task_struct(ctx);
+	ret = cr_read_task_struct(ctx, &tsk_ctx);
 	cr_debug("ret %d\n", ret);
 	if (ret < 0)
 		goto out;
@@ -341,6 +358,10 @@ int cr_read_task(struct cr_ctx *ctx)
 		goto out;
 	ret = cr_read_cpu(ctx);
 	cr_debug("cpu: ret %d\n", ret);
+	if (ret < 0)
+		goto out;
+	ret = cr_task_cleanup(ctx, &tsk_ctx);
+	cr_debug("cleanup: ret %d\n", ret);
  out:
 	return ret;
 }
diff --git a/include/linux/checkpoint_hdr.h b/include/linux/checkpoint_hdr.h
index 92b0336..a3f0b7e 100644
--- a/include/linux/checkpoint_hdr.h
+++ b/include/linux/checkpoint_hdr.h
@@ -127,6 +127,8 @@ struct cr_hdr_task {
 	__u32 exit_code;
 	__u32 exit_signal;
 
+	__u32 personality;
+
 	__u32 task_comm_len;
 } __attribute__((aligned(8)));
 
-- 
1.6.1

_______________________________________________
Containers mailing list
Containers at lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/containers




More information about the Devel mailing list