[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