Commit 2b9d87fe authored by Pavel Emelyanov's avatar Pavel Emelyanov

rst: Fix creds vs threads restoration

Writing to last_pid sysctl is CAP_SYS_ADMIN potected. Thus restoring
creds before it won't work in all the cases.

Fix this by making all threads restore creds themselves, and the
thread group leader -- after all of them.
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
Acked-by: 's avatarAndrey Vagin <avagin@parallels.com>
parent 762f493b
...@@ -1495,7 +1495,7 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core, struct list_head *tgt_v ...@@ -1495,7 +1495,7 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core, struct list_head *tgt_v
if (ret < 0) if (ret < 0)
goto err; goto err;
mutex_init(&task_args->t._rst_lock); mutex_init(&task_args->rst_lock);
/* /*
* Now prepare run-time data for threads restore. * Now prepare run-time data for threads restore.
...@@ -1537,7 +1537,7 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core, struct list_head *tgt_v ...@@ -1537,7 +1537,7 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core, struct list_head *tgt_v
goto err; goto err;
} }
thread_args[i].rst_lock = &task_args->t._rst_lock; thread_args[i].ta = task_args;
thread_args[i].gpregs = *core->thread_info->gpregs; thread_args[i].gpregs = *core->thread_info->gpregs;
thread_args[i].clear_tid_addr = core->thread_info->clear_tid_addr; thread_args[i].clear_tid_addr = core->thread_info->clear_tid_addr;
......
...@@ -62,6 +62,8 @@ struct rst_sched_param { ...@@ -62,6 +62,8 @@ struct rst_sched_param {
int prio; int prio;
}; };
struct task_restore_core_args;
/* Make sure it's pow2 in size */ /* Make sure it's pow2 in size */
struct thread_restore_args { struct thread_restore_args {
struct restore_mem_zone mem_zone; struct restore_mem_zone mem_zone;
...@@ -76,10 +78,7 @@ struct thread_restore_args { ...@@ -76,10 +78,7 @@ struct thread_restore_args {
struct rst_sched_param sp; struct rst_sched_param sp;
union { struct task_restore_core_args *ta;
mutex_t _rst_lock;
mutex_t *rst_lock;
};
} __aligned(sizeof(long)); } __aligned(sizeof(long));
struct task_restore_core_args { struct task_restore_core_args {
...@@ -90,6 +89,8 @@ struct task_restore_core_args { ...@@ -90,6 +89,8 @@ struct task_restore_core_args {
int logfd; int logfd;
unsigned int loglevel; unsigned int loglevel;
mutex_t rst_lock;
/* threads restoration */ /* threads restoration */
int nr_threads; /* number of threads */ int nr_threads; /* number of threads */
thread_restore_fcall_t clone_restore_fn; /* helper address for clone() call */ thread_restore_fcall_t clone_restore_fn; /* helper address for clone() call */
......
...@@ -224,7 +224,9 @@ long __export_restore_thread(struct thread_restore_args *args) ...@@ -224,7 +224,9 @@ long __export_restore_thread(struct thread_restore_args *args)
if (restore_thread_common(rt_sigframe, args)) if (restore_thread_common(rt_sigframe, args))
goto core_restore_end; goto core_restore_end;
mutex_unlock(args->rst_lock); mutex_unlock(&args->ta->rst_lock);
restore_creds(&args->ta->creds);
futex_dec_and_wake(&task_entries->nr_in_progress); futex_dec_and_wake(&task_entries->nr_in_progress);
...@@ -529,14 +531,6 @@ long __export_restore_task(struct task_restore_core_args *args) ...@@ -529,14 +531,6 @@ long __export_restore_task(struct task_restore_core_args *args)
goto core_restore_end; goto core_restore_end;
} }
/*
* last-pid is CAP_SYS_ADMIN protected, thus restore creds
* _after_ opening that file, but before fork to make threads
* inherit them properly
*/
restore_creds(&args->creds);
ret = sys_flock(fd, LOCK_EX); ret = sys_flock(fd, LOCK_EX);
if (ret) { if (ret) {
pr_err("Can't lock last_pid %d\n", fd); pr_err("Can't lock last_pid %d\n", fd);
...@@ -550,7 +544,7 @@ long __export_restore_task(struct task_restore_core_args *args) ...@@ -550,7 +544,7 @@ long __export_restore_task(struct task_restore_core_args *args)
if (thread_args[i].pid == args->t.pid) if (thread_args[i].pid == args->t.pid)
continue; continue;
mutex_lock(&args->t._rst_lock); mutex_lock(&args->rst_lock);
new_sp = new_sp =
RESTORE_ALIGN_STACK((long)thread_args[i].mem_zone.stack, RESTORE_ALIGN_STACK((long)thread_args[i].mem_zone.stack,
...@@ -613,8 +607,14 @@ long __export_restore_task(struct task_restore_core_args *args) ...@@ -613,8 +607,14 @@ long __export_restore_task(struct task_restore_core_args *args)
} }
sys_close(fd); sys_close(fd);
} else }
restore_creds(&args->creds);
/*
* Writing to last-pid is CAP_SYS_ADMIN protected, thus restore
* creds _after_ all threads creation.
*/
restore_creds(&args->creds);
futex_dec_and_wake(&args->task_entries->nr_in_progress); futex_dec_and_wake(&args->task_entries->nr_in_progress);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment