@@ -65,30 +65,29 @@ int main(int argc, char *argv[]) {
6565 usage(argv[0]);
6666 }
6767
68+ // Create skeleton root dir in temp. All dirs will be mounted here.
6869 char template[] = "/tmp/nixXXXXXX";
6970 char *rootdir = mkdtemp(template);
7071 if (!rootdir) {
7172 err_exit("mkdtemp(%s)", template);
7273 }
7374
75+ // determine absolute directory for nix dir
7476 char *nixdir = realpath(argv[1], NULL);
7577 if (!nixdir) {
7678 err_exit("realpath(%s)", argv[1]);
7779 }
7880
81+ // get uid, gid before going to new namespace
7982 uid_t uid = getuid();
8083 gid_t gid = getgid();
8184
85+ // "unshare" into new namespace
8286 if (unshare(CLONE_NEWNS | CLONE_NEWUSER) < 0) {
8387 err_exit("unshare()");
8488 }
8589
86− // bind mount all / stuff into rootdir
87− DIR* d = opendir("/");
88− if (!d) {
89− err_exit("open /");
90− }
91−
90+ // add necessary system stuff to rootdir namespace
9291 add_path("dev", rootdir);
9392 add_path("proc", rootdir);
9493 add_path("sys", rootdir);
@@ -96,13 +95,14 @@ int main(int argc, char *argv[]) {
9695 add_path("tmp", rootdir);
9796 add_path("var", rootdir);
9897
98+ // make sure nixdir exists
9999 struct stat statbuf2;
100100 if (stat(nixdir, &statbuf2) < 0) {
101101 err_exit("stat(%s)", nixdir);
102102 }
103103
104+ // mount /nix to new namespace
104105 char path_buf[PATH_MAX];
105−
106106 snprintf(path_buf, sizeof(path_buf), "%s/nix", rootdir);
107107 mkdir(path_buf, statbuf2.st_mode & ~S_IFMT);
108108 if (mount(nixdir, path_buf, "none", MS_BIND | MS_REC, NULL) < 0) {
@@ -116,29 +116,19 @@ int main(int argc, char *argv[]) {
116116 write(fd_setgroups, "deny", 4);
117117 }
118118
119− char map_buf[1024];
120−
121119 // map the original uid/gid in the new ns
120+ char map_buf[1024];
122121 snprintf(map_buf, sizeof(map_buf), "%d %d 1", uid, uid);
123122 update_map(map_buf, "/proc/self/uid_map");
124−
125123 snprintf(map_buf, sizeof(map_buf), "%d %d 1", gid, gid);
126124 update_map(map_buf, "/proc/self/gid_map");
127125
128− char cwd[PATH_MAX];
129−
130− if (!getcwd(cwd, PATH_MAX)) {
131− err_exit("getcwd()");
132− }
133−
134− chdir("/");
126+ // chroot to rootdir
135127 if (chroot(rootdir) < 0) {
136128 err_exit("chroot(%s)", rootdir);
137129 }
138− chdir(cwd);
139130
140131 // execute the command
141−
142132 execvp(argv[2], argv+2);
143133 err_exit("execvp(%s)", argv[2]);
144134}