]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libmount: ensure child hangs around until we persisted namespace
authorChristian Brauner <brauner@kernel.org>
Sun, 8 Jan 2023 12:05:20 +0000 (13:05 +0100)
committerChristian Brauner (Microsoft) <brauner@kernel.org>
Sun, 8 Jan 2023 12:05:20 +0000 (13:05 +0100)
When we create a new namespace in a child process to persist it we need
to ensure that the child hangs around. During exit the child will drop
all references to its namespaces and so by the time we call open we
might already fail to open the namespace. Fix this.

Signed-off-by: Christian Brauner (Microsoft) <brauner@kernel.org>
libmount/src/hook_idmap.c

index 3001e406249f18c4882fc2599b0ef85ab25518a7..7e7c9e742fd2eb4181573fcc751061737d73943d 100644 (file)
@@ -210,10 +210,16 @@ static int get_userns_fd_from_idmap(struct list_head *idmap)
                if (rc < 0)
                        _exit(EXIT_FAILURE);
 
+               /* Let parent know we're ready to have the idmapping written. */
                rc = write_all(sock_fds[0], &c, 1);
                if (rc)
                        _exit(EXIT_FAILURE);
 
+               /* Hang around until the parent has persisted our namespace. */
+               rc = read_all(sock_fds[0], &c, 1);
+               if (rc != 1)
+                       _exit(EXIT_FAILURE);
+
                close(sock_fds[0]);
 
                _exit(EXIT_SUCCESS);
@@ -221,6 +227,7 @@ static int get_userns_fd_from_idmap(struct list_head *idmap)
        close(sock_fds[0]);
        sock_fds[0] = -1;
 
+       /* Wait for child to set up a new namespace. */
        rc = read_all(sock_fds[1], &c, 1);
        if (rc != 1)
                goto err_wait;
@@ -232,6 +239,9 @@ static int get_userns_fd_from_idmap(struct list_head *idmap)
        snprintf(path, sizeof(path), "/proc/%d/ns/user", pid);
        fd_userns = open(path, O_RDONLY | O_CLOEXEC | O_NOCTTY);
 
+       /* Let child know we've persisted its namespace. */
+       (void)write_all(sock_fds[0], &c, 1);
+
 err_wait:
        rc = wait_for_pid(pid);