mnt: use setcwd unconditionally with and w/o clone_newns
authorRobert Swiecki <robert@swiecki.net>
Sun, 25 Aug 2019 09:16:12 +0000 (11:16 +0200)
committerRobert Swiecki <robert@swiecki.net>
Sun, 25 Aug 2019 09:16:12 +0000 (11:16 +0200)
mnt.cc

diff --git a/mnt.cc b/mnt.cc
index 26bd5a881537580492ef8dc5582b6a038be83bc0..a4faac678da000d5d402165acd517bde1f23d907 100644 (file)
--- a/mnt.cc
+++ b/mnt.cc
@@ -337,26 +337,26 @@ static std::unique_ptr<std::string> getDir(nsjconf_t* nsjconf, const char* name)
        return nullptr;
 }
 
-static bool initNsInternal(nsjconf_t* nsjconf) {
+static bool initNoCloneNs(nsjconf_t* nsjconf) {
        /*
         * If CLONE_NEWNS is not used, we would be changing the global mount namespace, so simply
         * use --chroot in this case
         */
-       if (!nsjconf->clone_newns) {
-               if (nsjconf->chroot.empty()) {
-                       return true;
-               }
-               if (chroot(nsjconf->chroot.c_str()) == -1) {
-                       PLOG_E("chroot('%s')", nsjconf->chroot.c_str());
-                       return false;
-               }
-               if (chdir("/") == -1) {
-                       PLOG_E("chdir('/')");
-                       return false;
-               }
+       if (nsjconf->chroot.empty()) {
                return true;
        }
+       if (chroot(nsjconf->chroot.c_str()) == -1) {
+               PLOG_E("chroot('%s')", nsjconf->chroot.c_str());
+               return false;
+       }
+       if (chdir("/") == -1) {
+               PLOG_E("chdir('/')");
+               return false;
+       }
+       return true;
+}
 
+static bool initCloneNs(nsjconf_t* nsjconf) {
        if (chdir("/") == -1) {
                PLOG_E("chdir('/')");
                return false;
@@ -399,11 +399,12 @@ static bool initNsInternal(nsjconf_t* nsjconf) {
                return false;
        }
        /*
-        * This requires some explanation: It's actually possible to pivot_root('/', '/'). After
-        * this operation has been completed, the old root is mounted over the new root, and it's OK
-        * to simply umount('/') now, and to have new_root as '/'. This allows us not care about
-        * providing any special directory for old_root, which is sometimes not easy, given that
-        * e.g. /tmp might not always be present inside new_root
+        * This requires some explanation: It's actually possible to pivot_root('/', '/').
+        * After this operation has been completed, the old root is mounted over the new
+        * root, and it's OK to simply umount('/') now, and to have new_root as '/'. This
+        * allows us not care about providing any special directory for old_root, which is
+        * sometimes not easy, given that e.g. /tmp might not always be present inside
+        * new_root
         */
        if (util::syscall(
                __NR_pivot_root, (uintptr_t)destdir->c_str(), (uintptr_t)destdir->c_str()) == -1) {
@@ -415,10 +416,6 @@ static bool initNsInternal(nsjconf_t* nsjconf) {
                PLOG_E("umount2('/', MNT_DETACH)");
                return false;
        }
-       if (chdir(nsjconf->cwd.c_str()) == -1) {
-               PLOG_E("chdir('%s')", nsjconf->cwd.c_str());
-               return false;
-       }
 
        for (const auto& p : nsjconf->mountpts) {
                if (!remountPt(p) && p.is_mandatory) {
@@ -429,6 +426,24 @@ static bool initNsInternal(nsjconf_t* nsjconf) {
        return true;
 }
 
+static bool initNsInternal(nsjconf_t* nsjconf) {
+       if (nsjconf->clone_newns) {
+               if (!initCloneNs(nsjconf)) {
+                       return false;
+               }
+       } else {
+               if (!initNoCloneNs(nsjconf)) {
+                       return false;
+               }
+       }
+
+       if (chdir(nsjconf->cwd.c_str()) == -1) {
+               PLOG_E("chdir('%s')", nsjconf->cwd.c_str());
+               return false;
+       }
+       return true;
+}
+
 /*
  * With mode MODE_STANDALONE_EXECVE it's required to mount /proc inside a new process,
  * as the current process is still in the original PID namespace (man pid_namespaces)