github.com/moby/docker@v26.1.3+incompatible/daemon/exec_linux.go (about) 1 package daemon // import "github.com/docker/docker/daemon" 2 3 import ( 4 "context" 5 6 "github.com/containerd/containerd" 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 15 func getUserFromContainerd(ctx context.Context, containerdCli *containerd.Client, ec *container.ExecConfig) (specs.User, error) { 16 ctr, err := containerdCli.LoadContainer(ctx, ec.Container.ID) 17 if err != nil { 18 return specs.User{}, err 19 } 20 21 cinfo, err := ctr.Info(ctx) 22 if err != nil { 23 return specs.User{}, err 24 } 25 26 spec, err := ctr.Spec(ctx) 27 if err != nil { 28 return specs.User{}, err 29 } 30 31 opts := []coci.SpecOpts{ 32 coci.WithUser(ec.User), 33 coci.WithAdditionalGIDs(ec.User), 34 coci.WithAppendAdditionalGroups(ec.Container.HostConfig.GroupAdd...), 35 } 36 for _, opt := range opts { 37 if err := opt(ctx, containerdCli, &cinfo, spec); err != nil { 38 return specs.User{}, err 39 } 40 } 41 42 return spec.Process.User, nil 43 } 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 61 if ec.Privileged { 62 p.Capabilities = &specs.LinuxCapabilities{ 63 Bounding: caps.GetAllCapabilities(), 64 Permitted: caps.GetAllCapabilities(), 65 Effective: caps.GetAllCapabilities(), 66 } 67 } 68 69 if apparmor.HostSupports() { 70 var appArmorProfile string 71 if ec.Container.AppArmorProfile != "" { 72 appArmorProfile = ec.Container.AppArmorProfile 73 } else if ec.Container.HostConfig.Privileged { 74 // `docker exec --privileged` does not currently disable AppArmor 75 // profiles. Privileged configuration of the container is inherited 76 appArmorProfile = unconfinedAppArmorProfile 77 } else { 78 appArmorProfile = defaultAppArmorProfile 79 } 80 81 if appArmorProfile == defaultAppArmorProfile { 82 // Unattended upgrades and other fun services can unload AppArmor 83 // profiles inadvertently. Since we cannot store our profile in 84 // /etc/apparmor.d, nor can we practically add other ways of 85 // telling the system to keep our profile loaded, in order to make 86 // sure that we keep the default profile enabled we dynamically 87 // reload it if necessary. 88 if err := ensureDefaultAppArmorProfile(); err != nil { 89 return err 90 } 91 } 92 p.ApparmorProfile = appArmorProfile 93 } 94 s := &specs.Spec{Process: p} 95 return withRlimits(daemon, daemonCfg, ec.Container)(ctx, nil, nil, s) 96 }