When I call the Linux system unshare function (CLONE_NEWNS), it returns 0, indicating success. But it does not seem to work as I expected. In particular, when I add a new mount, such as tmpfs one, it is displayed globally. Therefore, this is actually not a private mount namespace, as expected.
Here is an example program that demonstrates the problem. Compile this and run it in one terminal. Then open another terminal and check if the path shown in the example program is displayed. It should not be, but it is. It behaves as if the fuzzy call did nothing. I expected that from now on any subsequent mounts performed by this program will not be visible to other processes.
#define _GNU_SOURCE #include <sched.h> #include <unistd.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/mount.h> #include <stdlib.h> #include <stdio.h> #define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \ } while (0) int main(int argc, char *argv[]) { // Create a temporary directory at /tmp/unshare mkdir("/tmp/unshare", S_IRWXG); if (unshare(CLONE_NEWNS) == -1) errExit("unshare"); if (mount("none", "/tmp/unshare", "tmpfs", 0, "mode=0700") == -1) errExit("unshare"); FILE* fp = fopen("/tmp/unshare/test", "w"); fprintf(fp, "This file should not be seen by other processes right?\n"); fclose(fp); // Pause printf("Now open another shell. As the root user, verify the file /tmp/unshare/test is not seen\n.Press enter end finish\n"); char c = getchar(); if (umount("/tmp/unshare") == -1) errExit("umount"); }
I must indicate that the mount man page suggests that this should work. In particular, the section labeled "Process Namespaces".
i.e.
A process can obtain a private mount namespace if ... it calls unshare(2) with the CLONE_NEWNS flag, which causes the caller mount namespace to obtain a private copy of the namespace that it was previously sharing with other processes, so that future mounts and unmounts by the caller are invisible to other pro‐ cesses (except child processes that the caller subsequently creates) and vice versa.
If you use the unsshare terminal command, it works. But it also triggers another process. But the man page suggests that when using an unconfirmed system call, there is no need for a fork or cloning. What am I doing wrong here?