[CRIU] [PATCH 3/4] lsm: restore lsm bits per tid instead of per pid
Tycho Andersen
tycho.andersen at canonical.com
Mon Jun 15 14:50:36 PDT 2015
This is a little tricky, since the threads are forked in the restorer blob, we
can't open their attr/curent files to pass into the restorer blob. So, we pass
in an fd for /proc that the restorer blob can use to access the attr/current
files once they exist.
N.B. this is still incorrect in that it restores the same credentials for all
threads in the group; however, it matches the behavior of the current creds
restore code, which also restores the same creds for all threads in the group.
v2: use simple_sprintf() instead of pie_strcat()
Signed-off-by: Tycho Andersen <tycho.andersen at canonical.com>
---
cr-restore.c | 24 ++++++++++----------
include/restorer.h | 9 +++++---
pie/restorer.c | 65 +++++++++++++++++++++++++++++++-----------------------
3 files changed, 56 insertions(+), 42 deletions(-)
diff --git a/cr-restore.c b/cr-restore.c
index fbf8002..af12c0b 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -2836,6 +2836,14 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
strncpy(lsm, rendered, lsm_profile_len);
xfree(rendered);
+
+ task_args->proc_fd = dup(get_service_fd(PROC_FD_OFF));
+ if (task_args->proc_fd < 0) {
+ pr_perror("can't dup proc fd");
+ goto err;
+ }
+ } else {
+ task_args->proc_fd = -1;
}
/*
@@ -2881,18 +2889,10 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
#undef remap_array
- if (lsm) {
- task_args->proc_attr_current = open_proc_rw(PROC_SELF, "attr/current");
- if (task_args->proc_attr_current < 0) {
- pr_perror("Can't open attr/current");
- goto err;
- }
-
- task_args->lsm_profile = rst_mem_remap_ptr(lsm_pos, RM_PRIVATE);
- task_args->lsm_profile_len = lsm_profile_len;
- } else {
- task_args->lsm_profile = NULL;
- }
+ if (lsm)
+ task_args->creds.lsm_profile = rst_mem_remap_ptr(lsm_pos, RM_PRIVATE);
+ else
+ task_args->creds.lsm_profile = NULL;
/*
* Arguments for task restoration.
diff --git a/include/restorer.h b/include/restorer.h
index 54f4166..c82557c 100644
--- a/include/restorer.h
+++ b/include/restorer.h
@@ -160,9 +160,12 @@ struct task_restore_args {
int fd_last_pid; /* sys.ns_last_pid for threads rst */
- int proc_attr_current;
- char *lsm_profile;
- int lsm_profile_len;
+ /*
+ * proc_fd is a handle to /proc that the restorer blob can use to open
+ * files there, because some of them can't be opened before the
+ * restorer blob is called.
+ */
+ int proc_fd;
#ifdef CONFIG_VDSO
unsigned long vdso_rt_size;
diff --git a/pie/restorer.c b/pie/restorer.c
index c11c9c8..aff49bc 100644
--- a/pie/restorer.c
+++ b/pie/restorer.c
@@ -95,7 +95,39 @@ static void sigchld_handler(int signal, siginfo_t *siginfo, void *data)
sys_exit_group(1);
}
-static int restore_creds(CredsEntry *ce)
+static int lsm_set_label(char *label, int procfd)
+{
+ int ret = -1, len, lsmfd;
+ char path[LOG_SIMPLE_CHUNK];
+
+ if (!label)
+ return 0;
+
+ pr_info("restoring lsm profile %s\n", label);
+
+ simple_sprintf(path, "self/task/%ld/attr/current", sys_gettid());
+
+ lsmfd = sys_openat(procfd, path, O_WRONLY, 0);
+ sys_close(procfd);
+ if (lsmfd < 0) {
+ pr_err("failed openat %d\n", lsmfd);
+ return -1;
+ }
+
+ for (len = 0; label[len]; len++)
+ ;
+
+ ret = sys_write(lsmfd, label, len);
+ sys_close(lsmfd);
+ if (ret < 0) {
+ pr_err("can't write lsm profile %d\n", ret);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int restore_creds(CredsEntry *ce, int procfd)
{
int b, i, ret;
struct cap_header hdr;
@@ -200,6 +232,9 @@ static int restore_creds(CredsEntry *ce)
return -1;
}
+ if (lsm_set_label(ce->lsm_profile, procfd) < 0)
+ return -1;
+
return 0;
}
@@ -366,7 +401,7 @@ long __export_restore_thread(struct thread_restore_args *args)
if (restore_thread_common(rt_sigframe, args))
goto core_restore_end;
- ret = restore_creds(&args->ta->creds);
+ ret = restore_creds(&args->ta->creds, args->ta->proc_fd);
if (ret)
goto core_restore_end;
@@ -738,25 +773,6 @@ static int wait_helpers(struct task_restore_args *task_args)
return 0;
}
-static int lsm_set_label(struct task_restore_args *args)
-{
- int ret = -1;
-
- if (!args->lsm_profile)
- return 0;
-
- pr_info("restoring lsm profile %s\n", args->lsm_profile);
-
- ret = sys_write(args->proc_attr_current, args->lsm_profile, args->lsm_profile_len);
- sys_close(args->proc_attr_current);
- if (ret < 0) {
- pr_err("can't write lsm profile\n");
- return -1;
- }
-
- return ret;
-}
-
/*
* The main routine to restore task via sigreturn.
* This one is very special, we never return there
@@ -1171,15 +1187,10 @@ long __export_restore_task(struct task_restore_args *args)
* thus restore* creds _after_ all of the above.
*/
- ret = restore_creds(&args->creds);
+ ret = restore_creds(&args->creds, args->proc_fd);
ret = ret || restore_dumpable_flag(&args->mm);
ret = ret || restore_pdeath_sig(args->t);
- if (lsm_set_label(args) < 0) {
- pr_err("lsm_set_label failed\n");
- goto core_restore_end;
- }
-
futex_set_and_wake(&thread_inprogress, args->nr_threads);
restore_finish_stage(CR_STATE_RESTORE_CREDS);
--
2.1.4
More information about the CRIU
mailing list