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