فهرست منبع

Merge pull request #41965 from thaJeztah/buildkit_apparmor_master

[master] Ensure AppArmor and SELinux profiles are applied when building with BuildKit
Tibor Vass 4 سال پیش
والد
کامیت
2bd6213363

+ 1 - 0
builder/builder-next/builder.go

@@ -75,6 +75,7 @@ type Opt struct {
 	Rootless            bool
 	IdentityMapping     *idtools.IdentityMapping
 	DNSConfig           config.DNSConfig
+	ApparmorProfile     string
 }
 
 // Builder can build using BuildKit backend

+ 1 - 1
builder/builder-next/controller.go

@@ -132,7 +132,7 @@ func newController(rt http.RoundTripper, opt Opt) (*control.Controller, error) {
 
 	dns := getDNSConfig(opt.DNSConfig)
 
-	exec, err := newExecutor(root, opt.DefaultCgroupParent, opt.NetworkController, dns, opt.Rootless, opt.IdentityMapping)
+	exec, err := newExecutor(root, opt.DefaultCgroupParent, opt.NetworkController, dns, opt.Rootless, opt.IdentityMapping, opt.ApparmorProfile)
 	if err != nil {
 		return nil, err
 	}

+ 2 - 1
builder/builder-next/executor_unix.go

@@ -25,7 +25,7 @@ import (
 
 const networkName = "bridge"
 
-func newExecutor(root, cgroupParent string, net libnetwork.NetworkController, dnsConfig *oci.DNSConfig, rootless bool, idmap *idtools.IdentityMapping) (executor.Executor, error) {
+func newExecutor(root, cgroupParent string, net libnetwork.NetworkController, dnsConfig *oci.DNSConfig, rootless bool, idmap *idtools.IdentityMapping, apparmorProfile string) (executor.Executor, error) {
 	netRoot := filepath.Join(root, "net")
 	networkProviders := map[pb.NetMode]network.Provider{
 		pb.NetMode_UNSET: &bridgeProvider{NetworkController: net, Root: netRoot},
@@ -52,6 +52,7 @@ func newExecutor(root, cgroupParent string, net libnetwork.NetworkController, dn
 		NoPivot:             os.Getenv("DOCKER_RAMDISK") != "",
 		IdentityMapping:     idmap,
 		DNS:                 dnsConfig,
+		ApparmorProfile:     apparmorProfile,
 	}, networkProviders)
 }
 

+ 1 - 1
builder/builder-next/executor_windows.go

@@ -11,7 +11,7 @@ import (
 	"github.com/moby/buildkit/executor/oci"
 )
 
-func newExecutor(_, _ string, _ libnetwork.NetworkController, _ *oci.DNSConfig, _ bool, _ *idtools.IdentityMapping) (executor.Executor, error) {
+func newExecutor(_, _ string, _ libnetwork.NetworkController, _ *oci.DNSConfig, _ bool, _ *idtools.IdentityMapping, _ string) (executor.Executor, error) {
 	return &winExecutor{}, nil
 }
 

+ 1 - 0
cmd/dockerd/daemon.go

@@ -297,6 +297,7 @@ func newRouterOptions(config *config.Config, d *daemon.Daemon) (routerOptions, e
 		Rootless:            d.Rootless(),
 		IdentityMapping:     d.IdentityMapping(),
 		DNSConfig:           config.DNSConfig,
+		ApparmorProfile:     daemon.DefaultApparmorProfile(),
 	})
 	if err != nil {
 		return opts, err

+ 8 - 0
daemon/apparmor_default.go

@@ -15,6 +15,14 @@ const (
 	defaultAppArmorProfile    = "docker-default"
 )
 
+// DefaultApparmorProfile returns the name of the default apparmor profile
+func DefaultApparmorProfile() string {
+	if apparmor.IsEnabled() {
+		return defaultAppArmorProfile
+	}
+	return ""
+}
+
 func ensureDefaultAppArmorProfile() error {
 	if apparmor.IsEnabled() {
 		loaded, err := aaprofile.IsLoaded(defaultAppArmorProfile)

+ 5 - 0
daemon/apparmor_default_unsupported.go

@@ -5,3 +5,8 @@ package daemon // import "github.com/docker/docker/daemon"
 func ensureDefaultAppArmorProfile() error {
 	return nil
 }
+
+// DefaultApparmorProfile returns an empty string.
+func DefaultApparmorProfile() string {
+	return ""
+}

+ 1 - 1
vendor.conf

@@ -33,7 +33,7 @@ github.com/imdario/mergo                            1afb36080aec31e0d1528973ebe6
 golang.org/x/sync                                   cd5d95a43a6e21273425c7ae415d3df9ea832eeb
 
 # buildkit
-github.com/moby/buildkit                            8142d66b5ebde79846b869fba30d9d30633e74aa # v0.8.1
+github.com/moby/buildkit                            68bb095353c65bc3993fd534c26cf77fe05e61b1 # v0.8 branch
 github.com/tonistiigi/fsutil                        0834f99b7b85462efb69b4f571a4fa3ca7da5ac9
 github.com/tonistiigi/units                         6950e57a87eaf136bbe44ef2ec8e75b9e3569de2
 github.com/grpc-ecosystem/grpc-opentracing          8e809c8a86450a29b90dcc9efbf062d0fe6d9746

+ 8 - 0
vendor/github.com/moby/buildkit/cmd/buildkitd/config/config.go

@@ -87,6 +87,10 @@ type OCIConfig struct {
 	// Decoding this is delayed in order to remove the dependency from this
 	// config pkg to stargz snapshotter's config pkg.
 	StargzSnapshotterConfig toml.Primitive `toml:"stargzSnapshotter"`
+
+	// ApparmorProfile is the name of the apparmor profile that should be used to constrain build containers.
+	// The profile should already be loaded (by a higher level system) before creating a worker.
+	ApparmorProfile string `toml:"apparmor-profile"`
 }
 
 type ContainerdConfig struct {
@@ -98,6 +102,10 @@ type ContainerdConfig struct {
 	GCConfig
 	NetworkConfig
 	Snapshotter string `toml:"snapshotter"`
+
+	// ApparmorProfile is the name of the apparmor profile that should be used to constrain build containers.
+	// The profile should already be loaded (by a higher level system) before creating a worker.
+	ApparmorProfile string `toml:"apparmor-profile"`
 }
 
 type GCPolicy struct {

+ 6 - 2
vendor/github.com/moby/buildkit/executor/oci/spec.go

@@ -16,6 +16,7 @@ import (
 	"github.com/moby/buildkit/snapshot"
 	"github.com/moby/buildkit/util/network"
 	specs "github.com/opencontainers/runtime-spec/specs-go"
+	"github.com/opencontainers/selinux/go-selinux"
 	"github.com/pkg/errors"
 )
 
@@ -35,7 +36,7 @@ const (
 
 // GenerateSpec generates spec using containerd functionality.
 // opts are ignored for s.Process, s.Hostname, and s.Mounts .
-func GenerateSpec(ctx context.Context, meta executor.Meta, mounts []executor.Mount, id, resolvConf, hostsFile string, namespace network.Namespace, processMode ProcessMode, idmap *idtools.IdentityMapping, opts ...oci.SpecOpts) (*specs.Spec, func(), error) {
+func GenerateSpec(ctx context.Context, meta executor.Meta, mounts []executor.Mount, id, resolvConf, hostsFile string, namespace network.Namespace, processMode ProcessMode, idmap *idtools.IdentityMapping, apparmorProfile string, opts ...oci.SpecOpts) (*specs.Spec, func(), error) {
 	c := &containers.Container{
 		ID: id,
 	}
@@ -52,7 +53,7 @@ func GenerateSpec(ctx context.Context, meta executor.Meta, mounts []executor.Mou
 		return nil, nil, err
 	}
 
-	if securityOpts, err := generateSecurityOpts(meta.SecurityMode); err == nil {
+	if securityOpts, err := generateSecurityOpts(meta.SecurityMode, apparmorProfile); err == nil {
 		opts = append(opts, securityOpts...)
 	} else {
 		return nil, nil, err
@@ -103,6 +104,9 @@ func GenerateSpec(ctx context.Context, meta executor.Meta, mounts []executor.Mou
 		for _, f := range releasers {
 			f()
 		}
+		if s.Process.SelinuxLabel != "" {
+			selinux.ReleaseLabel(s.Process.SelinuxLabel)
+		}
 	}
 
 	for _, m := range mounts {

+ 22 - 4
vendor/github.com/moby/buildkit/executor/oci/spec_unix.go

@@ -13,6 +13,7 @@ import (
 	"github.com/moby/buildkit/util/entitlements/security"
 	"github.com/moby/buildkit/util/system"
 	specs "github.com/opencontainers/runtime-spec/specs-go"
+	"github.com/opencontainers/selinux/go-selinux/label"
 )
 
 func generateMountOpts(resolvConf, hostsFile string) ([]oci.SpecOpts, error) {
@@ -26,15 +27,32 @@ func generateMountOpts(resolvConf, hostsFile string) ([]oci.SpecOpts, error) {
 }
 
 // generateSecurityOpts may affect mounts, so must be called after generateMountOpts
-func generateSecurityOpts(mode pb.SecurityMode) ([]oci.SpecOpts, error) {
-	if mode == pb.SecurityMode_INSECURE {
+func generateSecurityOpts(mode pb.SecurityMode, apparmorProfile string) (opts []oci.SpecOpts, _ error) {
+	switch mode {
+	case pb.SecurityMode_INSECURE:
 		return []oci.SpecOpts{
 			security.WithInsecureSpec(),
 			oci.WithWriteableCgroupfs,
 			oci.WithWriteableSysfs,
+			func(_ context.Context, _ oci.Client, _ *containers.Container, s *oci.Spec) error {
+				var err error
+				s.Process.SelinuxLabel, s.Linux.MountLabel, err = label.InitLabels([]string{"disable"})
+				return err
+			},
 		}, nil
-	} else if system.SeccompSupported() && mode == pb.SecurityMode_SANDBOX {
-		return []oci.SpecOpts{withDefaultProfile()}, nil
+	case pb.SecurityMode_SANDBOX:
+		if system.SeccompSupported() {
+			opts = append(opts, withDefaultProfile())
+		}
+		if apparmorProfile != "" {
+			opts = append(opts, oci.WithApparmorProfile(apparmorProfile))
+		}
+		opts = append(opts, func(_ context.Context, _ oci.Client, _ *containers.Container, s *oci.Spec) error {
+			var err error
+			s.Process.SelinuxLabel, s.Linux.MountLabel, err = label.InitLabels(nil)
+			return err
+		})
+		return opts, nil
 	}
 	return nil, nil
 }

+ 1 - 1
vendor/github.com/moby/buildkit/executor/oci/spec_windows.go

@@ -14,7 +14,7 @@ func generateMountOpts(resolvConf, hostsFile string) ([]oci.SpecOpts, error) {
 }
 
 // generateSecurityOpts may affect mounts, so must be called after generateMountOpts
-func generateSecurityOpts(mode pb.SecurityMode) ([]oci.SpecOpts, error) {
+func generateSecurityOpts(mode pb.SecurityMode, apparmorProfile string) ([]oci.SpecOpts, error) {
 	if mode == pb.SecurityMode_INSECURE {
 		return nil, errors.New("no support for running in insecure mode on Windows")
 	}

+ 7 - 4
vendor/github.com/moby/buildkit/executor/runcexecutor/executor.go

@@ -42,9 +42,10 @@ type Opt struct {
 	ProcessMode     oci.ProcessMode
 	IdentityMapping *idtools.IdentityMapping
 	// runc run --no-pivot (unrecommended)
-	NoPivot     bool
-	DNS         *oci.DNSConfig
-	OOMScoreAdj *int
+	NoPivot         bool
+	DNS             *oci.DNSConfig
+	OOMScoreAdj     *int
+	ApparmorProfile string
 }
 
 var defaultCommandCandidates = []string{"buildkit-runc", "runc"}
@@ -62,6 +63,7 @@ type runcExecutor struct {
 	oomScoreAdj      *int
 	running          map[string]chan error
 	mu               sync.Mutex
+	apparmorProfile  string
 }
 
 func New(opt Opt, networkProviders map[pb.NetMode]network.Provider) (executor.Executor, error) {
@@ -124,6 +126,7 @@ func New(opt Opt, networkProviders map[pb.NetMode]network.Provider) (executor.Ex
 		dns:              opt.DNS,
 		oomScoreAdj:      opt.OOMScoreAdj,
 		running:          make(map[string]chan error),
+		apparmorProfile:  opt.ApparmorProfile,
 	}
 	return w, nil
 }
@@ -253,7 +256,7 @@ func (w *runcExecutor) Run(ctx context.Context, id string, root executor.Mount,
 		}
 		opts = append(opts, containerdoci.WithCgroup(cgroupsPath))
 	}
-	spec, cleanup, err := oci.GenerateSpec(ctx, meta, mounts, id, resolvConf, hostsFile, namespace, w.processMode, w.idmap, opts...)
+	spec, cleanup, err := oci.GenerateSpec(ctx, meta, mounts, id, resolvConf, hostsFile, namespace, w.processMode, w.idmap, w.apparmorProfile, opts...)
 	if err != nil {
 		return err
 	}

+ 1 - 0
vendor/github.com/moby/buildkit/go.mod

@@ -46,6 +46,7 @@ require (
 	github.com/opencontainers/image-spec v1.0.1
 	github.com/opencontainers/runc v1.0.0-rc92
 	github.com/opencontainers/runtime-spec v1.0.3-0.20200728170252-4d89ac9fbff6
+	github.com/opencontainers/selinux v1.8.0
 	github.com/opentracing-contrib/go-stdlib v1.0.0
 	github.com/opentracing/opentracing-go v1.2.0
 	github.com/pkg/errors v0.9.1