Commit c378f790 authored by Pavel Emelyanov's avatar Pavel Emelyanov

fs: Restore root

First of all, this should be done strictly after we've stopped accessing
files by their paths, even absolute. This place is right before going
into restorer.

And the second thing is that we want to re-use the open_fd_by_id engine,
since it handles various tricky cases of open-file-by-path. And since
there's no such thing as fchroot(int fd), we emulate it using the
/proc/self/fd/ links.
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 75b1d4a1
...@@ -715,9 +715,6 @@ static int restore_one_alive_task(int pid, CoreEntry *core) ...@@ -715,9 +715,6 @@ static int restore_one_alive_task(int pid, CoreEntry *core)
if (prepare_fds(current)) if (prepare_fds(current))
return -1; return -1;
if (prepare_fs(pid))
return -1;
if (prepare_file_locks(pid)) if (prepare_file_locks(pid))
return -1; return -1;
...@@ -2563,6 +2560,14 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core) ...@@ -2563,6 +2560,14 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
task_args->clone_restore_fn = (void *)restore_thread_exec_start; task_args->clone_restore_fn = (void *)restore_thread_exec_start;
task_args->thread_args = thread_args; task_args->thread_args = thread_args;
/*
* Make root and cwd restore _that_ late not to break any
* attempts to open files by paths above (e.g. /proc).
*/
if (prepare_fs(pid))
goto err;
close_image_dir(); close_image_dir();
__gcov_flush(); __gcov_flush();
......
...@@ -938,6 +938,20 @@ out: ...@@ -938,6 +938,20 @@ out:
return ret; return ret;
} }
static int fchroot(int fd)
{
char fd_path[32];
/*
* There's no such thing in syscalls. We can emulate
* it using the /proc/self/fd/ :)
*/
sprintf(fd_path, "/proc/self/fd/%d", fd);
pr_debug("Going to chroot into %s\n", fd_path);
return chroot(fd_path);
}
int prepare_fs(int pid) int prepare_fs(int pid)
{ {
int ifd, dd, ret = -1; int ifd, dd, ret = -1;
...@@ -950,6 +964,10 @@ int prepare_fs(int pid) ...@@ -950,6 +964,10 @@ int prepare_fs(int pid)
if (pb_read_one(ifd, &fe, PB_FS) < 0) if (pb_read_one(ifd, &fe, PB_FS) < 0)
goto out_i; goto out_i;
/*
* Restore CWD
*/
dd = open_reg_by_id(fe->cwd_id); dd = open_reg_by_id(fe->cwd_id);
if (dd < 0) { if (dd < 0) {
pr_err("Can't open cwd %#x\n", fe->cwd_id); pr_err("Can't open cwd %#x\n", fe->cwd_id);
...@@ -964,14 +982,22 @@ int prepare_fs(int pid) ...@@ -964,14 +982,22 @@ int prepare_fs(int pid)
} }
/* /*
* FIXME: restore task's root. Don't want to do it now, since * Restore root
* it's not yet clean how we're going to resolve tasks' paths
* relative to the dumper/restorer and all this logic is likely
* to be hidden in a couple of calls (open_fe_fd is one od them)
* but for chroot there's no fchroot call, we have to chroot
* by path thus exposing this (yet unclean) logic here.
*/ */
dd = open_reg_by_id(fe->root_id);
if (dd < 0) {
pr_err("Can't open root %#x\n", fe->root_id);
goto err;
}
ret = fchroot(dd);
close(dd);
if (ret < 0) {
pr_perror("Can't change root");
goto err;
}
if (fe->has_umask) { if (fe->has_umask) {
pr_info("Restoring umask to %o\n", fe->umask); pr_info("Restoring umask to %o\n", fe->umask);
umask(fe->umask); umask(fe->umask);
......
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