exec_linux.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. package daemon // import "github.com/docker/docker/daemon"
  2. import (
  3. "context"
  4. "github.com/containerd/containerd"
  5. "github.com/containerd/containerd/containers"
  6. "github.com/containerd/containerd/oci"
  7. coci "github.com/containerd/containerd/oci"
  8. "github.com/containerd/containerd/pkg/apparmor"
  9. "github.com/docker/docker/container"
  10. "github.com/docker/docker/daemon/config"
  11. "github.com/docker/docker/oci/caps"
  12. specs "github.com/opencontainers/runtime-spec/specs-go"
  13. )
  14. func withResetAdditionalGIDs() oci.SpecOpts {
  15. return func(_ context.Context, _ oci.Client, _ *containers.Container, s *oci.Spec) error {
  16. s.Process.User.AdditionalGids = nil
  17. return nil
  18. }
  19. }
  20. func getUserFromContainerd(ctx context.Context, containerdCli *containerd.Client, ec *container.ExecConfig) (specs.User, error) {
  21. ctr, err := containerdCli.LoadContainer(ctx, ec.Container.ID)
  22. if err != nil {
  23. return specs.User{}, err
  24. }
  25. cinfo, err := ctr.Info(ctx)
  26. if err != nil {
  27. return specs.User{}, err
  28. }
  29. spec, err := ctr.Spec(ctx)
  30. if err != nil {
  31. return specs.User{}, err
  32. }
  33. opts := []oci.SpecOpts{
  34. coci.WithUser(ec.User),
  35. withResetAdditionalGIDs(),
  36. coci.WithAdditionalGIDs(ec.User),
  37. }
  38. for _, opt := range opts {
  39. if err := opt(ctx, containerdCli, &cinfo, spec); err != nil {
  40. return specs.User{}, err
  41. }
  42. }
  43. return spec.Process.User, nil
  44. }
  45. func (daemon *Daemon) execSetPlatformOpt(ctx context.Context, daemonCfg *config.Config, ec *container.ExecConfig, p *specs.Process) error {
  46. if len(ec.User) > 0 {
  47. var err error
  48. if daemon.UsesSnapshotter() {
  49. p.User, err = getUserFromContainerd(ctx, daemon.containerdClient, ec)
  50. if err != nil {
  51. return err
  52. }
  53. } else {
  54. p.User, err = getUser(ec.Container, ec.User)
  55. if err != nil {
  56. return err
  57. }
  58. }
  59. }
  60. if ec.Privileged {
  61. p.Capabilities = &specs.LinuxCapabilities{
  62. Bounding: caps.GetAllCapabilities(),
  63. Permitted: caps.GetAllCapabilities(),
  64. Effective: caps.GetAllCapabilities(),
  65. }
  66. }
  67. if apparmor.HostSupports() {
  68. var appArmorProfile string
  69. if ec.Container.AppArmorProfile != "" {
  70. appArmorProfile = ec.Container.AppArmorProfile
  71. } else if ec.Container.HostConfig.Privileged {
  72. // `docker exec --privileged` does not currently disable AppArmor
  73. // profiles. Privileged configuration of the container is inherited
  74. appArmorProfile = unconfinedAppArmorProfile
  75. } else {
  76. appArmorProfile = defaultAppArmorProfile
  77. }
  78. if appArmorProfile == defaultAppArmorProfile {
  79. // Unattended upgrades and other fun services can unload AppArmor
  80. // profiles inadvertently. Since we cannot store our profile in
  81. // /etc/apparmor.d, nor can we practically add other ways of
  82. // telling the system to keep our profile loaded, in order to make
  83. // sure that we keep the default profile enabled we dynamically
  84. // reload it if necessary.
  85. if err := ensureDefaultAppArmorProfile(); err != nil {
  86. return err
  87. }
  88. }
  89. p.ApparmorProfile = appArmorProfile
  90. }
  91. s := &specs.Spec{Process: p}
  92. return withRlimits(daemon, daemonCfg, ec.Container)(ctx, nil, nil, s)
  93. }