Only explicitly deny ptrace for container-originated procs

The 'deny ptrace' statement was supposed to only ignore
ptrace failures in the AUDIT log. However, ptrace was implicitly
allowed from unconfined processes (such as the docker daemon and
its integration tests) due to the abstractions/base include.

This rule narrows the definition such that it will only ignore
the failures originating inside of the container and will not
cause denials when the daemon or its tests ptrace inside processes.

Introduces positive and negative tests for ptrace /w apparmor.

Signed-off-by: Eric Windisch <eric@windisch.us>
(cherry picked from commit f5c388b35a)
This commit is contained in:
Eric Windisch
2015-07-30 12:54:21 -04:00
committed by David Calavera
parent 559043b953
commit f156fb7be5
2 changed files with 40 additions and 1 deletions
+1 -1
View File
@@ -50,7 +50,7 @@ profile {{.Name}} flags=(attach_disconnected,mediate_deleted) {
deny @{PROC}/sys/kernel/*/** wklx,
deny mount,
deny ptrace,
deny ptrace (trace) peer=docker-default,
deny /sys/[^f]*/** wklx,
deny /sys/f[^s]*/** wklx,
+39
View File
@@ -2729,3 +2729,42 @@ func (s *DockerTrustSuite) TestTrustedRunFromBadTrustServer(c *check.C) {
c.Fatalf("Missing expected output on trusted push:\n%s", out)
}
}
func (s *DockerSuite) TestPtraceContainerProcsFromHost(c *check.C) {
testRequires(c, SameHostDaemon)
out, _ := dockerCmd(c, "run", "-d", "busybox", "top")
id := strings.TrimSpace(out)
if err := waitRun(id); err != nil {
c.Fatal(err)
}
pid1, err := inspectField(id, "State.Pid")
c.Assert(err, check.IsNil)
_, err = os.Readlink(fmt.Sprintf("/proc/%s/ns/net", pid1))
if err != nil {
c.Fatal(err)
}
}
func (s *DockerSuite) TestAppArmorDeniesPtrace(c *check.C) {
testRequires(c, SameHostDaemon)
testRequires(c, Apparmor)
// Run through 'sh' so we are NOT pid 1. Pid 1 may be able to trace
// itself, but pid>1 should not be able to trace pid1.
_, exitCode, _ := dockerCmdWithError("run", "busybox", "sh", "-c", "readlink /proc/1/ns/net")
if exitCode == 0 {
c.Fatal("ptrace was not successfully restricted by AppArmor")
}
}
func (s *DockerSuite) TestAppArmorTraceSelf(c *check.C) {
testRequires(c, SameHostDaemon)
testRequires(c, Apparmor)
_, exitCode, _ := dockerCmdWithError("run", "busybox", "readlink", "/proc/1/ns/net")
if exitCode != 0 {
c.Fatal("ptrace of self failed.")
}
}