Commit 70171818 authored by Andrew Vagin's avatar Andrew Vagin Committed by Pavel Emelyanov

mount: don't inherit mount namespace descriptors to each process

close_olds_fds() knows nothing about more than one set of service file
descriptros, so it's better to call it before forking children as it was
bedore 9d60724e ("restore: restore mntns before creating private vma-s")

The root task restores all processes and pin them with file descriptors,
then a task restores a mount namespace by opening the file descriptor of
the root task via /proc/pid/fd/X.

Reported-by: Mr Jenkins
Signed-off-by: 's avatarAndrew Vagin <avagin@virtuozzo.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 9d60724e
...@@ -1509,9 +1509,6 @@ static int restore_task_with_children(void *_arg) ...@@ -1509,9 +1509,6 @@ static int restore_task_with_children(void *_arg)
if (restore_finish_stage(CR_STATE_RESTORE_NS) < 0) if (restore_finish_stage(CR_STATE_RESTORE_NS) < 0)
goto err; goto err;
if (prepare_namespace(current, ca->clone_flags))
goto err_fini_mnt;
/* /*
* We need non /proc proc mount for restoring pid and mount * We need non /proc proc mount for restoring pid and mount
* namespaces and do not care for the rest of the cases. * namespaces and do not care for the rest of the cases.
...@@ -1520,6 +1517,9 @@ static int restore_task_with_children(void *_arg) ...@@ -1520,6 +1517,9 @@ static int restore_task_with_children(void *_arg)
if (mount_proc()) if (mount_proc())
goto err_fini_mnt; goto err_fini_mnt;
if (prepare_namespace(current, ca->clone_flags))
goto err_fini_mnt;
if (root_prepare_shared()) if (root_prepare_shared())
goto err_fini_mnt; goto err_fini_mnt;
...@@ -1567,8 +1567,12 @@ static int restore_task_with_children(void *_arg) ...@@ -1567,8 +1567,12 @@ static int restore_task_with_children(void *_arg)
if (restore_finish_stage(CR_STATE_FORKING) < 0) if (restore_finish_stage(CR_STATE_FORKING) < 0)
goto err_fini_mnt; goto err_fini_mnt;
if (current->parent == NULL && depopulate_roots_yard()) if (current->parent == NULL) {
goto err; if (depopulate_roots_yard())
goto err;
fini_restore_mntns();
}
if (restore_one_task(current->pid.virt, ca->core)) if (restore_one_task(current->pid.virt, ca->core))
goto err; goto err;
......
...@@ -114,6 +114,7 @@ extern bool phys_stat_dev_match(dev_t st_dev, dev_t phys_dev, ...@@ -114,6 +114,7 @@ extern bool phys_stat_dev_match(dev_t st_dev, dev_t phys_dev,
struct ns_id *, const char *path); struct ns_id *, const char *path);
extern int restore_task_mnt_ns(struct pstree_item *current); extern int restore_task_mnt_ns(struct pstree_item *current);
extern void fini_restore_mntns(void);
extern int depopulate_roots_yard(void); extern int depopulate_roots_yard(void);
extern int rst_get_mnt_root(int mnt_id, char *path, int plen); extern int rst_get_mnt_root(int mnt_id, char *path, int plen);
......
...@@ -2590,10 +2590,18 @@ int mntns_maybe_create_roots(void) ...@@ -2590,10 +2590,18 @@ int mntns_maybe_create_roots(void)
static int do_restore_task_mnt_ns(struct ns_id *nsid, struct pstree_item *current) static int do_restore_task_mnt_ns(struct ns_id *nsid, struct pstree_item *current)
{ {
if (setns(nsid->mnt.ns_fd, CLONE_NEWNS)) { int fd;
fd = open_proc(root_item->pid.virt, "fd/%d", nsid->mnt.ns_fd);
if (fd < 0)
return -1;
if (setns(fd, CLONE_NEWNS)) {
pr_perror("Can't restore mntns"); pr_perror("Can't restore mntns");
close(fd);
return -1; return -1;
} }
close(fd);
if (nsid->ns_pid == current->pid.virt) if (nsid->ns_pid == current->pid.virt)
futex_set_and_wake(&nsid->ns_created, 1); futex_set_and_wake(&nsid->ns_created, 1);
...@@ -2634,6 +2642,19 @@ int restore_task_mnt_ns(struct pstree_item *current) ...@@ -2634,6 +2642,19 @@ int restore_task_mnt_ns(struct pstree_item *current)
return 0; return 0;
} }
void fini_restore_mntns(void)
{
struct ns_id *nsid;
for (nsid = ns_ids; nsid != NULL; nsid = nsid->next) {
if (nsid->nd != &mnt_ns_desc)
continue;
if (root_item->ids->mnt_ns_id == nsid->id)
continue;
close(nsid->mnt.ns_fd);
}
}
/* /*
* All nested mount namespaces are restore as sub-trees of the root namespace. * All nested mount namespaces are restore as sub-trees of the root namespace.
*/ */
...@@ -2753,8 +2774,6 @@ int prepare_mnt_ns(void) ...@@ -2753,8 +2774,6 @@ int prepare_mnt_ns(void)
if (old == NULL) if (old == NULL)
return -1; return -1;
close_proc();
if (!opts.root) { if (!opts.root) {
if (chdir("/")) { if (chdir("/")) {
pr_perror("chdir(\"/\") failed"); pr_perror("chdir(\"/\") failed");
......
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