[go] os/exec: add a mount command when Unshareflags include CLONE_NEWNS

144 views
Skip to first unread message

Ian Lance Taylor (Gerrit)

unread,
Mar 22, 2017, 6:08:55 PM3/22/17
to ron minnich, golang-co...@googlegroups.com

Ian Lance Taylor posted comments on this change.

View Change

Patch set 2:

Can you confirm that `sudo go test os/exec` failed before this CL and works after it?

(1 comment)

To view, visit change 38471. To unsubscribe, visit settings.

Gerrit-Project: go
Gerrit-Branch: master
Gerrit-MessageType: comment
Gerrit-Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
Gerrit-Change-Number: 38471
Gerrit-PatchSet: 2
Gerrit-Owner: ron minnich <rmin...@gmail.com>
Gerrit-CC: Ian Lance Taylor <ia...@golang.org>
Gerrit-Comment-Date: Wed, 22 Mar 2017 22:08:52 +0000
Gerrit-HasComments: Yes

ron minnich (Gerrit)

unread,
Mar 22, 2017, 6:09:21 PM3/22/17
to Ian Lance Taylor, Rob Pike, golang-co...@googlegroups.com

ron minnich has uploaded this change for review.

View Change

os/exec: add a mount command when Unshareflags include CLONE_NEWNS

In some newer Linux distros, the mountflags specified at boot essentially
disable the CLONE_NEWNS flag in unshare(2). This problem is most commonly seen
on systems with systemd, but it can happen anywhere.

Hence, to create a private mount namespace, it is not sufficient to just set
CLONE_NEWS; you have to call mount(2) to change the behavior of namespaces, i.e.
mount("none", "/", NULL, MS_REC|MS_PRIVATE, NULL)

This is tested and working and we can now correctly start child process with
private namespaces on Linux.

Fixes #19661

Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
Signed-off-by: Ronald G. Minnich <rmin...@gmail.com>
---
M src/syscall/exec_linux.go
1 file changed, 9 insertions(+), 0 deletions(-)

diff --git a/src/syscall/exec_linux.go b/src/syscall/exec_linux.go
index 6ad20f6..aa307e2 100644
--- a/src/syscall/exec_linux.go
+++ b/src/syscall/exec_linux.go
@@ -66,6 +66,8 @@
 		nextfd int
 		i      int
 		p      [2]int
+		n      = uintptr(unsafe.Pointer(&[]byte("none")[0]))
+		s      = uintptr(unsafe.Pointer(&[]byte("/")[0]))
 	)
 
 	// Record parent PID so child can test if it has died.
@@ -201,6 +203,13 @@
 		if err1 != 0 {
 			goto childerror
 		}
+		if sys.Unshareflags&CLONE_NEWNS == CLONE_NEWNS {
+			_, _, err1 = RawSyscall6(SYS_MOUNT, n, s, 0, MS_REC|MS_PRIVATE, 0, 0)
+			if err1 != 0 {
+				goto childerror
+			}
+
+		}
 	}
 
 	// User and groups

To view, visit change 38471. To unsubscribe, visit settings.

Gerrit-Project: go
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
Gerrit-Change-Number: 38471
Gerrit-PatchSet: 1
Gerrit-Owner: ron minnich <rmin...@gmail.com>

ron minnich (Gerrit)

unread,
Mar 22, 2017, 6:09:21 PM3/22/17
to golang-co...@googlegroups.com

ron minnich uploaded patch set #2 to this change.

View Change

os/exec: correctly handle Unshareflags with CLONE_NEWNS

In some newer Linux distros, the mountflags specified
at boot essentially
disable the CLONE_NEWNS flag in unshare(2).
This problem is most commonly seen
on systems with systemd, but it can happen anywhere.

Hence, to create a private mount namespace,
it is not sufficient to just set
CLONE_NEWS; you have to call mount(2) to change
the behavior of namespaces, i.e.
mount("none", "/", NULL, MS_REC|MS_PRIVATE, NULL)

This is tested and working and we can now correctly
start child process with
private namespaces on Linux.

Fixes #19661

Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
Signed-off-by: Ronald G. Minnich <rmin...@gmail.com>
---
M src/syscall/exec_linux.go
1 file changed, 9 insertions(+), 0 deletions(-)

Gerrit-MessageType: newpatchset
Gerrit-Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
Gerrit-Change-Number: 38471

ron minnich (Gerrit)

unread,
Mar 22, 2017, 6:09:21 PM3/22/17
to golang-co...@googlegroups.com

ron minnich uploaded patch set #3 to this change.

View Change

os/exec: handle Unshareflags with CLONE_NEWNS

In some newer Linux distros, the mountflags specified
at boot essentially
disable the CLONE_NEWNS flag in unshare(2).
This problem is most commonly seen
on systems with systemd, but it can happen anywhere.

Hence, to create a private mount namespace,
it is not sufficient to just set
CLONE_NEWS; you have to call mount(2) to change
the behavior of namespaces, i.e.
mount("none", "/", NULL, MS_REC|MS_PRIVATE, NULL)

This is tested and working and we can now correctly
start child process with
private namespaces on Linux.

Fixes #19661

Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
Signed-off-by: Ronald G. Minnich <rmin...@gmail.com>
---
M src/syscall/exec_linux.go
1 file changed, 9 insertions(+), 0 deletions(-)

Gerrit-MessageType: newpatchset
Gerrit-Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
Gerrit-Change-Number: 38471
Gerrit-PatchSet: 3
Gerrit-Owner: ron minnich <rmin...@gmail.com>

ron minnich (Gerrit)

unread,
Mar 22, 2017, 6:36:18 PM3/22/17
to Ian Lance Taylor, golang-co...@googlegroups.com

ron minnich posted comments on this change.

View Change

Patch set 3:

Patch Set 2:

(1 comment)

Can you confirm that `sudo go test os/exec` failed before this CL and works after it?

Nope, it does not fail. I'm happy to try to modify it to fail, however, if that helps. It gets a tad messy as whether it fails depends, in most cases, on whether you're running systemd and whether it's set up mounts to have certain default behavior. I expect it will involve a lot of rooting around in /sys.

    To view, visit change 38471. To unsubscribe, visit settings.

    Gerrit-Project: go
    Gerrit-Branch: master
    Gerrit-MessageType: comment
    Gerrit-Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
    Gerrit-Change-Number: 38471
    Gerrit-PatchSet: 3
    Gerrit-Owner: ron minnich <rmin...@gmail.com>
    Gerrit-Reviewer: ron minnich <rmin...@gmail.com>
    Gerrit-CC: Ian Lance Taylor <ia...@golang.org>
    Gerrit-Comment-Date: Wed, 22 Mar 2017 22:36:16 +0000
    Gerrit-HasComments: No

    ron minnich (Gerrit)

    unread,
    Mar 22, 2017, 6:37:01 PM3/22/17
    to Ian Lance Taylor, golang-co...@googlegroups.com

    ron minnich uploaded patch set #4 to this change.

    View Change

    os/exec: handle Unshareflags with CLONE_NEWNS
    
    In some newer Linux distros, the mountflags specified
    at boot essentially
    disable the CLONE_NEWNS flag in unshare(2).
    This problem is most commonly seen
    on systems with systemd, but it can happen anywhere.
    
    Hence, to create a private mount namespace,
    it is not sufficient to just set
    CLONE_NEWS; you have to call mount(2) to change
    the behavior of namespaces, i.e.
    mount("none", "/", NULL, MS_REC|MS_PRIVATE, NULL)
    
    This is tested and working and we can now correctly
    start child process with
    private namespaces on Linux.
    
    Fixes #19661
    
    Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
    ---
    M src/syscall/exec_linux.go
    1 file changed, 9 insertions(+), 0 deletions(-)
    
    
    Gerrit-MessageType: newpatchset
    Gerrit-Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
    Gerrit-Change-Number: 38471
    Gerrit-PatchSet: 4

    ron minnich (Gerrit)

    unread,
    Mar 22, 2017, 7:00:36 PM3/22/17
    to Ian Lance Taylor, golang-co...@googlegroups.com

    ron minnich posted comments on this change.

    View Change

    Patch set 4:

    Patch Set 3:

    Patch Set 2:

    (1 comment)

    Can you confirm that `sudo go test os/exec` failed before this CL and works after it?

    Nope, it does not fail. I'm happy to try to modify it to fail, however, if that helps. It gets a tad messy as whether it fails depends, in most cases, on whether you're running systemd and whether it's set up mounts to have certain default behavior. I expect it will involve a lot of rooting around in /sys.

    other context: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=739593

      To view, visit change 38471. To unsubscribe, visit settings.

      Gerrit-Project: go
      Gerrit-Branch: master
      Gerrit-MessageType: comment
      Gerrit-Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
      Gerrit-Change-Number: 38471
      Gerrit-PatchSet: 4
      Gerrit-Owner: ron minnich <rmin...@gmail.com>
      Gerrit-Reviewer: ron minnich <rmin...@gmail.com>
      Gerrit-CC: Ian Lance Taylor <ia...@golang.org>
      Gerrit-Comment-Date: Wed, 22 Mar 2017 23:00:34 +0000
      Gerrit-HasComments: No

      Ian Lance Taylor (Gerrit)

      unread,
      Mar 22, 2017, 7:41:58 PM3/22/17
      to ron minnich, golang-co...@googlegroups.com

      Ian Lance Taylor posted comments on this change.

      View Change

      Patch set 4:

      My concern about the test is simply that we have no way of knowing whether this works or not. I understand that this is system-specific, but I gather from your comments that you have some way of knowing that this patch fixed something. Ideally I would like to capture that in exec_linux_test.go, if possible, even if the resulting test always passes on machines without systemd.

      (2 comments)

      To view, visit change 38471. To unsubscribe, visit settings.

      Gerrit-Project: go
      Gerrit-Branch: master
      Gerrit-MessageType: comment
      Gerrit-Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
      Gerrit-Change-Number: 38471
      Gerrit-PatchSet: 4
      Gerrit-Owner: ron minnich <rmin...@gmail.com>
      Gerrit-Reviewer: ron minnich <rmin...@gmail.com>
      Gerrit-CC: Ian Lance Taylor <ia...@golang.org>
      Gerrit-Comment-Date: Wed, 22 Mar 2017 23:41:55 +0000
      Gerrit-HasComments: Yes

      ron minnich (Gerrit)

      unread,
      Mar 22, 2017, 7:51:08 PM3/22/17
      to Ian Lance Taylor, golang-co...@googlegroups.com

      ron minnich posted comments on this change.

      View Change

      Patch set 4:

      Patch Set 4:

      (2 comments)

      My concern about the test is simply that we have no way of knowing whether this works or not. I understand that this is system-specific, but I gather from your comments that you have some way of knowing that this patch fixed something. Ideally I would like to capture that in exec_linux_test.go, if possible, even if the resulting test always passes on machines without systemd.

      So, a false positive is probably ok here. I think this makes sense. I have a rough idea of what to do, will do. Thanks.

      (2 comments)

        • Done

        • I've stopped writing that style because I've seen people get burned once or twice (in Go and other languages) when the constant in question is a multi-bit field. Yes, this is not a multi-bit field, now, but, how do we know, precisely? This test is safer. Anyway, I can change it, but I'm a bit uncomfortable doing so.

      To view, visit change 38471. To unsubscribe, visit settings.

      Gerrit-Project: go
      Gerrit-Branch: master
      Gerrit-MessageType: comment
      Gerrit-Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
      Gerrit-Change-Number: 38471
      Gerrit-PatchSet: 4
      Gerrit-Owner: ron minnich <rmin...@gmail.com>
      Gerrit-Reviewer: ron minnich <rmin...@gmail.com>
      Gerrit-CC: Ian Lance Taylor <ia...@golang.org>
      Gerrit-Comment-Date: Wed, 22 Mar 2017 23:51:05 +0000
      Gerrit-HasComments: Yes

      Ian Lance Taylor (Gerrit)

      unread,
      Mar 22, 2017, 8:00:18 PM3/22/17
      to ron minnich, golang-co...@googlegroups.com

      Ian Lance Taylor posted comments on this change.

      View Change

      Patch set 4:

      So, a false positive is probably ok here. I think this makes sense. I have a rough idea of what to do, will do. Thanks.

      I think I would say that a false negative is OK here. That is, it's OK if the test passes unexpectedly, as long as it fails sometimes. That is probably what you meant too.

      (1 comment)

      To view, visit change 38471. To unsubscribe, visit settings.

      Gerrit-Project: go
      Gerrit-Branch: master
      Gerrit-MessageType: comment
      Gerrit-Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
      Gerrit-Change-Number: 38471
      Gerrit-PatchSet: 4
      Gerrit-Owner: ron minnich <rmin...@gmail.com>
      Gerrit-Reviewer: ron minnich <rmin...@gmail.com>
      Gerrit-CC: Ian Lance Taylor <ia...@golang.org>
      Gerrit-Comment-Date: Thu, 23 Mar 2017 00:00:16 +0000
      Gerrit-HasComments: Yes

      ron minnich (Gerrit)

      unread,
      Mar 22, 2017, 9:22:46 PM3/22/17
      to Ian Lance Taylor, golang-co...@googlegroups.com

      ron minnich uploaded patch set #5 to this change.

      View Change

      os/exec: handle Unshareflags with CLONE_NEWNS
      
      In some newer Linux distros, systemd forces
      all mount namespaces to be shared, starting
      at /. This disables the CLONE_NEWNS
      flag in unshare(2) and clone(2).
      While this problem is most commonly seen
      on systems with systemd, it can happen anywhere,
      due to how Linux namespaces now work.
      
      Hence, to create a private mount namespace,
      it is not sufficient to just set
      CLONE_NEWS; you have to call mount(2) to change
      the behavior of namespaces, i.e.
      mount("none", "/", NULL, MS_REC|MS_PRIVATE, NULL)
      
      This is tested and working and we can now correctly
      start child process with private namespaces on Linux
      distros that use systemd.
      
      The new test works correctly on Ubuntu 16.04.2 LTS.
      It fails if I comment out the new Mount, and
      succeeds otherwise. In each case it correctly
      cleans up after itself.
      
      Fixes #19661
      
      Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
      ---
      M src/syscall/exec_linux.go
      M src/syscall/exec_linux_test.go
      2 files changed, 81 insertions(+), 0 deletions(-)
      
      
      diff --git a/src/syscall/exec_linux.go b/src/syscall/exec_linux.go
      index 6ad20f6..3c16acc 100644
      --- a/src/syscall/exec_linux.go
      +++ b/src/syscall/exec_linux.go
      @@ -42,6 +42,11 @@
       	GidMappingsEnableSetgroups bool
       }
       
      +var (
      +	n = uintptr(unsafe.Pointer(&[]byte("none")[0]))
      +	s = uintptr(unsafe.Pointer(&[]byte("/")[0]))
      +)
      +
       // Implemented in runtime package.
       func runtime_BeforeFork()
       func runtime_AfterFork()
      @@ -201,6 +206,19 @@
       		if err1 != 0 {
       			goto childerror
       		}
      +		// The unshare system call in Linux doesn't unshare mount points
      +		// mounted with --shared. Systemd mounts / with --shared. For a
      +		// long discussion of the pros and cons of this see debian bug 739593.
      +		// The Go model of unsharing is more like Plan 9, where you ask
      +		// to unshare and the namespaces are unconditionally unshared.
      +		// To make this model work we must further mark / as MS_PRIVATE.
      +		// This is what the standard unshare command does.
      +		if sys.Unshareflags&CLONE_NEWNS == CLONE_NEWNS {
      +			_, _, err1 = RawSyscall6(SYS_MOUNT, n, s, 0, MS_REC|MS_PRIVATE, 0, 0)
      +			if err1 != 0 {
      +				goto childerror
      +			}
      +		}
       	}
       
       	// User and groups
      diff --git a/src/syscall/exec_linux_test.go b/src/syscall/exec_linux_test.go
      index 7a4b571..0a7cf30 100644
      --- a/src/syscall/exec_linux_test.go
      +++ b/src/syscall/exec_linux_test.go
      @@ -7,6 +7,8 @@
       package syscall_test
       
       import (
      +	"flag"
      +	"fmt"
       	"io/ioutil"
       	"os"
       	"os/exec"
      @@ -253,3 +255,64 @@
       	}
       	t.Errorf("id command output: %q, expected one of %q", strOut, expected)
       }
      +
      +// TestUnshareHelperProcess isn't a real test. It's used as a helper process
      +// for TestUnshareMountNameSpace.
      +func TestUnshareMountNameSpaceHelper(*testing.T) {
      +	if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" {
      +		return
      +	}
      +	defer os.Exit(0)
      +
      +	if err := syscall.Mount("none", flag.Args()[0], "proc", 0, ""); err != nil {
      +		fmt.Fprintf(os.Stderr, "unshare: mount %v failed: %v", os.Args, err)
      +		os.Exit(2)
      +	}
      +	os.Exit(0)
      +}
      +
      +// Test for Issue 38471: unshare fails because systemd has forced / to be shared
      +func TestUnshareMountNameSpace(t *testing.T) {
      +	// Make sure we are running as root so we have permissions to use unshare
      +	// and create a network namespace.
      +	if os.Getuid() != 0 {
      +		t.Skip("kernel prohibits unshare in unprivileged process, unless using user namespace")
      +	}
      +
      +	// When running under the Go continuous build, skip tests for
      +	// now when under Kubernetes. (where things are root but not quite)
      +	// Both of these are our own environment variables.
      +	// See Issue 12815.
      +	if os.Getenv("GO_BUILDER_NAME") != "" && os.Getenv("IN_KUBERNETES") == "1" {
      +		t.Skip("skipping test on Kubernetes-based builders; see Issue 12815")
      +	}
      +
      +	d, err := ioutil.TempDir("", "unshare")
      +	if err != nil {
      +		t.Fatalf("tempdir: %v", err)
      +	}
      +
      +	cmd := exec.Command(os.Args[0], "-test.run=TestUnshareMountNameSpaceHelper", d)
      +	cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1"}
      +	cmd.SysProcAttr = &syscall.SysProcAttr{Unshareflags: syscall.CLONE_NEWNS}
      +
      +	o, err := cmd.CombinedOutput()
      +	if err != nil {
      +		t.Fatalf("unshare failed: %v, %v", o, err)
      +	}
      +
      +	// How do we tell if the namespace was really unshared? It turns out
      +	// to be simple: just try to remove the directory. If it's still mounted
      +	// on the rm will fail with EBUSY. Then we have some cleanup to do:
      +	// we must unmount it, then try to remove it again.
      +
      +	if err := os.Remove(d); err != nil {
      +		t.Errorf("rmdir failed on %v: %v", d, err)
      +		if err := syscall.Unmount(d, syscall.MNT_FORCE); err != nil {
      +			t.Errorf("Can't unmount %v: %v", d, err)
      +		}
      +		if err := os.Remove(d); err != nil {
      +			t.Errorf("rmdir after unmount failed on %v: %v", d, err)
      +		}
      +	}
      +}
      

      To view, visit change 38471. To unsubscribe, visit settings.

      Gerrit-Project: go
      Gerrit-Branch: master
      Gerrit-MessageType: newpatchset
      Gerrit-Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
      Gerrit-Change-Number: 38471
      Gerrit-PatchSet: 5

      ron minnich (Gerrit)

      unread,
      Mar 22, 2017, 9:26:41 PM3/22/17
      to Ian Lance Taylor, golang-co...@googlegroups.com

      ron minnich uploaded patch set #6 to this change.

      View Change

      os/exec: handle Unshareflags with CLONE_NEWNS
      
      In some newer Linux distros, systemd forces
      all mount namespaces to be shared, starting
      at /. This disables the CLONE_NEWNS
      flag in unshare(2) and clone(2).
      While this problem is most commonly seen
      on systems with systemd, it can happen anywhere,
      due to how Linux namespaces now work.
      
      Hence, to create a private mount namespace,
      it is not sufficient to just set
      CLONE_NEWS; you have to call mount(2) to change
      the behavior of namespaces, i.e.
      mount("none", "/", NULL, MS_REC|MS_PRIVATE, NULL)
      
      This is tested and working and we can now correctly
      start child process with private namespaces on Linux
      distros that use systemd.
      
      The new test works correctly on Ubuntu 16.04.2 LTS.
      It fails if I comment out the new Mount, and
      succeeds otherwise. In each case it correctly
      cleans up after itself.
      
      Fixes #19661
      
      Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
      ---
      M src/syscall/exec_linux.go
      M src/syscall/exec_linux_test.go
      2 files changed, 80 insertions(+), 0 deletions(-)
      
      
      diff --git a/src/syscall/exec_linux.go b/src/syscall/exec_linux.go
      index 6ad20f6..3c16acc 100644
      --- a/src/syscall/exec_linux.go
      +++ b/src/syscall/exec_linux.go
      @@ -42,6 +42,11 @@
       	GidMappingsEnableSetgroups bool
       }
       
      +var (
      +	n = uintptr(unsafe.Pointer(&[]byte("none")[0]))
      +	s = uintptr(unsafe.Pointer(&[]byte("/")[0]))
      +)
      +
       // Implemented in runtime package.
       func runtime_BeforeFork()
       func runtime_AfterFork()
      @@ -201,6 +206,19 @@
       		if err1 != 0 {
       			goto childerror
       		}
      +		// The unshare system call in Linux doesn't unshare mount points
      +		// mounted with --shared. Systemd mounts / with --shared. For a
      +		// long discussion of the pros and cons of this see debian bug 739593.
      +		// The Go model of unsharing is more like Plan 9, where you ask
      +		// to unshare and the namespaces are unconditionally unshared.
      +		// To make this model work we must further mark / as MS_PRIVATE.
      +		// This is what the standard unshare command does.
      +		if sys.Unshareflags&CLONE_NEWNS == CLONE_NEWNS {
      +			_, _, err1 = RawSyscall6(SYS_MOUNT, n, s, 0, MS_REC|MS_PRIVATE, 0, 0)
      +			if err1 != 0 {
      +				goto childerror
      +			}
      +		}
       	}
       
       	// User and groups
      diff --git a/src/syscall/exec_linux_test.go b/src/syscall/exec_linux_test.go
      index 7a4b571..ed44ddf 100644
      --- a/src/syscall/exec_linux_test.go
      +++ b/src/syscall/exec_linux_test.go
      @@ -7,6 +7,8 @@
       package syscall_test
       
       import (
      +	"flag"
      +	"fmt"
       	"io/ioutil"
       	"os"
       	"os/exec"
      @@ -253,3 +255,63 @@
       	}
       	t.Errorf("id command output: %q, expected one of %q", strOut, expected)
       }
      +
      +// TestUnshareHelperProcess isn't a real test. It's used as a helper process
      +// for TestUnshareMountNameSpace.
      +func TestUnshareMountNameSpaceHelper(*testing.T) {
      +	if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" {
      +		return
      +	}
      +	defer os.Exit(0)
      +
      +	if err := syscall.Mount("none", flag.Args()[0], "proc", 0, ""); err != nil {
      +		fmt.Fprintf(os.Stderr, "unshare: mount %v failed: %v", os.Args, err)
      +		os.Exit(2)
      +	}
      +}
      +
      +// Test for Issue 38471: unshare fails because systemd has forced / to be shared
      +func TestUnshareMountNameSpace(t *testing.T) {
      +	// Make sure we are running as root so we have permissions to use unshare
      +	// and create a network namespace.
      +	if os.Getuid() != 0 {
      +		t.Skip("kernel prohibits unshare in unprivileged process, unless using user namespace")
      +	}
      +
      +	// When running under the Go continuous build, skip tests for
      +	// now when under Kubernetes. (where things are root but not quite)
      +	// Both of these are our own environment variables.
      +	// See Issue 12815.
      +	if os.Getenv("GO_BUILDER_NAME") != "" && os.Getenv("IN_KUBERNETES") == "1" {
      +		t.Skip("skipping test on Kubernetes-based builders; see Issue 12815")
      +	}
      +
      +	d, err := ioutil.TempDir("", "unshare")
      +	if err != nil {
      +		t.Fatalf("tempdir: %v", err)
      +	}
      +
      +	cmd := exec.Command(os.Args[0], "-test.run=TestUnshareMountNameSpaceHelper", d)
      +	cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1"}
      +	cmd.SysProcAttr = &syscall.SysProcAttr{Unshareflags: syscall.CLONE_NEWNS}
      +
      +	o, err := cmd.CombinedOutput()
      +	if err != nil {
      +		t.Fatalf("unshare failed: %v, %v", o, err)
      +	}
      +
      +	// How do we tell if the namespace was really unshared? It turns out
      +	// to be simple: just try to remove the directory. If it's still mounted
      +	// on the rm will fail with EBUSY. Then we have some cleanup to do:
      +	// we must unmount it, then try to remove it again.
      +
      +	if err := os.Remove(d); err != nil {
      +		t.Errorf("rmdir failed on %v: %v", d, err)
      +		if err := syscall.Unmount(d, syscall.MNT_FORCE); err != nil {
      +			t.Errorf("Can't unmount %v: %v", d, err)
      +		}
      +		if err := os.Remove(d); err != nil {
      +			t.Errorf("rmdir after unmount failed on %v: %v", d, err)
      +		}
      +	}
      +}
      

      To view, visit change 38471. To unsubscribe, visit settings.

      Gerrit-Project: go
      Gerrit-Branch: master
      Gerrit-MessageType: newpatchset
      Gerrit-Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
      Gerrit-Change-Number: 38471
      Gerrit-PatchSet: 6

      Ian Lance Taylor (Gerrit)

      unread,
      Mar 22, 2017, 11:48:09 PM3/22/17
      to ron minnich, golang-co...@googlegroups.com

      Ian Lance Taylor posted comments on this change.

      View Change

      Patch set 6:Run-TryBot +1

      (1 comment)

      • File src/syscall/exec_linux.go:

        • Patch Set #6, Line 46: n = uintptr(unsafe.Pointer(&[]byte("none")[0]))

          Oh, sorry, don't write it like this. You need longer names, and you just need something you can pass to the kernel, so use [...]byte to save space.

          var (
              none = [...]byte{'n', 'o', 'n', 'e'}
              slash = [...byte{'/'}
          )
          Then below you can use
              uintptr(unsafe.Pointer(&none[0]))

      To view, visit change 38471. To unsubscribe, visit settings.

      Gerrit-Project: go
      Gerrit-Branch: master
      Gerrit-MessageType: comment
      Gerrit-Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
      Gerrit-Change-Number: 38471
      Gerrit-PatchSet: 6
      Gerrit-Owner: ron minnich <rmin...@gmail.com>
      Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
      Gerrit-Reviewer: ron minnich <rmin...@gmail.com>
      Gerrit-Comment-Date: Thu, 23 Mar 2017 03:48:07 +0000
      Gerrit-HasComments: Yes

      Gobot Gobot (Gerrit)

      unread,
      Mar 22, 2017, 11:48:28 PM3/22/17
      to ron minnich, Ian Lance Taylor, golang-co...@googlegroups.com

      Gobot Gobot posted comments on this change.

      View Change

      Patch set 6:

      TryBots beginning. Status page: http://farmer.golang.org/try?commit=77286cb5

        To view, visit change 38471. To unsubscribe, visit settings.

        Gerrit-Project: go
        Gerrit-Branch: master
        Gerrit-MessageType: comment
        Gerrit-Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
        Gerrit-Change-Number: 38471
        Gerrit-PatchSet: 6
        Gerrit-Owner: ron minnich <rmin...@gmail.com>
        Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
        Gerrit-Reviewer: ron minnich <rmin...@gmail.com>
        Gerrit-CC: Gobot Gobot <go...@golang.org>
        Gerrit-Comment-Date: Thu, 23 Mar 2017 03:48:26 +0000
        Gerrit-HasComments: No

        Gobot Gobot (Gerrit)

        unread,
        Mar 22, 2017, 11:56:06 PM3/22/17
        to ron minnich, Ian Lance Taylor, golang-co...@googlegroups.com

        Gobot Gobot posted comments on this change.

        View Change

        Patch set 6:TryBot-Result +1

        TryBots are happy.

          To view, visit change 38471. To unsubscribe, visit settings.

          Gerrit-Project: go
          Gerrit-Branch: master
          Gerrit-MessageType: comment
          Gerrit-Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
          Gerrit-Change-Number: 38471
          Gerrit-PatchSet: 6
          Gerrit-Owner: ron minnich <rmin...@gmail.com>
          Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
          Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
          Gerrit-Reviewer: ron minnich <rmin...@gmail.com>
          Gerrit-Comment-Date: Thu, 23 Mar 2017 03:56:03 +0000
          Gerrit-HasComments: No

          ron minnich (Gerrit)

          unread,
          Mar 23, 2017, 11:18:32 AM3/23/17
          to Ian Lance Taylor, Gobot Gobot, golang-co...@googlegroups.com

          ron minnich uploaded patch set #7 to this change.

          View Change

          os/exec: handle Unshareflags with CLONE_NEWNS
          
          In some newer Linux distros, systemd forces
          all mount namespaces to be shared, starting
          at /. This disables the CLONE_NEWNS
          flag in unshare(2) and clone(2).
          While this problem is most commonly seen
          on systems with systemd, it can happen anywhere,
          due to how Linux namespaces now work.
          
          Hence, to create a private mount namespace,
          it is not sufficient to just set
          CLONE_NEWS; you have to call mount(2) to change
          the behavior of namespaces, i.e.
          mount("none", "/", NULL, MS_REC|MS_PRIVATE, NULL)
          
          This is tested and working and we can now correctly
          start child process with private namespaces on Linux
          distros that use systemd.
          
          The new test works correctly on Ubuntu 16.04.2 LTS.
          It fails if I comment out the new Mount, and
          succeeds otherwise. In each case it correctly
          cleans up after itself.
          
          Fixes #19661
          
          Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
          ---
          M src/syscall/exec_linux.go
          M src/syscall/exec_linux_test.go
          2 files changed, 80 insertions(+), 0 deletions(-)
          
          
          diff --git a/src/syscall/exec_linux.go b/src/syscall/exec_linux.go
          index 6ad20f6..8465bbc 100644
          --- a/src/syscall/exec_linux.go
          +++ b/src/syscall/exec_linux.go
          @@ -42,6 +42,11 @@
           	GidMappingsEnableSetgroups bool
           }
           
          +var (
          +	none  = []byte("none\000")
          +	slash = []byte("/\000")
          +)
          +
           // Implemented in runtime package.
           func runtime_BeforeFork()
           func runtime_AfterFork()
          @@ -201,6 +206,19 @@
           		if err1 != 0 {
           			goto childerror
           		}
          +		// The unshare system call in Linux doesn't unshare mount points
          +		// mounted with --shared. Systemd mounts / with --shared. For a
          +		// long discussion of the pros and cons of this see debian bug 739593.
          +		// The Go model of unsharing is more like Plan 9, where you ask
          +		// to unshare and the namespaces are unconditionally unshared.
          +		// To make this model work we must further mark / as MS_PRIVATE.
          +		// This is what the standard unshare command does.
          +		if sys.Unshareflags&CLONE_NEWNS == CLONE_NEWNS {
          +			_, _, err1 = RawSyscall6(SYS_MOUNT, uintptr(unsafe.Pointer(&none[0])), uintptr(unsafe.Pointer(&slash[0])), 0, MS_REC|MS_PRIVATE, 0, 0)
          +			if err1 != 0 {
          +				goto childerror
          +			}
          +		}
           	}
           
           	// User and groups
          diff --git a/src/syscall/exec_linux_test.go b/src/syscall/exec_linux_test.go
          index 7a4b571..ed44ddf 100644
          --- a/src/syscall/exec_linux_test.go
          +++ b/src/syscall/exec_linux_test.go
          @@ -7,6 +7,8 @@
           package syscall_test
           
           import (
          +	"flag"
          +	"fmt"
           	"io/ioutil"
           	"os"
           	"os/exec"
          @@ -253,3 +255,63 @@
           	}
           	t.Errorf("id command output: %q, expected one of %q", strOut, expected)
           }
          +
          +// TestUnshareHelperProcess isn't a real test. It's used as a helper process
          +// for TestUnshareMountNameSpace.
          +func TestUnshareMountNameSpaceHelper(*testing.T) {
          +	if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" {
          +		return
          +	}
          +	defer os.Exit(0)
          +
          +	if err := syscall.Mount("none", flag.Args()[0], "proc", 0, ""); err != nil {
          +		fmt.Fprintf(os.Stderr, "unshare: mount %v failed: %v", os.Args, err)
          +		os.Exit(2)
          +	}
          +}
          +
          +// Test for Issue 38471: unshare fails because systemd has forced / to be shared
          +func TestUnshareMountNameSpace(t *testing.T) {
          +	// Make sure we are running as root so we have permissions to use unshare
          +	// and create a network namespace.
          +	if os.Getuid() != 0 {
          +		t.Skip("kernel prohibits unshare in unprivileged process, unless using user namespace")
          +	}
          +
          +	// When running under the Go continuous build, skip tests for
          +	// now when under Kubernetes. (where things are root but not quite)
          +	// Both of these are our own environment variables.
          +	// See Issue 12815.
          +	if os.Getenv("GO_BUILDER_NAME") != "" && os.Getenv("IN_KUBERNETES") == "1" {
          +		t.Skip("skipping test on Kubernetes-based builders; see Issue 12815")
          +	}
          +
          +	d, err := ioutil.TempDir("", "unshare")
          +	if err != nil {
          +		t.Fatalf("tempdir: %v", err)
          +	}
          +
          +	cmd := exec.Command(os.Args[0], "-test.run=TestUnshareMountNameSpaceHelper", d)
          +	cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1"}
          +	cmd.SysProcAttr = &syscall.SysProcAttr{Unshareflags: syscall.CLONE_NEWNS}
          +
          +	o, err := cmd.CombinedOutput()
          +	if err != nil {
          +		t.Fatalf("unshare failed: %v, %v", o, err)
          +	}
          +
          +	// How do we tell if the namespace was really unshared? It turns out
          +	// to be simple: just try to remove the directory. If it's still mounted
          +	// on the rm will fail with EBUSY. Then we have some cleanup to do:
          +	// we must unmount it, then try to remove it again.
          +
          +	if err := os.Remove(d); err != nil {
          +		t.Errorf("rmdir failed on %v: %v", d, err)
          +		if err := syscall.Unmount(d, syscall.MNT_FORCE); err != nil {
          +			t.Errorf("Can't unmount %v: %v", d, err)
          +		}
          +		if err := os.Remove(d); err != nil {
          +			t.Errorf("rmdir after unmount failed on %v: %v", d, err)
          +		}
          +	}
          +}
          

          To view, visit change 38471. To unsubscribe, visit settings.

          Gerrit-Project: go
          Gerrit-Branch: master
          Gerrit-MessageType: newpatchset
          Gerrit-Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
          Gerrit-Change-Number: 38471
          Gerrit-PatchSet: 7

          ron minnich (Gerrit)

          unread,
          Mar 23, 2017, 11:21:49 AM3/23/17
          to Gobot Gobot, Ian Lance Taylor, golang-co...@googlegroups.com

          ron minnich posted comments on this change.

          View Change

          Patch set 6:

          (1 comment)

            • Patch Set #6, Line 46: n = uintptr(unsafe.Pointer(&[]byte("none")[0]))

              Oh, sorry, don't write it like this. You need longer names, and you just n

            • I like your change but in practice it does not work. The string passed to the system call is not null-terminated. So to the kernel it looks like none<garbage> and /<garbage>

              Now I know it should work but does not. I've no idea why and I'll get back to it when I can.

              I've done an alternate form that works, though I doubt you'll like it. I actually prefer the "none" to 'n', 'o', ... anyway. the latter form I've found harder to read.

          To view, visit change 38471. To unsubscribe, visit settings.

          Gerrit-Project: go
          Gerrit-Branch: master
          Gerrit-MessageType: comment
          Gerrit-Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
          Gerrit-Change-Number: 38471
          Gerrit-PatchSet: 6
          Gerrit-Owner: ron minnich <rmin...@gmail.com>
          Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
          Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
          Gerrit-Reviewer: ron minnich <rmin...@gmail.com>
          Gerrit-Comment-Date: Thu, 23 Mar 2017 15:21:47 +0000
          Gerrit-HasComments: Yes

          Ian Lance Taylor (Gerrit)

          unread,
          Mar 23, 2017, 11:55:57 AM3/23/17
          to ron minnich, Gobot Gobot, golang-co...@googlegroups.com

          Ian Lance Taylor posted comments on this change.

          View Change

          Patch set 7:

          Patch Set 6:

          (1 comment)

          (1 comment)

            • I like your change but in practice it does not work. The string passed to t

            • Hmmmm, did you try

              none = [...]byte{'n', 'o', 'n', 'e', '\000'}

              (has an explicit \000 at the end). I agree that the "none" is nicer but that form takes more memory in the executable because it uses a slice rather than an array. Since this is code that matters for approximately nobody, I'm trying to minimize the cost.

          To view, visit change 38471. To unsubscribe, visit settings.

          Gerrit-Project: go
          Gerrit-Branch: master
          Gerrit-MessageType: comment
          Gerrit-Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
          Gerrit-Change-Number: 38471
          Gerrit-PatchSet: 7
          Gerrit-Owner: ron minnich <rmin...@gmail.com>
          Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
          Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
          Gerrit-Reviewer: ron minnich <rmin...@gmail.com>
          Gerrit-Comment-Date: Thu, 23 Mar 2017 15:55:55 +0000
          Gerrit-HasComments: Yes

          ron minnich (Gerrit)

          unread,
          Mar 23, 2017, 12:44:08 PM3/23/17
          to Ian Lance Taylor, Gobot Gobot, golang-co...@googlegroups.com

          ron minnich uploaded patch set #8 to this change.

          View Change

          os/exec: handle Unshareflags with CLONE_NEWNS
          
          In some newer Linux distros, systemd forces
          all mount namespaces to be shared, starting
          at /. This disables the CLONE_NEWNS
          flag in unshare(2) and clone(2).
          While this problem is most commonly seen
          on systems with systemd, it can happen anywhere,
          due to how Linux namespaces now work.
          
          Hence, to create a private mount namespace,
          it is not sufficient to just set
          CLONE_NEWS; you have to call mount(2) to change
          the behavior of namespaces, i.e.
          mount("none", "/", NULL, MS_REC|MS_PRIVATE, NULL)
          
          This is tested and working and we can now correctly
          start child process with private namespaces on Linux
          distros that use systemd.
          
          The new test works correctly on Ubuntu 16.04.2 LTS.
          It fails if I comment out the new Mount, and
          succeeds otherwise. In each case it correctly
          cleans up after itself.
          
          Fixes #19661
          
          Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
          ---
          M src/syscall/exec_linux.go
          M src/syscall/exec_linux_test.go
          2 files changed, 80 insertions(+), 0 deletions(-)
          
          
          diff --git a/src/syscall/exec_linux.go b/src/syscall/exec_linux.go
          index 6ad20f6..b36de96 100644
          --- a/src/syscall/exec_linux.go
          +++ b/src/syscall/exec_linux.go
          @@ -42,6 +42,11 @@
           	GidMappingsEnableSetgroups bool
           }
           
          +var (
          +	none  = []byte{'n', 'o', 'n', 'e', 0}
          +	slash = []byte{'/', 0}
          +)
          +
           // Implemented in runtime package.
           func runtime_BeforeFork()
           func runtime_AfterFork()
          @@ -201,6 +206,19 @@
           		if err1 != 0 {
           			goto childerror
           		}
          +		// The unshare system call in Linux doesn't unshare mount points
          +		// mounted with --shared. Systemd mounts / with --shared. For a
          +		// long discussion of the pros and cons of this see debian bug 739593.
          +		// The Go model of unsharing is more like Plan 9, where you ask
          +		// to unshare and the namespaces are unconditionally unshared.
          +		// To make this model work we must further mark / as MS_PRIVATE.
          +		// This is what the standard unshare command does.
          +		if sys.Unshareflags&CLONE_NEWNS == CLONE_NEWNS {
          +			_, _, err1 = RawSyscall6(SYS_MOUNT, uintptr(unsafe.Pointer(&none[0])), uintptr(unsafe.Pointer(&slash[0])), 0, MS_REC|MS_PRIVATE, 0, 0)
          +			if err1 != 0 {
          +				goto childerror
          +			}
          +		}
           	}
           
           	// User and groups
          diff --git a/src/syscall/exec_linux_test.go b/src/syscall/exec_linux_test.go
          index 7a4b571..ed44ddf 100644
          --- a/src/syscall/exec_linux_test.go
          +++ b/src/syscall/exec_linux_test.go
          @@ -7,6 +7,8 @@
           package syscall_test
           
           import (
          +	"flag"
          +	"fmt"
           	"io/ioutil"
           	"os"
           	"os/exec"
          @@ -253,3 +255,63 @@
           	}
           	t.Errorf("id command output: %q, expected one of %q", strOut, expected)
           }
          +
          +// TestUnshareHelperProcess isn't a real test. It's used as a helper process
          +// for TestUnshareMountNameSpace.
          +func TestUnshareMountNameSpaceHelper(*testing.T) {
          +	if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" {
          +		return
          +	}
          +	defer os.Exit(0)
          +
          +	if err := syscall.Mount("none", flag.Args()[0], "proc", 0, ""); err != nil {
          +		fmt.Fprintf(os.Stderr, "unshare: mount %v failed: %v", os.Args, err)
          +		os.Exit(2)
          +	}
          +}
          +
          +// Test for Issue 38471: unshare fails because systemd has forced / to be shared
          +func TestUnshareMountNameSpace(t *testing.T) {
          +	// Make sure we are running as root so we have permissions to use unshare
          +	// and create a network namespace.
          +	if os.Getuid() != 0 {
          +		t.Skip("kernel prohibits unshare in unprivileged process, unless using user namespace")
          +	}
          +
          +	// When running under the Go continuous build, skip tests for
          +	// now when under Kubernetes. (where things are root but not quite)
          +	// Both of these are our own environment variables.
          +	// See Issue 12815.
          +	if os.Getenv("GO_BUILDER_NAME") != "" && os.Getenv("IN_KUBERNETES") == "1" {
          +		t.Skip("skipping test on Kubernetes-based builders; see Issue 12815")
          +	}
          +
          +	d, err := ioutil.TempDir("", "unshare")
          +	if err != nil {
          +		t.Fatalf("tempdir: %v", err)
          +	}
          +
          +	cmd := exec.Command(os.Args[0], "-test.run=TestUnshareMountNameSpaceHelper", d)
          +	cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1"}
          +	cmd.SysProcAttr = &syscall.SysProcAttr{Unshareflags: syscall.CLONE_NEWNS}
          +
          +	o, err := cmd.CombinedOutput()
          +	if err != nil {
          +		t.Fatalf("unshare failed: %v, %v", o, err)
          +	}
          +
          +	// How do we tell if the namespace was really unshared? It turns out
          +	// to be simple: just try to remove the directory. If it's still mounted
          +	// on the rm will fail with EBUSY. Then we have some cleanup to do:
          +	// we must unmount it, then try to remove it again.
          +
          +	if err := os.Remove(d); err != nil {
          +		t.Errorf("rmdir failed on %v: %v", d, err)
          +		if err := syscall.Unmount(d, syscall.MNT_FORCE); err != nil {
          +			t.Errorf("Can't unmount %v: %v", d, err)
          +		}
          +		if err := os.Remove(d); err != nil {
          +			t.Errorf("rmdir after unmount failed on %v: %v", d, err)
          +		}
          +	}
          +}
          

          To view, visit change 38471. To unsubscribe, visit settings.

          Gerrit-Project: go
          Gerrit-Branch: master
          Gerrit-MessageType: newpatchset
          Gerrit-Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
          Gerrit-Change-Number: 38471
          Gerrit-PatchSet: 8

          Ian Lance Taylor (Gerrit)

          unread,
          Mar 23, 2017, 12:47:09 PM3/23/17
          to ron minnich, Gobot Gobot, golang-co...@googlegroups.com

          Ian Lance Taylor posted comments on this change.

          View Change

          Patch set 8:

          (1 comment)

          To view, visit change 38471. To unsubscribe, visit settings.

          Gerrit-Project: go
          Gerrit-Branch: master
          Gerrit-MessageType: comment
          Gerrit-Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
          Gerrit-Change-Number: 38471
          Gerrit-PatchSet: 8
          Gerrit-Owner: ron minnich <rmin...@gmail.com>
          Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
          Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
          Gerrit-Reviewer: ron minnich <rmin...@gmail.com>
          Gerrit-Comment-Date: Thu, 23 Mar 2017 16:47:06 +0000
          Gerrit-HasComments: Yes

          ron minnich (Gerrit)

          unread,
          Mar 23, 2017, 12:55:07 PM3/23/17
          to Ian Lance Taylor, Gobot Gobot, golang-co...@googlegroups.com

          ron minnich posted comments on this change.

          View Change

          Patch set 8:

          (1 comment)

          To view, visit change 38471. To unsubscribe, visit settings.

          Gerrit-Project: go
          Gerrit-Branch: master
          Gerrit-MessageType: comment
          Gerrit-Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
          Gerrit-Change-Number: 38471
          Gerrit-PatchSet: 8
          Gerrit-Owner: ron minnich <rmin...@gmail.com>
          Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
          Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
          Gerrit-Reviewer: ron minnich <rmin...@gmail.com>
          Gerrit-Comment-Date: Thu, 23 Mar 2017 16:55:05 +0000
          Gerrit-HasComments: Yes

          ron minnich (Gerrit)

          unread,
          Mar 23, 2017, 12:56:07 PM3/23/17
          to Ian Lance Taylor, Gobot Gobot, golang-co...@googlegroups.com

          ron minnich posted comments on this change.

          View Change

          Patch set 8:

          (1 comment)

            • Really sorry about this, but it should be

            • yeah but ... that did not work. That's why I'm here with this :-)

          To view, visit change 38471. To unsubscribe, visit settings.

          Gerrit-Project: go
          Gerrit-Branch: master
          Gerrit-MessageType: comment
          Gerrit-Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
          Gerrit-Change-Number: 38471
          Gerrit-PatchSet: 8
          Gerrit-Owner: ron minnich <rmin...@gmail.com>
          Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
          Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
          Gerrit-Reviewer: ron minnich <rmin...@gmail.com>
          Gerrit-Comment-Date: Thu, 23 Mar 2017 16:56:05 +0000
          Gerrit-HasComments: Yes

          ron minnich (Gerrit)

          unread,
          Mar 23, 2017, 12:58:27 PM3/23/17
          to Ian Lance Taylor, Gobot Gobot, golang-co...@googlegroups.com

          ron minnich posted comments on this change.

          View Change

          Patch set 8:

          Patch Set 8:

          (1 comment)

          Just to be sure I'm not nuts, I did test this one more time and ... no good. The none and / strings are not null terminated. Bug in go? I don't know. This *should* work.

            To view, visit change 38471. To unsubscribe, visit settings.

            Gerrit-Project: go
            Gerrit-Branch: master
            Gerrit-MessageType: comment
            Gerrit-Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
            Gerrit-Change-Number: 38471
            Gerrit-PatchSet: 8
            Gerrit-Owner: ron minnich <rmin...@gmail.com>
            Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
            Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
            Gerrit-Reviewer: ron minnich <rmin...@gmail.com>
            Gerrit-Comment-Date: Thu, 23 Mar 2017 16:58:24 +0000
            Gerrit-HasComments: No

            ron minnich (Gerrit)

            unread,
            Mar 23, 2017, 1:06:22 PM3/23/17
            to Ian Lance Taylor, Gobot Gobot, golang-co...@googlegroups.com

            ron minnich uploaded patch set #9 to this change.

            View Change

            os/exec: handle Unshareflags with CLONE_NEWNS
            
            In some newer Linux distros, systemd forces
            all mount namespaces to be shared, starting
            at /. This disables the CLONE_NEWNS
            flag in unshare(2) and clone(2).
            While this problem is most commonly seen
            on systems with systemd, it can happen anywhere,
            due to how Linux namespaces now work.
            
            Hence, to create a private mount namespace,
            it is not sufficient to just set
            CLONE_NEWS; you have to call mount(2) to change
            the behavior of namespaces, i.e.
            mount("none", "/", NULL, MS_REC|MS_PRIVATE, NULL)
            
            This is tested and working and we can now correctly
            start child process with private namespaces on Linux
            distros that use systemd.
            
            The new test works correctly on Ubuntu 16.04.2 LTS.
            It fails if I comment out the new Mount, and
            succeeds otherwise. In each case it correctly
            cleans up after itself.
            
            Fixes #19661
            
            Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
            ---
            M src/syscall/exec_linux.go
            M src/syscall/exec_linux_test.go
            2 files changed, 80 insertions(+), 0 deletions(-)
            
            
            diff --git a/src/syscall/exec_linux.go b/src/syscall/exec_linux.go
            index 6ad20f6..a5e9a56 100644
            --- a/src/syscall/exec_linux.go
            +++ b/src/syscall/exec_linux.go
            @@ -42,6 +42,11 @@
             	GidMappingsEnableSetgroups bool
             }
             
            +var (
            +	none  = [...]byte{'n', 'o', 'n', 'e', 0}
            +	slash = [...]byte{'/', 0}
            +)
            +
             // Implemented in runtime package.
             func runtime_BeforeFork()
             func runtime_AfterFork()
            @@ -201,6 +206,19 @@
             		if err1 != 0 {
             			goto childerror
             		}
            +		// The unshare system call in Linux doesn't unshare mount points
            +		// mounted with --shared. Systemd mounts / with --shared. For a
            +		// long discussion of the pros and cons of this see debian bug 739593.
            +		// The Go model of unsharing is more like Plan 9, where you ask
            +		// to unshare and the namespaces are unconditionally unshared.
            +		// To make this model work we must further mark / as MS_PRIVATE.
            +		// This is what the standard unshare command does.
            +		if sys.Unshareflags&CLONE_NEWNS == CLONE_NEWNS {
            +			_, _, err1 = RawSyscall6(SYS_MOUNT, uintptr(unsafe.Pointer(&none[0])), uintptr(unsafe.Pointer(&slash[0])), 0, MS_REC|MS_PRIVATE, 0, 0)
            +			if err1 != 0 {
            +				goto childerror
            +			}
            +		}
             	}
             
             	// User and groups
            diff --git a/src/syscall/exec_linux_test.go b/src/syscall/exec_linux_test.go
            index 7a4b571..ed44ddf 100644
            --- a/src/syscall/exec_linux_test.go
            +++ b/src/syscall/exec_linux_test.go
            @@ -7,6 +7,8 @@
             package syscall_test
             
             import (
            +	"flag"
            +	"fmt"
             	"io/ioutil"
             	"os"
             	"os/exec"
            @@ -253,3 +255,63 @@
             	}
             	t.Errorf("id command output: %q, expected one of %q", strOut, expected)
             }
            +
            +// TestUnshareHelperProcess isn't a real test. It's used as a helper process
            +// for TestUnshareMountNameSpace.
            +func TestUnshareMountNameSpaceHelper(*testing.T) {
            +	if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" {
            +		return
            +	}
            +	defer os.Exit(0)
            +
            +	if err := syscall.Mount("none", flag.Args()[0], "proc", 0, ""); err != nil {
            +		fmt.Fprintf(os.Stderr, "unshare: mount %v failed: %v", os.Args, err)
            +		os.Exit(2)
            +	}
            +}
            +
            +// Test for Issue 38471: unshare fails because systemd has forced / to be shared
            +func TestUnshareMountNameSpace(t *testing.T) {
            +	// Make sure we are running as root so we have permissions to use unshare
            +	// and create a network namespace.
            +	if os.Getuid() != 0 {
            +		t.Skip("kernel prohibits unshare in unprivileged process, unless using user namespace")
            +	}
            +
            +	// When running under the Go continuous build, skip tests for
            +	// now when under Kubernetes. (where things are root but not quite)
            +	// Both of these are our own environment variables.
            +	// See Issue 12815.
            +	if os.Getenv("GO_BUILDER_NAME") != "" && os.Getenv("IN_KUBERNETES") == "1" {
            +		t.Skip("skipping test on Kubernetes-based builders; see Issue 12815")
            +	}
            +
            +	d, err := ioutil.TempDir("", "unshare")
            +	if err != nil {
            +		t.Fatalf("tempdir: %v", err)
            +	}
            +
            +	cmd := exec.Command(os.Args[0], "-test.run=TestUnshareMountNameSpaceHelper", d)
            +	cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1"}
            +	cmd.SysProcAttr = &syscall.SysProcAttr{Unshareflags: syscall.CLONE_NEWNS}
            +
            +	o, err := cmd.CombinedOutput()
            +	if err != nil {
            +		t.Fatalf("unshare failed: %v, %v", o, err)
            +	}
            +
            +	// How do we tell if the namespace was really unshared? It turns out
            +	// to be simple: just try to remove the directory. If it's still mounted
            +	// on the rm will fail with EBUSY. Then we have some cleanup to do:
            +	// we must unmount it, then try to remove it again.
            +
            +	if err := os.Remove(d); err != nil {
            +		t.Errorf("rmdir failed on %v: %v", d, err)
            +		if err := syscall.Unmount(d, syscall.MNT_FORCE); err != nil {
            +			t.Errorf("Can't unmount %v: %v", d, err)
            +		}
            +		if err := os.Remove(d); err != nil {
            +			t.Errorf("rmdir after unmount failed on %v: %v", d, err)
            +		}
            +	}
            +}
            

            To view, visit change 38471. To unsubscribe, visit settings.

            Gerrit-Project: go
            Gerrit-Branch: master
            Gerrit-MessageType: newpatchset
            Gerrit-Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
            Gerrit-Change-Number: 38471
            Gerrit-PatchSet: 9

            Ian Lance Taylor (Gerrit)

            unread,
            Mar 23, 2017, 1:06:38 PM3/23/17
            to ron minnich, Gobot Gobot, golang-co...@googlegroups.com

            Ian Lance Taylor posted comments on this change.

            View Change

            Patch set 9:

            (1 comment)

              • yeah but ... that did not work. That's why I'm here with this :-)

              • Hmmm, I don't get it. I just tried recreating the problem and failed. Can you upload the code that does not work?

            To view, visit change 38471. To unsubscribe, visit settings.

            Gerrit-Project: go
            Gerrit-Branch: master
            Gerrit-MessageType: comment
            Gerrit-Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
            Gerrit-Change-Number: 38471
            Gerrit-PatchSet: 9
            Gerrit-Owner: ron minnich <rmin...@gmail.com>
            Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
            Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
            Gerrit-Reviewer: ron minnich <rmin...@gmail.com>
            Gerrit-Comment-Date: Thu, 23 Mar 2017 17:06:35 +0000
            Gerrit-HasComments: Yes

            ron minnich (Gerrit)

            unread,
            Mar 23, 2017, 1:07:12 PM3/23/17
            to Ian Lance Taylor, Gobot Gobot, golang-co...@googlegroups.com

            ron minnich posted comments on this change.

            View Change

            Patch set 8:

            (1 comment)

              • Hmmm, I don't get it. I just tried recreating the problem and failed. Can

              • If you delete the , 0 it will fail. But I've changed it to ...

            To view, visit change 38471. To unsubscribe, visit settings.

            Gerrit-Project: go
            Gerrit-Branch: master
            Gerrit-MessageType: comment
            Gerrit-Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
            Gerrit-Change-Number: 38471
            Gerrit-PatchSet: 8
            Gerrit-Owner: ron minnich <rmin...@gmail.com>
            Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
            Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
            Gerrit-Reviewer: ron minnich <rmin...@gmail.com>
            Gerrit-Comment-Date: Thu, 23 Mar 2017 17:07:09 +0000
            Gerrit-HasComments: Yes

            Ian Lance Taylor (Gerrit)

            unread,
            Mar 23, 2017, 1:12:15 PM3/23/17
            to ron minnich, Gobot Gobot, golang-co...@googlegroups.com

            Ian Lance Taylor posted comments on this change.

            View Change

            Patch set 9:

            (1 comment)

              • If you delete the , 0

              • Don't delete the ", 0". You need it.

                I tried the version with

                	none  = [...]byte{'n', 'o', 'n', 'e', 0}
                	slash = [...]byte{'/', 0}

                and it seems to work as expected for me. Using strace -f I see this:

                [pid 7132] mount("none", "/", NULL, MS_REC|MS_PRIVATE, NULL) = 0

            To view, visit change 38471. To unsubscribe, visit settings.

            Gerrit-Project: go
            Gerrit-Branch: master
            Gerrit-MessageType: comment
            Gerrit-Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
            Gerrit-Change-Number: 38471
            Gerrit-PatchSet: 9
            Gerrit-Owner: ron minnich <rmin...@gmail.com>
            Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
            Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
            Gerrit-Reviewer: ron minnich <rmin...@gmail.com>
            Gerrit-Comment-Date: Thu, 23 Mar 2017 17:12:13 +0000
            Gerrit-HasComments: Yes

            ron minnich (Gerrit)

            unread,
            Mar 23, 2017, 1:13:16 PM3/23/17
            to Ian Lance Taylor, Gobot Gobot, golang-co...@googlegroups.com

            ron minnich posted comments on this change.

            View Change

            Patch set 9:

            yep, my brain was in neutral as I confused Go syntax with another language. Thanks for your patience.

              To view, visit change 38471. To unsubscribe, visit settings.

              Gerrit-Project: go
              Gerrit-Branch: master
              Gerrit-MessageType: comment
              Gerrit-Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
              Gerrit-Change-Number: 38471
              Gerrit-PatchSet: 9
              Gerrit-Owner: ron minnich <rmin...@gmail.com>
              Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
              Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
              Gerrit-Reviewer: ron minnich <rmin...@gmail.com>
              Gerrit-Comment-Date: Thu, 23 Mar 2017 17:13:14 +0000
              Gerrit-HasComments: No

              ron minnich (Gerrit)

              unread,
              Mar 23, 2017, 1:13:39 PM3/23/17
              to Ian Lance Taylor, Gobot Gobot, golang-co...@googlegroups.com

              ron minnich posted comments on this change.

              View Change

              Patch set 9:

              Anyway, this fixes my problem.

                To view, visit change 38471. To unsubscribe, visit settings.

                Gerrit-Project: go
                Gerrit-Branch: master
                Gerrit-MessageType: comment
                Gerrit-Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
                Gerrit-Change-Number: 38471
                Gerrit-PatchSet: 9
                Gerrit-Owner: ron minnich <rmin...@gmail.com>
                Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
                Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
                Gerrit-Reviewer: ron minnich <rmin...@gmail.com>
                Gerrit-Comment-Date: Thu, 23 Mar 2017 17:13:37 +0000
                Gerrit-HasComments: No

                Ian Lance Taylor (Gerrit)

                unread,
                Mar 23, 2017, 1:39:44 PM3/23/17
                to ron minnich, Gobot Gobot, golang-co...@googlegroups.com

                Ian Lance Taylor posted comments on this change.

                View Change

                Patch set 9:Run-TryBot +1Code-Review +2

                Thanks for your patience.

                  To view, visit change 38471. To unsubscribe, visit settings.

                  Gerrit-Project: go
                  Gerrit-Branch: master
                  Gerrit-MessageType: comment
                  Gerrit-Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
                  Gerrit-Change-Number: 38471
                  Gerrit-PatchSet: 9
                  Gerrit-Owner: ron minnich <rmin...@gmail.com>
                  Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
                  Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
                  Gerrit-Reviewer: ron minnich <rmin...@gmail.com>
                  Gerrit-Comment-Date: Thu, 23 Mar 2017 17:39:41 +0000
                  Gerrit-HasComments: No

                  Gobot Gobot (Gerrit)

                  unread,
                  Mar 23, 2017, 1:39:53 PM3/23/17
                  to ron minnich, Ian Lance Taylor, golang-co...@googlegroups.com

                  Gobot Gobot posted comments on this change.

                  View Change

                  Patch set 9:

                  TryBots beginning. Status page: http://farmer.golang.org/try?commit=c9cd277c

                    To view, visit change 38471. To unsubscribe, visit settings.

                    Gerrit-Project: go
                    Gerrit-Branch: master
                    Gerrit-MessageType: comment
                    Gerrit-Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
                    Gerrit-Change-Number: 38471
                    Gerrit-PatchSet: 9
                    Gerrit-Owner: ron minnich <rmin...@gmail.com>
                    Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
                    Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
                    Gerrit-Reviewer: ron minnich <rmin...@gmail.com>
                    Gerrit-Comment-Date: Thu, 23 Mar 2017 17:39:51 +0000
                    Gerrit-HasComments: No

                    Gobot Gobot (Gerrit)

                    unread,
                    Mar 23, 2017, 1:47:31 PM3/23/17
                    to ron minnich, Ian Lance Taylor, golang-co...@googlegroups.com

                    Gobot Gobot posted comments on this change.

                    View Change

                    Patch set 9:TryBot-Result +1

                    TryBots are happy.

                      To view, visit change 38471. To unsubscribe, visit settings.

                      Gerrit-Project: go
                      Gerrit-Branch: master
                      Gerrit-MessageType: comment
                      Gerrit-Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
                      Gerrit-Change-Number: 38471
                      Gerrit-PatchSet: 9
                      Gerrit-Owner: ron minnich <rmin...@gmail.com>
                      Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
                      Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
                      Gerrit-Reviewer: ron minnich <rmin...@gmail.com>
                      Gerrit-Comment-Date: Thu, 23 Mar 2017 17:47:28 +0000
                      Gerrit-HasComments: No

                      Ian Lance Taylor (Gerrit)

                      unread,
                      Mar 23, 2017, 1:53:21 PM3/23/17
                      to ron minnich, golang-...@googlegroups.com, Gobot Gobot, golang-co...@googlegroups.com

                      Ian Lance Taylor merged this change.

                      View Change

                      Approvals: Ian Lance Taylor: Looks good to me, approved; Run TryBots Gobot Gobot: TryBots succeeded
                      os/exec: handle Unshareflags with CLONE_NEWNS
                      
                      In some newer Linux distros, systemd forces
                      all mount namespaces to be shared, starting
                      at /. This disables the CLONE_NEWNS
                      flag in unshare(2) and clone(2).
                      While this problem is most commonly seen
                      on systems with systemd, it can happen anywhere,
                      due to how Linux namespaces now work.
                      
                      Hence, to create a private mount namespace,
                      it is not sufficient to just set
                      CLONE_NEWS; you have to call mount(2) to change
                      the behavior of namespaces, i.e.
                      mount("none", "/", NULL, MS_REC|MS_PRIVATE, NULL)
                      
                      This is tested and working and we can now correctly
                      start child process with private namespaces on Linux
                      distros that use systemd.
                      
                      The new test works correctly on Ubuntu 16.04.2 LTS.
                      It fails if I comment out the new Mount, and
                      succeeds otherwise. In each case it correctly
                      cleans up after itself.
                      
                      Fixes #19661
                      
                      Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
                      Reviewed-on: https://go-review.googlesource.com/38471
                      Reviewed-by: Ian Lance Taylor <ia...@golang.org>
                      Run-TryBot: Ian Lance Taylor <ia...@golang.org>
                      TryBot-Result: Gobot Gobot <go...@golang.org>
                      ---
                      M src/syscall/exec_linux.go
                      M src/syscall/exec_linux_test.go
                      2 files changed, 80 insertions(+), 0 deletions(-)
                      
                      
                      diff --git a/src/syscall/exec_linux.go b/src/syscall/exec_linux.go
                      index 1ed10dd..e35ac25 100644
                      --- a/src/syscall/exec_linux.go
                      +++ b/src/syscall/exec_linux.go
                      @@ -42,6 +42,11 @@
                       	GidMappingsEnableSetgroups bool
                       }
                       
                      +var (
                      +	none  = [...]byte{'n', 'o', 'n', 'e', 0}
                      +	slash = [...]byte{'/', 0}
                      +)
                      +
                       // Implemented in runtime package.
                       func runtime_BeforeFork()
                       func runtime_AfterFork()
                      @@ -204,6 +209,19 @@
                       		if err1 != 0 {
                       			goto childerror
                       		}
                      +		// The unshare system call in Linux doesn't unshare mount points
                      +		// mounted with --shared. Systemd mounts / with --shared. For a
                      +		// long discussion of the pros and cons of this see debian bug 739593.
                      +		// The Go model of unsharing is more like Plan 9, where you ask
                      +		// to unshare and the namespaces are unconditionally unshared.
                      +		// To make this model work we must further mark / as MS_PRIVATE.
                      +		// This is what the standard unshare command does.
                      +		if sys.Unshareflags&CLONE_NEWNS == CLONE_NEWNS {
                      +			_, _, err1 = RawSyscall6(SYS_MOUNT, uintptr(unsafe.Pointer(&none[0])), uintptr(unsafe.Pointer(&slash[0])), 0, MS_REC|MS_PRIVATE, 0, 0)
                      +			if err1 != 0 {
                      +				goto childerror
                      +			}
                      +		}
                       	}
                       
                       	// User and groups
                      diff --git a/src/syscall/exec_linux_test.go b/src/syscall/exec_linux_test.go
                      index 7a4b571..ed44ddf 100644
                      --- a/src/syscall/exec_linux_test.go
                      +++ b/src/syscall/exec_linux_test.go
                      @@ -7,6 +7,8 @@
                       package syscall_test
                       
                       import (
                      +	"flag"
                      +	"fmt"
                       	"io/ioutil"
                       	"os"
                       	"os/exec"
                      @@ -253,3 +255,63 @@
                       	}
                       	t.Errorf("id command output: %q, expected one of %q", strOut, expected)
                       }
                      +
                      +// TestUnshareHelperProcess isn't a real test. It's used as a helper process
                      +// for TestUnshareMountNameSpace.
                      +func TestUnshareMountNameSpaceHelper(*testing.T) {
                      +	if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" {
                      +		return
                      +	}
                      +	defer os.Exit(0)
                      +
                      +	if err := syscall.Mount("none", flag.Args()[0], "proc", 0, ""); err != nil {
                      +		fmt.Fprintf(os.Stderr, "unshare: mount %v failed: %v", os.Args, err)
                      +		os.Exit(2)
                      +	}
                      +}
                      +
                      +// Test for Issue 38471: unshare fails because systemd has forced / to be shared
                      +func TestUnshareMountNameSpace(t *testing.T) {
                      +	// Make sure we are running as root so we have permissions to use unshare
                      +	// and create a network namespace.
                      +	if os.Getuid() != 0 {
                      +		t.Skip("kernel prohibits unshare in unprivileged process, unless using user namespace")
                      +	}
                      +
                      +	// When running under the Go continuous build, skip tests for
                      +	// now when under Kubernetes. (where things are root but not quite)
                      +	// Both of these are our own environment variables.
                      +	// See Issue 12815.
                      +	if os.Getenv("GO_BUILDER_NAME") != "" && os.Getenv("IN_KUBERNETES") == "1" {
                      +		t.Skip("skipping test on Kubernetes-based builders; see Issue 12815")
                      +	}
                      +
                      +	d, err := ioutil.TempDir("", "unshare")
                      +	if err != nil {
                      +		t.Fatalf("tempdir: %v", err)
                      +	}
                      +
                      +	cmd := exec.Command(os.Args[0], "-test.run=TestUnshareMountNameSpaceHelper", d)
                      +	cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1"}
                      +	cmd.SysProcAttr = &syscall.SysProcAttr{Unshareflags: syscall.CLONE_NEWNS}
                      +
                      +	o, err := cmd.CombinedOutput()
                      +	if err != nil {
                      +		t.Fatalf("unshare failed: %v, %v", o, err)
                      +	}
                      +
                      +	// How do we tell if the namespace was really unshared? It turns out
                      +	// to be simple: just try to remove the directory. If it's still mounted
                      +	// on the rm will fail with EBUSY. Then we have some cleanup to do:
                      +	// we must unmount it, then try to remove it again.
                      +
                      +	if err := os.Remove(d); err != nil {
                      +		t.Errorf("rmdir failed on %v: %v", d, err)
                      +		if err := syscall.Unmount(d, syscall.MNT_FORCE); err != nil {
                      +			t.Errorf("Can't unmount %v: %v", d, err)
                      +		}
                      +		if err := os.Remove(d); err != nil {
                      +			t.Errorf("rmdir after unmount failed on %v: %v", d, err)
                      +		}
                      +	}
                      +}
                      

                      To view, visit change 38471. To unsubscribe, visit settings.

                      Gerrit-Project: go
                      Gerrit-Branch: master
                      Gerrit-MessageType: merged
                      Gerrit-Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
                      Gerrit-Change-Number: 38471
                      Gerrit-PatchSet: 10

                      Elias Naur (Gerrit)

                      unread,
                      Mar 25, 2017, 9:49:03 AM3/25/17
                      to Ian Lance Taylor, ron minnich, Gobot Gobot, golang-co...@googlegroups.com

                      Elias Naur posted comments on this change.

                      View Change

                      Patch set 10:

                      This CL seems to have broken the (only) linux/arm64 builder:

                      https://build.golang.org/log/a2fd112da23e96e2c5ea00840544a1ddb6f45a2c

                        To view, visit change 38471. To unsubscribe, visit settings.

                        Gerrit-Project: go
                        Gerrit-Branch: master
                        Gerrit-MessageType: comment
                        Gerrit-Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
                        Gerrit-Change-Number: 38471
                        Gerrit-PatchSet: 10
                        Gerrit-Owner: ron minnich <rmin...@gmail.com>
                        Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
                        Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
                        Gerrit-Reviewer: ron minnich <rmin...@gmail.com>
                        Gerrit-CC: Elias Naur <elias...@gmail.com>
                        Gerrit-Comment-Date: Sat, 25 Mar 2017 13:49:00 +0000
                        Gerrit-HasComments: No

                        ron minnich

                        unread,
                        Mar 25, 2017, 12:19:51 PM3/25/17
                        to elias...@gmail.com, matt...@gmail.com, golang-co...@googlegroups.com, toud...@gmail.com, go...@golang.org, Ian Lance Taylor
                        man that's weird, that's a really innocuous change. Not sure if you can but if you can get me access to an ARM system somehow I'm happy to look. My ARM system is still in the mail.

                        Also, if there is an unshare command on that system, this change is equivalent to unshare -m /bin/date, so if you want to strace that and send me output I can take a look.

                        thanks

                        ron

                        Brad Fitzpatrick

                        unread,
                        Mar 25, 2017, 1:07:29 PM3/25/17
                        to ron minnich, Elias Naur, Yasuhiro MATSUMOTO, golang-co...@googlegroups.com, toud...@gmail.com, Gobot Gobot, Ian Lance Taylor
                        Please don't reply to gerrit emails. They're not slurped back into Gerrit and it fragments conversation.


                        On Sat, Mar 25, 2017 at 9:19 AM, ron minnich <rmin...@gmail.com> wrote:
                        man that's weird, that's a really innocuous change. Not sure if you can but if you can get me access to an ARM system somehow I'm happy to look. My ARM system is still in the mail.

                        Also, if there is an unshare command on that system, this change is equivalent to unshare -m /bin/date, so if you want to strace that and send me output I can take a look.

                        thanks

                        ron

                        On Sat, Mar 25, 2017 at 6:49 AM Elias Naur (Gerrit) <noreply-gerritcodereview-2DDInOvE1MrCWMxYGxqB3g@google.com> wrote:

                        Elias Naur posted comments on this change.

                        View Change

                        Patch set 10:

                        This CL seems to have broken the (only) linux/arm64 builder:

                        https://build.golang.org/log/a2fd112da23e96e2c5ea00840544a1ddb6f45a2c

                          To view, visit change 38471. To unsubscribe, visit settings.

                          Gerrit-Project: go
                          Gerrit-Branch: master
                          Gerrit-MessageType: comment
                          Gerrit-Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
                          Gerrit-Change-Number: 38471
                          Gerrit-PatchSet: 10
                          Gerrit-Owner: ron minnich <rmin...@gmail.com>
                          Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
                          Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
                          Gerrit-Reviewer: ron minnich <rmin...@gmail.com>
                          Gerrit-CC: Elias Naur <elias...@gmail.com>
                          Gerrit-Comment-Date: Sat, 25 Mar 2017 13:49:00 +0000
                          Gerrit-HasComments: No

                          --
                          You received this message because you are subscribed to the Google Groups "golang-codereviews" group.
                          To unsubscribe from this group and stop receiving emails from it, send an email to golang-codereviews+unsub...@googlegroups.com.
                          For more options, visit https://groups.google.com/d/optout.

                          ron minnich (Gerrit)

                          unread,
                          Mar 25, 2017, 1:31:20 PM3/25/17
                          to Ian Lance Taylor, Elias Naur, Gobot Gobot, golang-co...@googlegroups.com

                          ron minnich posted comments on this change.

                          View Change

                          Patch set 10:

                          if you can get me to a box to try I can take a look. My ARM is in the mail.

                          Do you have an unshare command on that system? can you
                          sudo strace unshare -m /bin/bash
                          and send me the output?

                            To view, visit change 38471. To unsubscribe, visit settings.

                            Gerrit-Project: go
                            Gerrit-Branch: master
                            Gerrit-MessageType: comment
                            Gerrit-Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
                            Gerrit-Change-Number: 38471
                            Gerrit-PatchSet: 10
                            Gerrit-Owner: ron minnich <rmin...@gmail.com>
                            Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
                            Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
                            Gerrit-Reviewer: ron minnich <rmin...@gmail.com>
                            Gerrit-CC: Elias Naur <elias...@gmail.com>
                            Gerrit-Comment-Date: Sat, 25 Mar 2017 17:31:18 +0000
                            Gerrit-HasComments: No

                            Brad Fitzpatrick (Gerrit)

                            unread,
                            Mar 25, 2017, 1:39:55 PM3/25/17
                            to Ian Lance Taylor, ron minnich, Brad Fitzpatrick, Elias Naur, Gobot Gobot, golang-co...@googlegroups.com

                            Brad Fitzpatrick posted comments on this change.

                            View Change

                            Patch set 10:

                            Ron, the tests need to pass as a regular user too.

                            I think you need to modify the tests to t.Skip on any permissions error, at least if the user isn't Uid 0.

                              To view, visit change 38471. To unsubscribe, visit settings.

                              Gerrit-Project: go
                              Gerrit-Branch: master
                              Gerrit-MessageType: comment
                              Gerrit-Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
                              Gerrit-Change-Number: 38471
                              Gerrit-PatchSet: 10
                              Gerrit-Owner: ron minnich <rmin...@gmail.com>
                              Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
                              Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
                              Gerrit-Reviewer: ron minnich <rmin...@gmail.com>
                              Gerrit-CC: Brad Fitzpatrick <brad...@golang.org>
                              Gerrit-CC: Elias Naur <elias...@gmail.com>
                              Gerrit-Comment-Date: Sat, 25 Mar 2017 17:39:52 +0000
                              Gerrit-HasComments: No

                              ron minnich (Gerrit)

                              unread,
                              Mar 25, 2017, 1:44:12 PM3/25/17
                              to Ian Lance Taylor, Brad Fitzpatrick, Elias Naur, Gobot Gobot, golang-co...@googlegroups.com

                              ron minnich posted comments on this change.

                              View Change

                              Patch set 10:

                              First three lines of the test:
                              if os.Getuid() != 0 {

                              t.Skip("kernel prohibits unshare in unprivileged process, unless using user namespace")
                              }

                              Why isn't that sufficient? On my system it prints the message and skips the test if I run as ! root

                                To view, visit change 38471. To unsubscribe, visit settings.

                                Gerrit-Project: go
                                Gerrit-Branch: master
                                Gerrit-MessageType: comment
                                Gerrit-Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
                                Gerrit-Change-Number: 38471
                                Gerrit-PatchSet: 10
                                Gerrit-Owner: ron minnich <rmin...@gmail.com>
                                Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
                                Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
                                Gerrit-Reviewer: ron minnich <rmin...@gmail.com>
                                Gerrit-CC: Brad Fitzpatrick <brad...@golang.org>
                                Gerrit-CC: Elias Naur <elias...@gmail.com>
                                Gerrit-Comment-Date: Sat, 25 Mar 2017 17:44:10 +0000
                                Gerrit-HasComments: No

                                Brad Fitzpatrick (Gerrit)

                                unread,
                                Mar 25, 2017, 1:47:13 PM3/25/17
                                to Ian Lance Taylor, ron minnich, Brad Fitzpatrick, Elias Naur, Gobot Gobot, golang-co...@googlegroups.com

                                Brad Fitzpatrick posted comments on this change.

                                View Change

                                Patch set 10:

                                Oh, hm. No clue.

                                  To view, visit change 38471. To unsubscribe, visit settings.

                                  Gerrit-Project: go
                                  Gerrit-Branch: master
                                  Gerrit-MessageType: comment
                                  Gerrit-Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
                                  Gerrit-Change-Number: 38471
                                  Gerrit-PatchSet: 10
                                  Gerrit-Owner: ron minnich <rmin...@gmail.com>
                                  Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
                                  Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
                                  Gerrit-Reviewer: ron minnich <rmin...@gmail.com>
                                  Gerrit-CC: Brad Fitzpatrick <brad...@golang.org>
                                  Gerrit-CC: Elias Naur <elias...@gmail.com>
                                  Gerrit-Comment-Date: Sat, 25 Mar 2017 17:47:12 +0000
                                  Gerrit-HasComments: No

                                  Elias Naur (Gerrit)

                                  unread,
                                  Mar 25, 2017, 1:53:51 PM3/25/17
                                  to Ian Lance Taylor, ron minnich, Brad Fitzpatrick, Gobot Gobot, golang-co...@googlegroups.com

                                  Elias Naur posted comments on this change.

                                  View Change

                                  Patch set 10:

                                  Patch Set 10:

                                  if you can get me to a box to try I can take a look. My ARM is in the mail.

                                  Do you have an unshare command on that system? can you
                                  sudo strace unshare -m /bin/bash
                                  and send me the output?

                                  I don't have access to a linux/arm64 machine. I merely followed the string of broken builds :) Perhaps Brad or someone else is able to get you access (is that what gomote can do?).

                                    To view, visit change 38471. To unsubscribe, visit settings.

                                    Gerrit-Project: go
                                    Gerrit-Branch: master
                                    Gerrit-MessageType: comment
                                    Gerrit-Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
                                    Gerrit-Change-Number: 38471
                                    Gerrit-PatchSet: 10
                                    Gerrit-Owner: ron minnich <rmin...@gmail.com>
                                    Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
                                    Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
                                    Gerrit-Reviewer: ron minnich <rmin...@gmail.com>
                                    Gerrit-CC: Brad Fitzpatrick <brad...@golang.org>
                                    Gerrit-CC: Elias Naur <elias...@gmail.com>
                                    Gerrit-Comment-Date: Sat, 25 Mar 2017 17:53:48 +0000
                                    Gerrit-HasComments: No

                                    ron minnich (Gerrit)

                                    unread,
                                    Mar 25, 2017, 2:28:26 PM3/25/17
                                    to Ian Lance Taylor, Brad Fitzpatrick, Elias Naur, Gobot Gobot, golang-co...@googlegroups.com

                                    ron minnich posted comments on this change.

                                    View Change

                                    Patch set 10:

                                    Thanks very much for catching this. Can someone do a uname -a and cat /etc/issue on that machine? I'll set up a VM I guess to try to recreate what's going on. I have little experience with the builder infrastructure, sorry.

                                      To view, visit change 38471. To unsubscribe, visit settings.

                                      Gerrit-Project: go
                                      Gerrit-Branch: master
                                      Gerrit-MessageType: comment
                                      Gerrit-Change-Id: I52240b59628e3772b529d9bbef7166606b0c157d
                                      Gerrit-Change-Number: 38471
                                      Gerrit-PatchSet: 10
                                      Gerrit-Owner: ron minnich <rmin...@gmail.com>
                                      Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
                                      Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
                                      Gerrit-Reviewer: ron minnich <rmin...@gmail.com>
                                      Gerrit-CC: Brad Fitzpatrick <brad...@golang.org>
                                      Gerrit-CC: Elias Naur <elias...@gmail.com>
                                      Gerrit-Comment-Date: Sat, 25 Mar 2017 18:28:24 +0000
                                      Gerrit-HasComments: No
                                      Reply all
                                      Reply to author
                                      Forward
                                      0 new messages