Karel Zak <kzak@xxxxxxxxxx> writes: (this was commited as c84f2590dfdb8570beeb731e0105f8fe597443d1) > +static void bind_ns_files_from_child(pid_t *child) > +{ > + pid_t ppid = getpid(); > + ino_t ino = get_mnt_ino(ppid); > + > + *child = fork(); > + > + switch(*child) { > + case -1: > + err(EXIT_FAILURE, _("fork failed")); > + case 0: /* child */ > + do { > + /* wait until parent unshare() */ > + ino_t new_ino = get_mnt_ino(ppid); > + if (ino != new_ino) > + break; > + } while (1); Racing? Suppose, parent died (e.g. unshare(2) failed), (parent) process was reaped, new (unrelated) process was created with same pid, as a result this function will bind namespaces from wrong process. (That said, pretty unlikely, and no idea how to properly fix it). > + bind_ns_files(ppid); > + exit(EXIT_SUCCESS); > + break; > + default: /* parent */ > + break; > + } > +} > + > static void usage(int status) > { > FILE *out = status == EXIT_SUCCESS ? stdout : stderr; > @@ -248,6 +289,8 @@ int main(int argc, char *argv[]) > int unshare_flags = 0; > int c, forkit = 0, maproot = 0; > const char *procmnt = NULL; > + pid_t pid = 0; > + int status; > unsigned long propagation = UNSHARE_PROPAGATION_DEFAULT; > uid_t real_euid = geteuid(); > gid_t real_egid = getegid();; > @@ -316,12 +359,35 @@ int main(int argc, char *argv[]) > } > } > > + if (npersists && (unshare_flags & CLONE_NEWNS)) > + bind_ns_files_from_child(&pid); > + > if (-1 == unshare(unshare_flags)) > err(EXIT_FAILURE, _("unshare failed")); > > + if (npersists) { > + if (pid && (unshare_flags & CLONE_NEWNS)) { > + /* wait for bind_ns_files_from_child() */ > + int rc; > + > + do { > + rc = waitpid(pid, &status, 0); > + if (rc < 0) { > + if (errno == EINTR) > + continue; > + err(EXIT_FAILURE, _("waitpid failed")); > + } > + if (WIFEXITED(status) && > + WEXITSTATUS(status) != EXIT_SUCCESS) > + return WEXITSTATUS(status); > + } while (rc < 0); > + } else > + /* simple way, just bind */ > + bind_ns_files(getpid()); > + } > + > if (forkit) { > - int status; > - pid_t pid = fork(); > + pid = fork(); > > switch(pid) { > case -1: > @@ -339,8 +405,6 @@ int main(int argc, char *argv[]) > } > } > > - if (npersists) > - bind_ns_files(getpid()); > > if (maproot) { > if (setgrpcmd == SETGROUPS_ALLOW) -- To unsubscribe from this list: send the line "unsubscribe util-linux" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html