exec_linux_test.go 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. //go:build linux
  2. package daemon
  3. import (
  4. "context"
  5. "testing"
  6. "github.com/containerd/containerd/pkg/apparmor"
  7. containertypes "github.com/docker/docker/api/types/container"
  8. "github.com/docker/docker/container"
  9. specs "github.com/opencontainers/runtime-spec/specs-go"
  10. "gotest.tools/v3/assert"
  11. )
  12. func TestExecSetPlatformOptAppArmor(t *testing.T) {
  13. appArmorEnabled := apparmor.HostSupports()
  14. tests := []struct {
  15. doc string
  16. privileged bool
  17. appArmorProfile string
  18. expectedProfile string
  19. }{
  20. {
  21. doc: "default options",
  22. expectedProfile: defaultAppArmorProfile,
  23. },
  24. {
  25. doc: "custom profile",
  26. appArmorProfile: "my-custom-profile",
  27. expectedProfile: "my-custom-profile",
  28. },
  29. {
  30. doc: "privileged container",
  31. privileged: true,
  32. expectedProfile: unconfinedAppArmorProfile,
  33. },
  34. {
  35. doc: "privileged container, custom profile",
  36. privileged: true,
  37. appArmorProfile: "my-custom-profile",
  38. expectedProfile: "my-custom-profile",
  39. // FIXME: execSetPlatformOpts prefers custom profiles over "privileged",
  40. // which looks like a bug (--privileged on the container should
  41. // disable apparmor, seccomp, and selinux); see the code at:
  42. // https://github.com/moby/moby/blob/46cdcd206c56172b95ba5c77b827a722dab426c5/daemon/exec_linux.go#L32-L40
  43. // expectedProfile: unconfinedAppArmorProfile,
  44. },
  45. }
  46. cfg := &configStore{}
  47. d := &Daemon{}
  48. d.configStore.Store(cfg)
  49. // Currently, `docker exec --privileged` inherits the Privileged configuration
  50. // of the container, and does not disable AppArmor.
  51. // See https://github.com/moby/moby/pull/31773#discussion_r105586900
  52. //
  53. // This behavior may change in future, but to verify the current behavior,
  54. // we run the test both with "exec" and "exec --privileged", which should
  55. // both give the same result.
  56. for _, execPrivileged := range []bool{false, true} {
  57. for _, tc := range tests {
  58. tc := tc
  59. doc := tc.doc
  60. if !appArmorEnabled {
  61. // no profile should be set if the host does not support AppArmor
  62. doc += " (apparmor disabled)"
  63. tc.expectedProfile = ""
  64. }
  65. if execPrivileged {
  66. doc += " (exec privileged)"
  67. }
  68. t.Run(doc, func(t *testing.T) {
  69. c := &container.Container{
  70. SecurityOptions: container.SecurityOptions{AppArmorProfile: tc.appArmorProfile},
  71. HostConfig: &containertypes.HostConfig{
  72. Privileged: tc.privileged,
  73. },
  74. }
  75. ec := &container.ExecConfig{Container: c, Privileged: execPrivileged}
  76. p := &specs.Process{}
  77. err := d.execSetPlatformOpt(context.Background(), &cfg.Config, ec, p)
  78. assert.NilError(t, err)
  79. assert.Equal(t, p.ApparmorProfile, tc.expectedProfile)
  80. })
  81. }
  82. }
  83. }