Merge pull request #18780 from jfrazelle/seccomp-default

set default seccomp profile
Upstream-commit: 78ce43bad85fdf97d7c836315e46b531901c8ae7
Component: engine
This commit is contained in:
David Calavera
2015-12-28 16:46:30 -08:00
12 changed files with 521 additions and 6 deletions
@@ -2858,18 +2858,25 @@ func (s *DockerSuite) TestRunUnshareProc(c *check.C) {
testRequires(c, Apparmor, DaemonIsLinux, NotUserNamespace)
name := "acidburn"
if out, _, err := dockerCmdWithError("run", "--name", name, "jess/unshare", "unshare", "-p", "-m", "-f", "-r", "--mount-proc=/proc", "mount"); err == nil || !strings.Contains(out, "Permission denied") {
out, _, err := dockerCmdWithError("run", "--name", name, "--security-opt", "seccomp:unconfined", "jess/unshare", "unshare", "-p", "-m", "-f", "-r", "--mount-proc=/proc", "mount")
if err == nil ||
!(strings.Contains(strings.ToLower(out), "permission denied") ||
strings.Contains(strings.ToLower(out), "operation not permitted")) {
c.Fatalf("unshare with --mount-proc should have failed with permission denied, got: %s, %v", out, err)
}
name = "cereal"
if out, _, err := dockerCmdWithError("run", "--name", name, "jess/unshare", "unshare", "-p", "-m", "-f", "-r", "mount", "-t", "proc", "none", "/proc"); err == nil || !strings.Contains(out, "Permission denied") {
out, _, err = dockerCmdWithError("run", "--name", name, "--security-opt", "seccomp:unconfined", "jess/unshare", "unshare", "-p", "-m", "-f", "-r", "mount", "-t", "proc", "none", "/proc")
if err == nil ||
!(strings.Contains(strings.ToLower(out), "permission denied") ||
strings.Contains(strings.ToLower(out), "operation not permitted")) {
c.Fatalf("unshare and mount of /proc should have failed with permission denied, got: %s, %v", out, err)
}
/* Ensure still fails if running privileged with the default policy */
name = "crashoverride"
if out, _, err := dockerCmdWithError("run", "--privileged", "--security-opt", "apparmor:docker-default", "--name", name, "jess/unshare", "unshare", "-p", "-m", "-f", "-r", "mount", "-t", "proc", "none", "/proc"); err == nil || !(strings.Contains(strings.ToLower(out), "permission denied") || strings.Contains(strings.ToLower(out), "operation not permitted")) {
out, _, err = dockerCmdWithError("run", "--privileged", "--security-opt", "seccomp:unconfined", "--security-opt", "apparmor:docker-default", "--name", name, "jess/unshare", "unshare", "-p", "-m", "-f", "-r", "mount", "-t", "proc", "none", "/proc")
if err == nil || !(strings.Contains(strings.ToLower(out), "permission denied") || strings.Contains(strings.ToLower(out), "operation not permitted")) {
c.Fatalf("privileged unshare with apparmor should have failed with permission denied, got: %s, %v", out, err)
}
}
@@ -514,7 +514,7 @@ func (s *DockerSuite) TestRunSeccompProfileDenyUnshare(c *check.C) {
if _, err := tmpFile.Write([]byte(jsonData)); err != nil {
c.Fatal(err)
}
runCmd := exec.Command(dockerBinary, "run", "--security-opt", "seccomp:"+tmpFile.Name(), "jess/unshare", "unshare", "-p", "-m", "-f", "-r", "mount", "-t", "proc", "none", "/proc")
runCmd := exec.Command(dockerBinary, "run", "--security-opt", "apparmor:unconfined", "--security-opt", "seccomp:"+tmpFile.Name(), "debian:jessie", "unshare", "-p", "-m", "-f", "-r", "mount", "-t", "proc", "none", "/proc")
out, _, _ := runCommandWithOutput(runCmd)
if !strings.Contains(out, "Operation not permitted") {
c.Fatalf("expected unshare with seccomp profile denied to fail, got %s", out)
@@ -548,3 +548,87 @@ func (s *DockerSuite) TestRunSeccompProfileDenyChmod(c *check.C) {
c.Fatalf("expected chmod with seccomp profile denied to fail, got %s", out)
}
}
// TestRunSeccompProfileDenyUnshareUserns checks that 'docker run jess/unshare unshare --map-root-user --user sh -c whoami' with a specific profile to
// deny unhare of a userns exits with operation not permitted.
func (s *DockerSuite) TestRunSeccompProfileDenyUnshareUserns(c *check.C) {
testRequires(c, SameHostDaemon, seccompEnabled)
// from sched.h
jsonData := fmt.Sprintf(`{
"defaultAction": "SCMP_ACT_ALLOW",
"syscalls": [
{
"name": "unshare",
"action": "SCMP_ACT_ERRNO",
"args": [
{
"index": 0,
"value": %d,
"op": "SCMP_CMP_EQ"
}
]
}
]
}`, uint64(0x10000000))
tmpFile, err := ioutil.TempFile("", "profile.json")
defer tmpFile.Close()
if err != nil {
c.Fatal(err)
}
if _, err := tmpFile.Write([]byte(jsonData)); err != nil {
c.Fatal(err)
}
runCmd := exec.Command(dockerBinary, "run", "--security-opt", "apparmor:unconfined", "--security-opt", "seccomp:"+tmpFile.Name(), "debian:jessie", "unshare", "--map-root-user", "--user", "sh", "-c", "whoami")
out, _, _ := runCommandWithOutput(runCmd)
if !strings.Contains(out, "Operation not permitted") {
c.Fatalf("expected unshare userns with seccomp profile denied to fail, got %s", out)
}
}
// TestRunSeccompProfileDenyCloneUserns checks that 'docker run userns-test'
// with a the default seccomp profile exits with operation not permitted.
func (s *DockerSuite) TestRunSeccompProfileDenyCloneUserns(c *check.C) {
testRequires(c, SameHostDaemon, seccompEnabled)
runCmd := exec.Command(dockerBinary, "run", "userns-test", "id")
out, _, err := runCommandWithOutput(runCmd)
if err == nil || !strings.Contains(out, "clone failed: Operation not permitted") {
c.Fatalf("expected clone userns with default seccomp profile denied to fail, got %s: %v", out, err)
}
}
// TestRunSeccompUnconfinedCloneUserns checks that
// 'docker run --security-opt seccomp:unconfined userns-test' allows creating a userns.
func (s *DockerSuite) TestRunSeccompUnconfinedCloneUserns(c *check.C) {
testRequires(c, SameHostDaemon, seccompEnabled, NotUserNamespace)
// make sure running w privileged is ok
runCmd := exec.Command(dockerBinary, "run", "--security-opt", "seccomp:unconfined", "userns-test", "id")
if out, _, err := runCommandWithOutput(runCmd); err != nil || !strings.Contains(out, "nobody") {
c.Fatalf("expected clone userns with --security-opt seccomp:unconfined to succeed, got %s: %v", out, err)
}
}
// TestRunSeccompAllowPrivCloneUserns checks that 'docker run --privileged userns-test'
// allows creating a userns.
func (s *DockerSuite) TestRunSeccompAllowPrivCloneUserns(c *check.C) {
testRequires(c, SameHostDaemon, seccompEnabled, NotUserNamespace)
// make sure running w privileged is ok
runCmd := exec.Command(dockerBinary, "run", "--privileged", "userns-test", "id")
if out, _, err := runCommandWithOutput(runCmd); err != nil || !strings.Contains(out, "nobody") {
c.Fatalf("expected clone userns with --privileged to succeed, got %s: %v", out, err)
}
}
// TestRunSeccompAllowAptKey checks that 'docker run debian:jessie apt-key' succeeds.
func (s *DockerSuite) TestRunSeccompAllowAptKey(c *check.C) {
testRequires(c, SameHostDaemon, seccompEnabled)
// apt-key uses setrlimit & getrlimit, so we want to make sure we don't break it
runCmd := exec.Command(dockerBinary, "run", "debian:jessie", "apt-key", "adv", "--keyserver", "hkp://p80.pool.sks-keyservers.net:80", "--recv-keys", "E871F18B51E0147C77796AC81196BA81F6B0FC61")
if out, _, err := runCommandWithOutput(runCmd); err != nil {
c.Fatalf("expected apt-key with seccomp to succeed, got %s: %v", out, err)
}
}