From bfdbb7089ab9bdc458340ac8353ee181393a2609 Mon Sep 17 00:00:00 2001
From: Bob Lantz <rlantz@cs.stanford.edu>
Date: Tue, 26 Aug 2014 14:08:28 -0700
Subject: [PATCH] Fall back to chroot() if setns() fails for mnt namespace

fixes #347
---
 mnexec.c | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/mnexec.c b/mnexec.c
index c7103d46..7f17494d 100644
--- a/mnexec.c
+++ b/mnexec.c
@@ -140,9 +140,9 @@ int main(int argc, char *argv[])
             fflush(stdout);
             break;
         case 'a':
-            /* Attach to pid's network namespace and mount namespace*/
+            /* Attach to pid's network namespace and mount namespace */
             pid = atoi(optarg);
-            sprintf(path, "/proc/%d/ns/net", pid );
+            sprintf(path, "/proc/%d/ns/net", pid);
             nsid = open(path, O_RDONLY);
             if (nsid < 0) {
                 perror(path);
@@ -152,15 +152,16 @@ int main(int argc, char *argv[])
                 perror("setns");
                 return 1;
             }
-            sprintf(path, "/proc/%d/ns/mnt", pid );
+            /* Plan A: call setns() to attach to mount namespace */
+            sprintf(path, "/proc/%d/ns/mnt", pid);
             nsid = open(path, O_RDONLY);
-            if (nsid < 0) {
-                perror(path);
-                return 1;
-            }
-            if (setns(nsid, 0) != 0) {
-                perror("setns");
-                return 1;
+            if (nsid < 0 || setns(nsid, 0) != 0) {
+                /* Plan B: chroot into pid's root file system */
+                sprintf(path, "/proc/%d/root", pid);
+                if (chroot(path) < 0) {
+                    perror(path);
+                    return 1;
+                }
             }
             break;
         case 'g':
-- 
GitLab