syscall: skip some exec tests in container

For those tests there won't be enough permissions in containers.
I decided to go this way instead of just skipping os.IsPermission errors because
many of those tests were specifically written to check false positive permission
errors.

Fixes #21379

Change-Id: Ie25e1d6d47f85bb6b570352638440f3ac1e18e03
Reviewed-on: https://go-review.googlesource.com/58170
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/src/syscall/exec_linux_test.go b/src/syscall/exec_linux_test.go
index 114deec..79a7916 100644
--- a/src/syscall/exec_linux_test.go
+++ b/src/syscall/exec_linux_test.go
@@ -23,6 +23,24 @@
 	"unsafe"
 )
 
+func isDocker() bool {
+	_, err := os.Stat("/.dockerenv")
+	return err == nil
+}
+
+func isLXC() bool {
+	return os.Getenv("container") == "lxc"
+}
+
+func skipInContainer(t *testing.T) {
+	if isDocker() {
+		t.Skip("skip this test in Docker container")
+	}
+	if isLXC() {
+		t.Skip("skip this test in LXC container")
+	}
+}
+
 // Check if we are in a chroot by checking if the inode of / is
 // different from 2 (there is no better test available to non-root on
 // linux).
@@ -35,6 +53,7 @@
 }
 
 func checkUserNS(t *testing.T) {
+	skipInContainer(t)
 	if _, err := os.Stat("/proc/self/ns/user"); err != nil {
 		if os.IsNotExist(err) {
 			t.Skip("kernel doesn't support user namespaces")
@@ -147,6 +166,7 @@
 }
 
 func TestUnshare(t *testing.T) {
+	skipInContainer(t)
 	// Make sure we are running as root so we have permissions to use unshare
 	// and create a network namespace.
 	if os.Getuid() != 0 {
@@ -293,6 +313,7 @@
 
 // Test for Issue 38471: unshare fails because systemd has forced / to be shared
 func TestUnshareMountNameSpace(t *testing.T) {
+	skipInContainer(t)
 	// Make sure we are running as root so we have permissions to use unshare
 	// and create a network namespace.
 	if os.Getuid() != 0 {
@@ -342,6 +363,7 @@
 
 // Test for Issue 20103: unshare fails when chroot is used
 func TestUnshareMountNameSpaceChroot(t *testing.T) {
+	skipInContainer(t)
 	// Make sure we are running as root so we have permissions to use unshare
 	// and create a network namespace.
 	if os.Getuid() != 0 {
@@ -477,6 +499,7 @@
 }
 
 func TestAmbientCaps(t *testing.T) {
+	skipInContainer(t)
 	// Make sure we are running as root so we have permissions to use unshare
 	// and create a network namespace.
 	if os.Getuid() != 0 {