Merge pull request #44982 from neersighted/containerd_1.6.18
daemon: fully resolve `apparmor_parser` regression
This commit is contained in:
commit
a4a3efb75b
12 changed files with 138 additions and 85 deletions
|
@ -5,12 +5,9 @@ package daemon // import "github.com/docker/docker/daemon"
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
"github.com/containerd/containerd/pkg/apparmor"
|
||||
aaprofile "github.com/docker/docker/profiles/apparmor"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Define constants for native driver
|
||||
|
@ -19,11 +16,6 @@ const (
|
|||
defaultAppArmorProfile = "docker-default"
|
||||
)
|
||||
|
||||
var (
|
||||
checkAppArmorOnce sync.Once
|
||||
isAppArmorAvailable bool
|
||||
)
|
||||
|
||||
// DefaultApparmorProfile returns the name of the default apparmor profile
|
||||
func DefaultApparmorProfile() string {
|
||||
if apparmor.HostSupports() {
|
||||
|
@ -33,20 +25,7 @@ func DefaultApparmorProfile() string {
|
|||
}
|
||||
|
||||
func ensureDefaultAppArmorProfile() error {
|
||||
checkAppArmorOnce.Do(func() {
|
||||
if apparmor.HostSupports() {
|
||||
// Restore the apparmor_parser check removed in containerd:
|
||||
// https://github.com/containerd/containerd/commit/1acca8bba36e99684ee3489ea4a42609194ca6b9
|
||||
// Fixes: https://github.com/moby/moby/issues/44900
|
||||
if _, err := os.Stat("/sbin/apparmor_parser"); err == nil {
|
||||
isAppArmorAvailable = true
|
||||
} else {
|
||||
logrus.Warn("AppArmor enabled on system but \"apparmor_parser\" binary is missing, so profile can't be loaded")
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
if isAppArmorAvailable {
|
||||
if apparmor.HostSupports() {
|
||||
loaded, err := aaprofile.IsLoaded(defaultAppArmorProfile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Could not check if %s AppArmor profile was loaded: %s", defaultAppArmorProfile, err)
|
||||
|
|
|
@ -25,7 +25,7 @@ require (
|
|||
github.com/bsphere/le_go v0.0.0-20200109081728-fc06dab2caa8
|
||||
github.com/cloudflare/cfssl v0.0.0-20180323000720-5d63dbd981b5
|
||||
github.com/containerd/cgroups v1.0.4
|
||||
github.com/containerd/containerd v1.6.16
|
||||
github.com/containerd/containerd v1.6.18
|
||||
github.com/containerd/continuity v0.3.0
|
||||
github.com/containerd/fifo v1.0.0
|
||||
github.com/containerd/typeurl v1.0.2
|
||||
|
|
|
@ -269,8 +269,8 @@ github.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09Zvgq
|
|||
github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s=
|
||||
github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g=
|
||||
github.com/containerd/containerd v1.5.7/go.mod h1:gyvv6+ugqY25TiXxcZC3L5yOeYgEw0QMhscqVp1AR9c=
|
||||
github.com/containerd/containerd v1.6.16 h1:0H5xH6ABsN7XTrxIAKxFpBkFCBtrZ/OSORhCpUnHjrc=
|
||||
github.com/containerd/containerd v1.6.16/go.mod h1:1RdCUu95+gc2v9t3IL+zIlpClSmew7/0YS8O5eQZrOw=
|
||||
github.com/containerd/containerd v1.6.18 h1:qZbsLvmyu+Vlty0/Ex5xc0z2YtKpIsb5n45mAMI+2Ns=
|
||||
github.com/containerd/containerd v1.6.18/go.mod h1:1RdCUu95+gc2v9t3IL+zIlpClSmew7/0YS8O5eQZrOw=
|
||||
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
||||
github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
||||
github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
||||
|
|
2
vendor/github.com/containerd/containerd/Vagrantfile
generated
vendored
2
vendor/github.com/containerd/containerd/Vagrantfile
generated
vendored
|
@ -93,7 +93,7 @@ EOF
|
|||
config.vm.provision "install-golang", type: "shell", run: "once" do |sh|
|
||||
sh.upload_path = "/tmp/vagrant-install-golang"
|
||||
sh.env = {
|
||||
'GO_VERSION': ENV['GO_VERSION'] || "1.18.10",
|
||||
'GO_VERSION': ENV['GO_VERSION'] || "1.19.6",
|
||||
}
|
||||
sh.inline = <<~SHELL
|
||||
#!/usr/bin/env bash
|
||||
|
|
2
vendor/github.com/containerd/containerd/api/services/content/v1/content.pb.go
generated
vendored
2
vendor/github.com/containerd/containerd/api/services/content/v1/content.pb.go
generated
vendored
|
@ -299,7 +299,7 @@ type ListContentRequest struct {
|
|||
// filters. Expanded, containers that match the following will be
|
||||
// returned:
|
||||
//
|
||||
// filters[0] or filters[1] or ... or filters[n-1] or filters[n]
|
||||
// filters[0] or filters[1] or ... or filters[n-1] or filters[n]
|
||||
//
|
||||
// If filters is zero-length or nil, all items will be returned.
|
||||
Filters []string `protobuf:"bytes,1,rep,name=filters,proto3" json:"filters,omitempty"`
|
||||
|
|
12
vendor/github.com/containerd/containerd/images/archive/importer.go
generated
vendored
12
vendor/github.com/containerd/containerd/images/archive/importer.go
generated
vendored
|
@ -232,12 +232,14 @@ func ImportIndex(ctx context.Context, store content.Store, reader io.Reader, opt
|
|||
return writeManifest(ctx, store, idx, ocispec.MediaTypeImageIndex)
|
||||
}
|
||||
|
||||
const (
|
||||
kib = 1024
|
||||
mib = 1024 * kib
|
||||
jsonLimit = 20 * mib
|
||||
)
|
||||
|
||||
func onUntarJSON(r io.Reader, j interface{}) error {
|
||||
b, err := io.ReadAll(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return json.Unmarshal(b, j)
|
||||
return json.NewDecoder(io.LimitReader(r, jsonLimit)).Decode(j)
|
||||
}
|
||||
|
||||
func onUntarBlob(ctx context.Context, r io.Reader, store content.Ingester, size int64, ref string) (digest.Digest, error) {
|
||||
|
|
140
vendor/github.com/containerd/containerd/oci/spec_opts.go
generated
vendored
140
vendor/github.com/containerd/containerd/oci/spec_opts.go
generated
vendored
|
@ -113,6 +113,17 @@ func setCapabilities(s *Spec) {
|
|||
}
|
||||
}
|
||||
|
||||
// ensureAdditionalGids ensures that the primary GID is also included in the additional GID list.
|
||||
func ensureAdditionalGids(s *Spec) {
|
||||
setProcess(s)
|
||||
for _, f := range s.Process.User.AdditionalGids {
|
||||
if f == s.Process.User.GID {
|
||||
return
|
||||
}
|
||||
}
|
||||
s.Process.User.AdditionalGids = append([]uint32{s.Process.User.GID}, s.Process.User.AdditionalGids...)
|
||||
}
|
||||
|
||||
// WithDefaultSpec returns a SpecOpts that will populate the spec with default
|
||||
// values.
|
||||
//
|
||||
|
@ -522,7 +533,9 @@ func WithNamespacedCgroup() SpecOpts {
|
|||
// user, uid, user:group, uid:gid, uid:group, user:gid
|
||||
func WithUser(userstr string) SpecOpts {
|
||||
return func(ctx context.Context, client Client, c *containers.Container, s *Spec) error {
|
||||
defer ensureAdditionalGids(s)
|
||||
setProcess(s)
|
||||
s.Process.User.AdditionalGids = nil
|
||||
|
||||
// For LCOW it's a bit harder to confirm that the user actually exists on the host as a rootfs isn't
|
||||
// mounted on the host and shared into the guest, but rather the rootfs is constructed entirely in the
|
||||
|
@ -615,7 +628,9 @@ func WithUser(userstr string) SpecOpts {
|
|||
// WithUIDGID allows the UID and GID for the Process to be set
|
||||
func WithUIDGID(uid, gid uint32) SpecOpts {
|
||||
return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
|
||||
defer ensureAdditionalGids(s)
|
||||
setProcess(s)
|
||||
s.Process.User.AdditionalGids = nil
|
||||
s.Process.User.UID = uid
|
||||
s.Process.User.GID = gid
|
||||
return nil
|
||||
|
@ -628,12 +643,11 @@ func WithUIDGID(uid, gid uint32) SpecOpts {
|
|||
// additionally sets the gid to 0, and does not return an error.
|
||||
func WithUserID(uid uint32) SpecOpts {
|
||||
return func(ctx context.Context, client Client, c *containers.Container, s *Spec) (err error) {
|
||||
defer ensureAdditionalGids(s)
|
||||
setProcess(s)
|
||||
if c.Snapshotter == "" && c.SnapshotKey == "" {
|
||||
if !isRootfsAbs(s.Root.Path) {
|
||||
return errors.New("rootfs absolute path is required")
|
||||
}
|
||||
user, err := UserFromPath(s.Root.Path, func(u user.User) bool {
|
||||
s.Process.User.AdditionalGids = nil
|
||||
setUser := func(root string) error {
|
||||
user, err := UserFromPath(root, func(u user.User) bool {
|
||||
return u.Uid == int(uid)
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -645,7 +659,12 @@ func WithUserID(uid uint32) SpecOpts {
|
|||
}
|
||||
s.Process.User.UID, s.Process.User.GID = uint32(user.Uid), uint32(user.Gid)
|
||||
return nil
|
||||
|
||||
}
|
||||
if c.Snapshotter == "" && c.SnapshotKey == "" {
|
||||
if !isRootfsAbs(s.Root.Path) {
|
||||
return errors.New("rootfs absolute path is required")
|
||||
}
|
||||
return setUser(s.Root.Path)
|
||||
}
|
||||
if c.Snapshotter == "" {
|
||||
return errors.New("no snapshotter set for container")
|
||||
|
@ -660,20 +679,7 @@ func WithUserID(uid uint32) SpecOpts {
|
|||
}
|
||||
|
||||
mounts = tryReadonlyMounts(mounts)
|
||||
return mount.WithTempMount(ctx, mounts, func(root string) error {
|
||||
user, err := UserFromPath(root, func(u user.User) bool {
|
||||
return u.Uid == int(uid)
|
||||
})
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) || err == ErrNoUsersFound {
|
||||
s.Process.User.UID, s.Process.User.GID = uid, 0
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
s.Process.User.UID, s.Process.User.GID = uint32(user.Uid), uint32(user.Gid)
|
||||
return nil
|
||||
})
|
||||
return mount.WithTempMount(ctx, mounts, setUser)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -685,13 +691,12 @@ func WithUserID(uid uint32) SpecOpts {
|
|||
// the container.
|
||||
func WithUsername(username string) SpecOpts {
|
||||
return func(ctx context.Context, client Client, c *containers.Container, s *Spec) (err error) {
|
||||
defer ensureAdditionalGids(s)
|
||||
setProcess(s)
|
||||
s.Process.User.AdditionalGids = nil
|
||||
if s.Linux != nil {
|
||||
if c.Snapshotter == "" && c.SnapshotKey == "" {
|
||||
if !isRootfsAbs(s.Root.Path) {
|
||||
return errors.New("rootfs absolute path is required")
|
||||
}
|
||||
user, err := UserFromPath(s.Root.Path, func(u user.User) bool {
|
||||
setUser := func(root string) error {
|
||||
user, err := UserFromPath(root, func(u user.User) bool {
|
||||
return u.Name == username
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -700,6 +705,12 @@ func WithUsername(username string) SpecOpts {
|
|||
s.Process.User.UID, s.Process.User.GID = uint32(user.Uid), uint32(user.Gid)
|
||||
return nil
|
||||
}
|
||||
if c.Snapshotter == "" && c.SnapshotKey == "" {
|
||||
if !isRootfsAbs(s.Root.Path) {
|
||||
return errors.New("rootfs absolute path is required")
|
||||
}
|
||||
return setUser(s.Root.Path)
|
||||
}
|
||||
if c.Snapshotter == "" {
|
||||
return errors.New("no snapshotter set for container")
|
||||
}
|
||||
|
@ -713,16 +724,7 @@ func WithUsername(username string) SpecOpts {
|
|||
}
|
||||
|
||||
mounts = tryReadonlyMounts(mounts)
|
||||
return mount.WithTempMount(ctx, mounts, func(root string) error {
|
||||
user, err := UserFromPath(root, func(u user.User) bool {
|
||||
return u.Name == username
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.Process.User.UID, s.Process.User.GID = uint32(user.Uid), uint32(user.Gid)
|
||||
return nil
|
||||
})
|
||||
return mount.WithTempMount(ctx, mounts, setUser)
|
||||
} else if s.Windows != nil {
|
||||
s.Process.User.Username = username
|
||||
} else {
|
||||
|
@ -733,7 +735,7 @@ func WithUsername(username string) SpecOpts {
|
|||
}
|
||||
|
||||
// WithAdditionalGIDs sets the OCI spec's additionalGids array to any additional groups listed
|
||||
// for a particular user in the /etc/groups file of the image's root filesystem
|
||||
// for a particular user in the /etc/group file of the image's root filesystem
|
||||
// The passed in user can be either a uid or a username.
|
||||
func WithAdditionalGIDs(userstr string) SpecOpts {
|
||||
return func(ctx context.Context, client Client, c *containers.Container, s *Spec) (err error) {
|
||||
|
@ -742,7 +744,9 @@ func WithAdditionalGIDs(userstr string) SpecOpts {
|
|||
return nil
|
||||
}
|
||||
setProcess(s)
|
||||
s.Process.User.AdditionalGids = nil
|
||||
setAdditionalGids := func(root string) error {
|
||||
defer ensureAdditionalGids(s)
|
||||
var username string
|
||||
uid, err := strconv.Atoi(userstr)
|
||||
if err == nil {
|
||||
|
@ -803,6 +807,68 @@ func WithAdditionalGIDs(userstr string) SpecOpts {
|
|||
}
|
||||
}
|
||||
|
||||
// WithAppendAdditionalGroups append additional groups within the container.
|
||||
// The passed in groups can be either a gid or a groupname.
|
||||
func WithAppendAdditionalGroups(groups ...string) SpecOpts {
|
||||
return func(ctx context.Context, client Client, c *containers.Container, s *Spec) (err error) {
|
||||
// For LCOW or on Darwin additional GID's are not supported
|
||||
if s.Windows != nil || runtime.GOOS == "darwin" {
|
||||
return nil
|
||||
}
|
||||
setProcess(s)
|
||||
setAdditionalGids := func(root string) error {
|
||||
defer ensureAdditionalGids(s)
|
||||
gpath, err := fs.RootPath(root, "/etc/group")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ugroups, err := user.ParseGroupFile(gpath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
groupMap := make(map[string]user.Group)
|
||||
for _, group := range ugroups {
|
||||
groupMap[group.Name] = group
|
||||
}
|
||||
var gids []uint32
|
||||
for _, group := range groups {
|
||||
gid, err := strconv.ParseUint(group, 10, 32)
|
||||
if err == nil {
|
||||
gids = append(gids, uint32(gid))
|
||||
} else {
|
||||
g, ok := groupMap[group]
|
||||
if !ok {
|
||||
return fmt.Errorf("unable to find group %s", group)
|
||||
}
|
||||
gids = append(gids, uint32(g.Gid))
|
||||
}
|
||||
}
|
||||
s.Process.User.AdditionalGids = append(s.Process.User.AdditionalGids, gids...)
|
||||
return nil
|
||||
}
|
||||
if c.Snapshotter == "" && c.SnapshotKey == "" {
|
||||
if !filepath.IsAbs(s.Root.Path) {
|
||||
return errors.New("rootfs absolute path is required")
|
||||
}
|
||||
return setAdditionalGids(s.Root.Path)
|
||||
}
|
||||
if c.Snapshotter == "" {
|
||||
return errors.New("no snapshotter set for container")
|
||||
}
|
||||
if c.SnapshotKey == "" {
|
||||
return errors.New("rootfs snapshot not created for container")
|
||||
}
|
||||
snapshotter := client.SnapshotService(c.Snapshotter)
|
||||
mounts, err := snapshotter.Mounts(ctx, c.SnapshotKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mounts = tryReadonlyMounts(mounts)
|
||||
return mount.WithTempMount(ctx, mounts, setAdditionalGids)
|
||||
}
|
||||
}
|
||||
|
||||
// WithCapabilities sets Linux capabilities on the process
|
||||
func WithCapabilities(caps []string) SpecOpts {
|
||||
return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
|
||||
|
@ -907,7 +973,7 @@ func UserFromPath(root string, filter func(user.User) bool) (user.User, error) {
|
|||
// ErrNoGroupsFound can be returned from GIDFromPath
|
||||
var ErrNoGroupsFound = errors.New("no groups found")
|
||||
|
||||
// GIDFromPath inspects the GID using /etc/passwd in the specified rootfs.
|
||||
// GIDFromPath inspects the GID using /etc/group in the specified rootfs.
|
||||
// filter can be nil.
|
||||
func GIDFromPath(root string, filter func(user.Group) bool) (gid uint32, err error) {
|
||||
gpath, err := fs.RootPath(root, "/etc/group")
|
||||
|
|
12
vendor/github.com/containerd/containerd/pkg/apparmor/apparmor.go
generated
vendored
12
vendor/github.com/containerd/containerd/pkg/apparmor/apparmor.go
generated
vendored
|
@ -16,13 +16,13 @@
|
|||
|
||||
package apparmor
|
||||
|
||||
// HostSupports returns true if apparmor is enabled for the host, // On non-Linux returns false
|
||||
// On Linux returns true if apparmor_parser is enabled, and if we
|
||||
// HostSupports returns true if apparmor is enabled for the host:
|
||||
// - On Linux returns true if apparmor is enabled, apparmor_parser is
|
||||
// present, and if we are not running docker-in-docker.
|
||||
// - On non-Linux returns false.
|
||||
//
|
||||
// are not running docker-in-docker.
|
||||
//
|
||||
// It is a modified version of libcontainer/apparmor.IsEnabled(), which does not
|
||||
// check for apparmor_parser to be present, or if we're running docker-in-docker.
|
||||
// This is derived from libcontainer/apparmor.IsEnabled(), with the addition
|
||||
// of checks for apparmor_parser to be present and docker-in-docker.
|
||||
func HostSupports() bool {
|
||||
return hostSupports()
|
||||
}
|
||||
|
|
10
vendor/github.com/containerd/containerd/pkg/apparmor/apparmor_linux.go
generated
vendored
10
vendor/github.com/containerd/containerd/pkg/apparmor/apparmor_linux.go
generated
vendored
|
@ -29,14 +29,16 @@ var (
|
|||
// hostSupports returns true if apparmor is enabled for the host, if
|
||||
// apparmor_parser is enabled, and if we are not running docker-in-docker.
|
||||
//
|
||||
// It is a modified version of libcontainer/apparmor.IsEnabled(), which does not
|
||||
// check for apparmor_parser to be present, or if we're running docker-in-docker.
|
||||
// This is derived from libcontainer/apparmor.IsEnabled(), with the addition
|
||||
// of checks for apparmor_parser to be present and docker-in-docker.
|
||||
func hostSupports() bool {
|
||||
checkAppArmor.Do(func() {
|
||||
// see https://github.com/opencontainers/runc/blob/0d49470392206f40eaab3b2190a57fe7bb3df458/libcontainer/apparmor/apparmor_linux.go
|
||||
if _, err := os.Stat("/sys/kernel/security/apparmor"); err == nil && os.Getenv("container") == "" {
|
||||
buf, err := os.ReadFile("/sys/module/apparmor/parameters/enabled")
|
||||
appArmorSupported = err == nil && len(buf) > 1 && buf[0] == 'Y'
|
||||
if _, err = os.Stat("/sbin/apparmor_parser"); err == nil {
|
||||
buf, err := os.ReadFile("/sys/module/apparmor/parameters/enabled")
|
||||
appArmorSupported = err == nil && len(buf) > 1 && buf[0] == 'Y'
|
||||
}
|
||||
}
|
||||
})
|
||||
return appArmorSupported
|
||||
|
|
12
vendor/github.com/containerd/containerd/platforms/defaults_windows.go
generated
vendored
12
vendor/github.com/containerd/containerd/platforms/defaults_windows.go
generated
vendored
|
@ -46,10 +46,14 @@ type matchComparer struct {
|
|||
|
||||
// Match matches platform with the same windows major, minor
|
||||
// and build version.
|
||||
func (m matchComparer) Match(p imagespec.Platform) bool {
|
||||
if m.defaults.Match(p) {
|
||||
// TODO(windows): Figure out whether OSVersion is deprecated.
|
||||
return strings.HasPrefix(p.OSVersion, m.osVersionPrefix)
|
||||
func (m matchComparer) Match(p specs.Platform) bool {
|
||||
match := m.defaults.Match(p)
|
||||
|
||||
if match && p.OS == "windows" {
|
||||
if strings.HasPrefix(p.OSVersion, m.osVersionPrefix) {
|
||||
return true
|
||||
}
|
||||
return p.OSVersion == ""
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
2
vendor/github.com/containerd/containerd/version/version.go
generated
vendored
2
vendor/github.com/containerd/containerd/version/version.go
generated
vendored
|
@ -23,7 +23,7 @@ var (
|
|||
Package = "github.com/containerd/containerd"
|
||||
|
||||
// Version holds the complete version number. Filled in at linking time.
|
||||
Version = "1.6.16+unknown"
|
||||
Version = "1.6.18+unknown"
|
||||
|
||||
// Revision is filled with the VCS (e.g. git) revision being used to build
|
||||
// the program at linking time.
|
||||
|
|
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
|
@ -207,7 +207,7 @@ github.com/containerd/cgroups/v2/stats
|
|||
# github.com/containerd/console v1.0.3
|
||||
## explicit; go 1.13
|
||||
github.com/containerd/console
|
||||
# github.com/containerd/containerd v1.6.16
|
||||
# github.com/containerd/containerd v1.6.18
|
||||
## explicit; go 1.17
|
||||
github.com/containerd/containerd
|
||||
github.com/containerd/containerd/api/events
|
||||
|
|
Loading…
Add table
Reference in a new issue