Commit 701f8837 authored by Pavel Emelyanov's avatar Pavel Emelyanov

restore: Do fchroot() via proc helpers

There's no such thing as fchroot() in Linux, but we need to do
chroot() into existing file descriptor. Before this patch we did
this by chroot()-ing into /proc/self/fd/$fd. W/o proc mounted it's
no longer possible, so do this like

fchdir(proc_service_fd);
chroot("./self/fd/$root_fd");
fchdir($cwd_fd);

Thanks to Andrey Vagin for this trick ;)
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
Acked-by: 's avatarAndrew Vagin <avagin@parallels.com>
parent 3659d60a
...@@ -997,13 +997,23 @@ out: ...@@ -997,13 +997,23 @@ out:
static int fchroot(int fd) static int fchroot(int fd)
{ {
char fd_path[PSFDS]; char fd_path[PSFDS];
int proc;
/* /*
* There's no such thing in syscalls. We can emulate * There's no such thing in syscalls. We can emulate
* it using the /proc/self/fd/ :) * it using the /proc/self/fd/ :)
*
* But since there might be no /proc mount in our mount
* namespace, we will have to ... workaround it.
*/ */
sprintf(fd_path, "/proc/self/fd/%d", fd); proc = get_service_fd(PROC_FD_OFF);
if (fchdir(proc) < 0) {
pr_perror("Can't chdir to proc");
return -1;
}
sprintf(fd_path, "./self/fd/%d", fd);
pr_debug("Going to chroot into %s\n", fd_path); pr_debug("Going to chroot into %s\n", fd_path);
return chroot(fd_path); return chroot(fd_path);
} }
...@@ -1021,36 +1031,36 @@ int prepare_fs(int pid) ...@@ -1021,36 +1031,36 @@ int prepare_fs(int pid)
goto out_i; goto out_i;
/* /*
* Restore CWD * Restore root
*/ */
dd = open_reg_by_id(fe->cwd_id); dd = open_reg_by_id(fe->root_id);
if (dd < 0) { if (dd < 0) {
pr_err("Can't open cwd %#x\n", fe->cwd_id); pr_err("Can't open root %#x\n", fe->root_id);
goto err; goto err;
} }
ret = fchdir(dd); ret = fchroot(dd);
close(dd); close(dd);
if (ret < 0) { if (ret < 0) {
pr_perror("Can't change cwd"); pr_perror("Can't change root");
goto err; goto err;
} }
/* /*
* Restore root * Restore CWD
*/ */
dd = open_reg_by_id(fe->root_id); dd = open_reg_by_id(fe->cwd_id);
if (dd < 0) { if (dd < 0) {
pr_err("Can't open root %#x\n", fe->root_id); pr_err("Can't open cwd %#x\n", fe->cwd_id);
goto err; goto err;
} }
ret = fchroot(dd); ret = fchdir(dd);
close(dd); close(dd);
if (ret < 0) { if (ret < 0) {
pr_perror("Can't change root"); pr_perror("Can't change cwd");
goto err; goto err;
} }
......
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