[CRIU] [PATCH] rst: move lsm memory allocations before rst_mem_lock()

Tycho Andersen tycho.andersen at canonical.com
Wed Jul 15 09:35:06 PDT 2015


8ffbe754bd9 moved the rst_mem_lock() call, but didn't move the
corresponding LSM allocations, so we do that here.

One unfortunate thing is that we have to split this into two steps: first
we have to read the creds to figure out exactly how much memory to
allocate for the lsm string. Since prepare_creds() wants to write directly
to the task_restore_args struct and that can't be allocated until after we
lock the restore memory, we break it up into two steps.

Signed-off-by: Tycho Andersen <tycho.andersen at canonical.com>
---
 cr-restore.c | 94 +++++++++++++++++++++++++++++++++---------------------------
 1 file changed, 51 insertions(+), 43 deletions(-)

diff --git a/cr-restore.c b/cr-restore.c
index 947985f..a37a032 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -2266,31 +2266,42 @@ static inline int verify_cap_size(CredsEntry *ce)
 		(ce->n_cap_prm == CR_CAP_SIZE) && (ce->n_cap_bnd == CR_CAP_SIZE));
 }
 
-static int prepare_creds(int pid, struct task_restore_args *args, char **lsm_profile)
+static CredsEntry *read_creds(int pid)
 {
 	int ret;
 	struct cr_img *img;
-	CredsEntry *ce;
+	CredsEntry *ce = NULL;
 
 	img = open_image(CR_FD_CREDS, O_RSTR, pid);
 	if (!img)
-		return -1;
+		return NULL;
 
 	ret = pb_read_one(img, &ce, PB_CREDS);
 	close_image(img);
 
-	if (ret < 0)
-		return ret;
+	if (ret < 0) {
+		creds_entry__free_unpacked(ce, NULL);
+		return NULL;
+	}
+
 	if (!verify_cap_size(ce)) {
 		pr_err("Caps size mismatch %d %d %d %d\n",
 		       (int)ce->n_cap_inh, (int)ce->n_cap_eff,
 		       (int)ce->n_cap_prm, (int)ce->n_cap_bnd);
-		return -1;
+		creds_entry__free_unpacked(ce, NULL);
+		return NULL;
 	}
 
-	if (!may_restore(ce))
-		return -1;
+	if (!may_restore(ce)) {
+		creds_entry__free_unpacked(ce, NULL);
+		return NULL;
+	}
+
+	return ce;
+}
 
+static int prepare_creds(CredsEntry *ce, struct task_restore_args *args)
+{
 	args->creds = *ce;
 	args->creds.cap_inh = args->cap_inh;
 	memcpy(args->cap_inh, ce->cap_inh, sizeof(args->cap_inh));
@@ -2313,17 +2324,6 @@ static int prepare_creds(int pid, struct task_restore_args *args, char **lsm_pro
 		return -1;
 	}
 
-	*lsm_profile = NULL;
-
-	if (ce->lsm_profile) {
-		if (validate_lsm(ce) < 0)
-			return -1;
-
-		*lsm_profile = xstrdup(ce->lsm_profile);
-		if (!*lsm_profile)
-			return -1;
-	}
-
 	creds_entry__free_unpacked(ce, NULL);
 
 	args->cap_last_cap = kdat.last_cap;
@@ -2664,6 +2664,8 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
 	struct vm_area_list *vmas = &rsti(current)->vmas;
 	int i;
 
+	CredsEntry *creds;
+
 	pr_info("Restore via sigreturn\n");
 
 	/* pr_info_vma_list(&self_vma_list); */
@@ -2735,6 +2737,35 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
 	if (ret < 0)
 		goto err;
 
+	creds = read_creds(pid);
+	if (!creds)
+		goto err;
+
+	if (creds->lsm_profile) {
+		char *rendered;
+		int ret;
+
+		if (validate_lsm(creds) < 0)
+			return -1;
+
+		ret = render_lsm_profile(creds->lsm_profile, &rendered);
+		if (ret < 0) {
+			goto err_nv;
+		}
+
+		lsm_pos = rst_mem_cpos(RM_PRIVATE);
+		lsm_profile_len = strlen(rendered);
+		lsm = rst_mem_alloc(lsm_profile_len + 1, RM_PRIVATE);
+		if (!lsm) {
+			xfree(rendered);
+			goto err_nv;
+		}
+
+		strncpy(lsm, rendered, lsm_profile_len);
+		xfree(rendered);
+
+	}
+
 	rst_mem_size = rst_mem_lock();
 	restore_bootstrap_len = restorer_len + args_len + rst_mem_size;
 
@@ -2810,33 +2841,10 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
 		goto err;
 	}
 
-	ret = prepare_creds(pid, task_args, &lsm);
+	ret = prepare_creds(creds, task_args);
 	if (ret < 0)
 		goto err;
 
-	if (lsm) {
-		char *rendered;
-		int ret;
-
-		ret = render_lsm_profile(lsm, &rendered);
-		xfree(lsm);
-		if (ret < 0) {
-			goto err_nv;
-		}
-
-		lsm_pos = rst_mem_cpos(RM_PRIVATE);
-		lsm_profile_len = strlen(rendered);
-		lsm = rst_mem_alloc(lsm_profile_len + 1, RM_PRIVATE);
-		if (!lsm) {
-			xfree(rendered);
-			goto err_nv;
-		}
-
-		strncpy(lsm, rendered, lsm_profile_len);
-		xfree(rendered);
-
-	}
-
 	/*
 	 * Get a reference to shared memory area which is
 	 * used to signal if shmem restoration complete
-- 
2.1.4



More information about the CRIU mailing list