guix-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

01/07: container: Allow 'container-excursion' to the same namespaces.


From: Ludovic Courtès
Subject: 01/07: container: Allow 'container-excursion' to the same namespaces.
Date: Wed, 19 Oct 2016 13:55:00 +0000 (UTC)

civodul pushed a commit to branch master
in repository guix.

commit 7fee5b53973fb4fe049aa0bc5db58093727bdf30
Author: Ludovic Courtès <address@hidden>
Date:   Tue Oct 18 23:22:03 2016 +0200

    container: Allow 'container-excursion' to the same namespaces.
    
    Before that, 'container-excursion' would call 'setns' even when the
    target namespace is the one the caller is already in, which would fail.
    
    * gnu/build/linux-container.scm (container-excursion): Introduce
    'source' and 'target'.  Compare the result of 'readlink' on these
    instead of comparing file descriptors to decide whether to call
    'setns'.
    * tests/containers.scm ("container-excursion, same namespace"): New test.
---
 gnu/build/linux-container.scm |   20 +++++++++++---------
 tests/containers.scm          |    9 +++++++++
 2 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/gnu/build/linux-container.scm b/gnu/build/linux-container.scm
index 91996d0..3fccc9a 100644
--- a/gnu/build/linux-container.scm
+++ b/gnu/build/linux-container.scm
@@ -291,15 +291,17 @@ return the exit status."
      (call-with-clean-exit
       (lambda ()
         (for-each (lambda (ns)
-                    (call-with-input-file (namespace-file (getpid) ns)
-                      (lambda (current-ns-port)
-                        (call-with-input-file (namespace-file pid ns)
-                          (lambda (new-ns-port)
-                            ;; Joining the namespace that the process
-                            ;; already belongs to would throw an error.
-                            (unless (= (port->fdes current-ns-port)
-                                       (port->fdes new-ns-port))
-                              (setns (port->fdes new-ns-port) 0)))))))
+                    (let ((source (namespace-file (getpid) ns))
+                          (target (namespace-file pid ns)))
+                      ;; Joining the namespace that the process already
+                      ;; belongs to would throw an error so avoid that.
+                      ;; XXX: This /proc interface leads to TOCTTOU.
+                      (unless (string=? (readlink source) (readlink target))
+                        (call-with-input-file source
+                          (lambda (current-ns-port)
+                            (call-with-input-file target
+                              (lambda (new-ns-port)
+                                (setns (fileno new-ns-port) 0))))))))
                   ;; It's important that the user namespace is joined first,
                   ;; so that the user will have the privileges to join the
                   ;; other namespaces.  Furthermore, it's important that the
diff --git a/tests/containers.scm b/tests/containers.scm
index bbcff3f..698bef3 100644
--- a/tests/containers.scm
+++ b/tests/containers.scm
@@ -162,4 +162,13 @@
           (waitpid pid)
           (zero? result)))))))
 
+(skip-if-unsupported)
+(test-equal "container-excursion, same namespaces"
+  42
+  ;; The parent and child are in the same namespaces.  'container-excursion'
+  ;; should notice that and avoid calling 'setns' since that would fail.
+  (container-excursion (getpid)
+    (lambda ()
+      (primitive-exit 42))))
+
 (test-end)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]