|
@@ -8,46 +8,83 @@ import (
|
|
|
"github.com/containerd/containerd/pkg/apparmor"
|
|
|
containertypes "github.com/docker/docker/api/types/container"
|
|
|
"github.com/docker/docker/container"
|
|
|
+ "github.com/docker/docker/daemon/config"
|
|
|
"github.com/docker/docker/daemon/exec"
|
|
|
specs "github.com/opencontainers/runtime-spec/specs-go"
|
|
|
"gotest.tools/v3/assert"
|
|
|
)
|
|
|
|
|
|
-func TestExecSetPlatformOpt(t *testing.T) {
|
|
|
- if !apparmor.HostSupports() {
|
|
|
- t.Skip("requires AppArmor to be enabled")
|
|
|
+func TestExecSetPlatformOptAppArmor(t *testing.T) {
|
|
|
+ appArmorEnabled := apparmor.HostSupports()
|
|
|
+
|
|
|
+ tests := []struct {
|
|
|
+ doc string
|
|
|
+ privileged bool
|
|
|
+ appArmorProfile string
|
|
|
+ expectedProfile string
|
|
|
+ }{
|
|
|
+ {
|
|
|
+ doc: "default options",
|
|
|
+ expectedProfile: defaultAppArmorProfile,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ doc: "custom profile",
|
|
|
+ appArmorProfile: "my-custom-profile",
|
|
|
+ expectedProfile: "my-custom-profile",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ doc: "privileged container",
|
|
|
+ privileged: true,
|
|
|
+ expectedProfile: unconfinedAppArmorProfile,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ doc: "privileged container, custom profile",
|
|
|
+ privileged: true,
|
|
|
+ appArmorProfile: "my-custom-profile",
|
|
|
+ expectedProfile: "my-custom-profile",
|
|
|
+ // FIXME: execSetPlatformOpts prefers custom profiles over "privileged",
|
|
|
+ // which looks like a bug (--privileged on the container should
|
|
|
+ // disable apparmor, seccomp, and selinux); see the code at:
|
|
|
+ // https://github.com/moby/moby/blob/46cdcd206c56172b95ba5c77b827a722dab426c5/daemon/exec_linux.go#L32-L40
|
|
|
+ // expectedProfile: unconfinedAppArmorProfile,
|
|
|
+ },
|
|
|
}
|
|
|
- d := &Daemon{}
|
|
|
- c := &container.Container{AppArmorProfile: "my-custom-profile"}
|
|
|
- ec := &exec.Config{}
|
|
|
- p := &specs.Process{}
|
|
|
-
|
|
|
- err := d.execSetPlatformOpt(c, ec, p)
|
|
|
- assert.NilError(t, err)
|
|
|
- assert.Equal(t, "my-custom-profile", p.ApparmorProfile)
|
|
|
-}
|
|
|
|
|
|
-// TestExecSetPlatformOptPrivileged verifies that `docker exec --privileged`
|
|
|
-// does not disable AppArmor profiles. Exec currently inherits the `Privileged`
|
|
|
-// configuration of the container. See https://github.com/moby/moby/pull/31773#discussion_r105586900
|
|
|
-//
|
|
|
-// This behavior may change in future, but test for the behavior to prevent it
|
|
|
-// from being changed accidentally.
|
|
|
-func TestExecSetPlatformOptPrivileged(t *testing.T) {
|
|
|
- if !apparmor.HostSupports() {
|
|
|
- t.Skip("requires AppArmor to be enabled")
|
|
|
+ d := &Daemon{configStore: &config.Config{}}
|
|
|
+
|
|
|
+ // Currently, `docker exec --privileged` inherits the Privileged configuration
|
|
|
+ // of the container, and does not disable AppArmor.
|
|
|
+ // See https://github.com/moby/moby/pull/31773#discussion_r105586900
|
|
|
+ //
|
|
|
+ // This behavior may change in future, but to verify the current behavior,
|
|
|
+ // we run the test both with "exec" and "exec --privileged", which should
|
|
|
+ // both give the same result.
|
|
|
+ for _, execPrivileged := range []bool{false, true} {
|
|
|
+ for _, tc := range tests {
|
|
|
+ tc := tc
|
|
|
+ doc := tc.doc
|
|
|
+ if !appArmorEnabled {
|
|
|
+ // no profile should be set if the host does not support AppArmor
|
|
|
+ doc += " (apparmor disabled)"
|
|
|
+ tc.expectedProfile = ""
|
|
|
+ }
|
|
|
+ if execPrivileged {
|
|
|
+ doc += " (exec privileged)"
|
|
|
+ }
|
|
|
+ t.Run(doc, func(t *testing.T) {
|
|
|
+ c := &container.Container{
|
|
|
+ AppArmorProfile: tc.appArmorProfile,
|
|
|
+ HostConfig: &containertypes.HostConfig{
|
|
|
+ Privileged: tc.privileged,
|
|
|
+ },
|
|
|
+ }
|
|
|
+ ec := &exec.Config{Privileged: execPrivileged}
|
|
|
+ p := &specs.Process{}
|
|
|
+
|
|
|
+ err := d.execSetPlatformOpt(c, ec, p)
|
|
|
+ assert.NilError(t, err)
|
|
|
+ assert.Equal(t, p.ApparmorProfile, tc.expectedProfile)
|
|
|
+ })
|
|
|
+ }
|
|
|
}
|
|
|
- d := &Daemon{}
|
|
|
- c := &container.Container{AppArmorProfile: "my-custom-profile"}
|
|
|
- ec := &exec.Config{Privileged: true}
|
|
|
- p := &specs.Process{}
|
|
|
-
|
|
|
- err := d.execSetPlatformOpt(c, ec, p)
|
|
|
- assert.NilError(t, err)
|
|
|
- assert.Equal(t, "my-custom-profile", p.ApparmorProfile)
|
|
|
-
|
|
|
- c.HostConfig = &containertypes.HostConfig{Privileged: true}
|
|
|
- err = d.execSetPlatformOpt(c, ec, p)
|
|
|
- assert.NilError(t, err)
|
|
|
- assert.Equal(t, unconfinedAppArmorProfile, p.ApparmorProfile)
|
|
|
}
|