mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-07-21 01:06:58 +00:00
lsm: restore lsm bits per tid instead of per pid
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@canonical.com> Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
parent
ea5f35e26f
commit
7083fc370d
3 changed files with 56 additions and 42 deletions
24
cr-restore.c
24
cr-restore.c
|
|
@ -2834,6 +2834,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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -2879,18 +2887,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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue