From 70294dc093192319c963729256cfe48190e47dc4 Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Tue, 29 May 2018 11:29:28 -0700 Subject: [PATCH 1/5] tests/coreos.basic/DbusPerms: Set SELinux to permissive mode With the current SELinux policy the core user does not have rights to execute RestartUnit. Set SELinux to permisive mode so this test can run. Fixes runtime errors like these: kolet: RestartUnit failed: Error: Timeout was reached Signed-off-by: Geoff Levand --- kola/tests/coretest/core.go | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/kola/tests/coretest/core.go b/kola/tests/coretest/core.go index f86cd5eca..189b99b6d 100644 --- a/kola/tests/coretest/core.go +++ b/kola/tests/coretest/core.go @@ -191,7 +191,19 @@ func TestNTPDate() error { // This execs gdbus, because we need to change uses to test perms. func TestDbusPerms() error { + // With the current SELinux policy the core user does not have access + // to the systemd RestartUnit method. Set SELinux to permisive + // mode so this test can run. c := exec.Command( + "sudo", "setenforce", "0", + ) + out, err := c.CombinedOutput() + + if err != nil { + return fmt.Errorf("setenforce faied: Err:%s\n Out:%s", err, string(out)) + } + + c = exec.Command( "sudo", "-u", "core", "gdbus", "call", "--system", "--dest", "org.freedesktop.systemd1", @@ -199,12 +211,11 @@ func TestDbusPerms() error { "--method", "org.freedesktop.systemd1.Manager.RestartUnit", "ntpd.service", "replace", ) - out, err := c.CombinedOutput() + out, err = c.CombinedOutput() if err != nil { - if !strings.Contains(string(out), "org.freedesktop.DBus.Error.AccessDenied") && - !strings.Contains(string(out), "org.freedesktop.DBus.Error.InteractiveAuthorizationRequired") { - return err + if !strings.Contains(string(out), "org.freedesktop.DBus.Error.InteractiveAuthorizationRequired") { + return fmt.Errorf("RestartUnit failed: Err:%s\n Out:%s", err, string(out)) } } else { return fmt.Errorf("We were able to call RestartUnit as a non-root user.") @@ -221,7 +232,7 @@ func TestDbusPerms() error { out, err = c.CombinedOutput() if err != nil { - return fmt.Errorf("Err:%s\n Out:%v", err, out) + return fmt.Errorf("GetAll failed: Err:%s\n Out:%s", err, string(out)) } return nil } From dfb12a6088e4ce8cdefa40ca9491e91d11b1fc86 Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Tue, 29 May 2018 11:29:28 -0700 Subject: [PATCH 2/5] tests/docker.base/user-no-caps: Set SELinux to permissive mode With the current SELinux policy the docker daemon does not have access to the '/root' directory. Set SELinux to permisive mode so this test can run. Fixes runtime errors like these: Error response from daemon: OCI runtime create failed: "mkdir /var/lib/docker/overlay2/.../merged/root: permission denied Signed-off-by: Geoff Levand --- kola/tests/docker/docker.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/kola/tests/docker/docker.go b/kola/tests/docker/docker.go index 6200d37cc..259ec6027 100644 --- a/kola/tests/docker/docker.go +++ b/kola/tests/docker/docker.go @@ -435,6 +435,11 @@ func dockerUserNoCaps(c cluster.TestCluster) { genDockerContainer(c, m, "captest", []string{"capsh", "sh", "grep", "cat", "ls"}) + // With the current SELinux policy the docker daemon does not have + // access to the '/root' directory. Set SELinux to permisive mode + // so this test can run. + c.MustSSH(m, "sudo setenforce 0") + output := c.MustSSH(m, `docker run --user 1000:1000 \ -v /root:/root \ captest sh -c \ From af55deb55dffda32abb37859e2c9cf25f0eb3052 Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Tue, 29 May 2018 11:29:28 -0700 Subject: [PATCH 3/5] tests/docker.userns: Set SELinux to permissive mode A docker bug causes the docker daemon to fail in creating a container when the '--userns-remap' option is used and SELinux is enforcing. Set SELinux to permisive mode so this test can run. See: https://github.com/opencontainers/runc/pull/1562 (nsenter: improve namespace creation and SELinux IPC handling). Fixes runtime errors like these: OCI runtime create failed: running exec setns process for init caused exit Signed-off-by: Geoff Levand --- kola/tests/docker/docker.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/kola/tests/docker/docker.go b/kola/tests/docker/docker.go index 259ec6027..bddda1061 100644 --- a/kola/tests/docker/docker.go +++ b/kola/tests/docker/docker.go @@ -381,7 +381,13 @@ func dockerUserns(c cluster.TestCluster) { genDockerContainer(c, m, "userns-test", []string{"echo", "sleep"}) - c.MustSSH(m, `sudo setenforce 1`) + // A docker bug causes the docker daemon to fail in creating a container + // when the '--userns-remap' option is used and SELinux is enforcing. + // Set SELinux to permisive mode so this test can run. + // See: https://github.com/opencontainers/runc/pull/1562 (nsenter: + // improve namespace creation and SELinux IPC handling). + c.MustSSH(m, "sudo setenforce 0") + output := c.MustSSH(m, `docker run userns-test echo fj.fj`) if !bytes.Equal(output, []byte("fj.fj")) { c.Fatalf("expected fj.fj, got %s", string(output)) From e2be9b757ee3adf5ebb53501546cc35415668fda Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Tue, 29 May 2018 11:29:28 -0700 Subject: [PATCH 4/5] tests/docker: Add new SELinux tests Ensure that when SELinux is enforcing the docker daemon cannot create container instances with mounts to restricted directories. Signed-off-by: Geoff Levand --- kola/tests/docker/docker.go | 39 +++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/kola/tests/docker/docker.go b/kola/tests/docker/docker.go index bddda1061..d37b794a2 100644 --- a/kola/tests/docker/docker.go +++ b/kola/tests/docker/docker.go @@ -220,6 +220,8 @@ func dockerBaseTests(c cluster.TestCluster) { c.Run("resources", dockerResources) c.Run("networks-reliably", dockerNetworksReliably) c.Run("user-no-caps", dockerUserNoCaps) + c.Run("sel-restricted", dockerSelRestricted) + c.Run("sel-readonly", dockerSelReadOnly) } // using a simple container, exercise various docker options that set resource @@ -471,6 +473,43 @@ func dockerUserNoCaps(c cluster.TestCluster) { } } +// Ensure that when SELinux is enforcing the docker daemon cannot create a +// container instance with a mount to a restricted directory. +func dockerSelRestricted(c cluster.TestCluster) { + m := c.Machines()[0] + + genDockerContainer(c, m, "permtest", []string{"ls"}) + + _, stderr, _ := m.SSH("sudo setenforce 1 && docker run -v /root:/root permtest sh -c 'ls -dlZ /root'") + + if !(strings.Contains(string(stderr), "OCI runtime create failed") && + strings.Contains(string(stderr), "permission denied")) { + c.Fatalf("failed creating contanier with restricted directory: %q", string(stderr)) + } +} + +// Ensure that when SELinux is enforcing the docker daemon cannot create a +// container instance with a read-write mount to a read-only directory. +func dockerSelReadOnly(c cluster.TestCluster) { + m := c.Machines()[0] + + genDockerContainer(c, m, "writetest", []string{"echo"}) + + // Test ro mount as baseline, should succeed. + _, stderr, err := m.SSH("sudo setenforce 1 && docker run -v /etc/passwd:/etc/passwd:ro writetest sh -c 'echo badguy >> /etc/passwd'") + if err != nil { + c.Fatalf("failed creating contanier with read-only mount: %s, %v", stderr, err) + } + + // Now test rw mount. + _, stderr, _ = m.SSH("sudo setenforce 1 && docker run -v /etc/passwd:/etc/passwd:rw writetest sh -c 'echo badguy >> /etc/passwd'") + + if !(strings.Contains(string(stderr), "OCI runtime create failed") && + strings.Contains(string(stderr), "permission denied")) { + c.Fatalf("failed creating contanier with read-only directory: %q", string(stderr)) + } +} + // dockerContainerdRestart ensures containerd will restart if it dies. It tests that containerd is running, // kills it, the tests that it came back up. func dockerContainerdRestart(c cluster.TestCluster) { From b9738546d92afc8aed6a8fdac57eb7d965965d14 Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Tue, 29 May 2018 11:29:28 -0700 Subject: [PATCH 5/5] tests/selinux: Add new test coreos.selinux.logcheck Checks that no audit AVC messages appear in boot logs. Signed-off-by: Geoff Levand --- kola/tests/misc/selinux.go | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/kola/tests/misc/selinux.go b/kola/tests/misc/selinux.go index 29c6d0f9e..93ec46c5e 100644 --- a/kola/tests/misc/selinux.go +++ b/kola/tests/misc/selinux.go @@ -17,9 +17,16 @@ package misc import ( "github.com/coreos/mantle/kola/cluster" "github.com/coreos/mantle/kola/register" + "strings" ) func init() { + register.Register(®ister.Test{ + Run: SelinuxLogCheck, + ClusterSize: 1, + Name: "coreos.selinux.logcheck", + Flags: []register.Flag{register.NoEnableSelinux}, + }) register.Register(®ister.Test{ Run: SelinuxEnforce, ClusterSize: 1, @@ -28,6 +35,25 @@ func init() { }) } +// SelinuxLogCheck checks that no audit AVC messages appear in boot logs. +func SelinuxLogCheck(c cluster.TestCluster) { + m := c.Machines()[0] + + cmd := "sudo journalctl -b --no-pager | egrep 'AVC avc'" + stdout, stderr, err := m.SSH(cmd) + + if err == nil { + c.Fatalf("Found audit AVC messages in boot logs: \n%v", string(stdout)) + } + + if err.Error() == "Process exited with status 1" && + strings.TrimSpace(string(stderr)) == "" { + return // OK, nothing found. + } + + c.Fatalf("cmd '%v' failed: %v: %v.\n", string(cmd), err, string(stderr)) +} + // SelinuxEnforce checks that some basic things work after `setenforce 1` func SelinuxEnforce(c cluster.TestCluster) { m := c.Machines()[0]