Fix moby-engine CVE-2021-41091 CVE-2021-41089 (#1497)

This commit is contained in:
Henry Beberman 2021-10-06 10:31:28 -07:00 committed by GitHub
parent df7fe4e15a
commit e0477d785f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 379 additions and 2 deletions

View File

@ -0,0 +1,46 @@
From 80f1169eca587305759829e626cebd2a434664f6 Mon Sep 17 00:00:00 2001
From: Tonis Tiigi <tonistiigi@gmail.com>
Date: Wed, 19 May 2021 16:51:35 -0700
Subject: [PATCH] chrootarchive: don't create parent dirs outside of chroot
If chroot is used with a special root directory then create
destination directory within chroot. This works automatically
already due to extractor creating parent paths and is only
used currently with cp where parent paths are actually required
and error will be shown to user before reaching this point.
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
(cherry picked from commit 52d285184068998c22632bfb869f6294b5613a58)
Signed-off-by: Brian Goff <cpuguy83@gmail.com>
---
pkg/chrootarchive/archive.go | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/pkg/chrootarchive/archive.go b/pkg/chrootarchive/archive.go
index 83ed0c6b2fe..d11cbdf2777 100644
--- a/pkg/chrootarchive/archive.go
+++ b/pkg/chrootarchive/archive.go
@@ -74,13 +74,17 @@ func untarHandler(tarArchive io.Reader, dest string, options *archive.TarOptions
options.ExcludePatterns = []string{}
}
- idMapping := idtools.NewIDMappingsFromMaps(options.UIDMaps, options.GIDMaps)
- rootIDs := idMapping.RootPair()
+ // If dest is inside a root then directory is created within chroot by extractor.
+ // This case is only currently used by cp.
+ if dest == root {
+ idMapping := idtools.NewIDMappingsFromMaps(options.UIDMaps, options.GIDMaps)
+ rootIDs := idMapping.RootPair()
- dest = filepath.Clean(dest)
- if _, err := os.Stat(dest); os.IsNotExist(err) {
- if err := idtools.MkdirAllAndChownNew(dest, 0755, rootIDs); err != nil {
- return err
+ dest = filepath.Clean(dest)
+ if _, err := os.Stat(dest); os.IsNotExist(err) {
+ if err := idtools.MkdirAllAndChownNew(dest, 0755, rootIDs); err != nil {
+ return err
+ }
}
}

View File

@ -0,0 +1,322 @@
From 93ac040bf0c0b51d9a7fedaf994bf5bf1d68ee0e Mon Sep 17 00:00:00 2001
From: Brian Goff <cpuguy83@gmail.com>
Date: Fri, 2 Jul 2021 17:27:45 +0000
Subject: [PATCH] Lock down docker root dir perms.
Do not use 0701 perms.
0701 dir perms allows anyone to traverse the docker dir.
It happens to allow any user to execute, as an example, suid binaries
from image rootfs dirs because it allows traversal AND critically
container users need to be able to do execute things.
0701 on lower directories also happens to allow any user to modify
things in, for instance, the overlay upper dir which neccessarily
has 0755 permissions.
This changes to use 0710 which allows users in the group to traverse.
In userns mode the UID owner is (real) root and the GID is the remapped
root's GID.
This prevents anyone but the remapped root to traverse our directories
(which is required for userns with runc).
Backported to moby-engine 19.03.15
Signed-off-by: Henry Beberman <henry.beberman@microsoft.com>
Signed-off-by: Brian Goff <cpuguy83@gmail.com>
(cherry picked from commit ef7237442147441a7cadcda0600be1186d81ac73)
Signed-off-by: Brian Goff <cpuguy83@gmail.com>
---
daemon/container_operations_unix.go | 2 +-
daemon/create.go | 5 ++--
daemon/daemon.go | 5 +++-
daemon/daemon_unix.go | 14 +++++------
daemon/graphdriver/aufs/aufs.go | 13 ++++++++--
daemon/graphdriver/btrfs/btrfs.go | 18 ++++++++++++--
.../fuse-overlayfs/fuseoverlayfs.go | 24 +++++++++++++++----
daemon/graphdriver/overlay/overlay.go | 20 ++++++++++++----
daemon/graphdriver/overlay2/overlay.go | 24 +++++++++++++++----
daemon/graphdriver/vfs/driver.go | 17 +++++++++++--
daemon/graphdriver/zfs/zfs.go | 11 ++++++++-
11 files changed, 121 insertions(+), 32 deletions(-)
diff -Naur a/daemon/container_operations_unix.go b/daemon/container_operations_unix.go
--- a/daemon/container_operations_unix.go 2021-01-28 13:43:36.000000000 -0800
+++ b/daemon/container_operations_unix.go 2021-09-30 14:36:29.626220368 -0700
@@ -411,5 +411,5 @@
if err != nil {
return err
}
- return idtools.MkdirAllAndChown(p, 0701, idtools.CurrentIdentity())
+ return idtools.MkdirAllAndChown(p, 0710, idtools.Identity{UID: idtools.CurrentIdentity().UID, GID: daemon.IdentityMapping().RootPair().GID})
}
diff -Naur a/daemon/create.go b/daemon/create.go
--- a/daemon/create.go 2021-01-28 13:43:36.000000000 -0800
+++ b/daemon/create.go 2021-09-30 14:43:06.763757281 -0700
@@ -194,10 +194,11 @@
}
container.RWLayer = rwLayer
- if err := idtools.MkdirAndChown(container.Root, 0701, idtools.CurrentIdentity()); err != nil {
+ current := idtools.CurrentIdentity()
+ if err := idtools.MkdirAndChown(container.Root, 0710, idtools.Identity{UID: current.UID, GID: daemon.IdentityMapping().RootPair().GID}); err != nil {
return nil, err
}
- if err := idtools.MkdirAndChown(container.CheckpointDir(), 0700, idtools.CurrentIdentity()); err != nil {
+ if err := idtools.MkdirAndChown(container.CheckpointDir(), 0700, current); err != nil {
return nil, err
}
diff -Naur a/daemon/daemon.go b/daemon/daemon.go
--- a/daemon/daemon.go 2021-01-28 13:43:36.000000000 -0800
+++ b/daemon/daemon.go 2021-09-30 14:36:29.626220368 -0700
@@ -813,7 +813,10 @@
}
daemonRepo := filepath.Join(config.Root, "containers")
- if err := idtools.MkdirAllAndChown(daemonRepo, 0701, idtools.CurrentIdentity()); err != nil {
+ if err := idtools.MkdirAllAndChown(daemonRepo, 0710, idtools.Identity{
+ UID: idtools.CurrentIdentity().UID,
+ GID: rootIDs.GID,
+ }); err != nil {
return nil, err
}
diff -Naur a/daemon/daemon_unix.go b/daemon/daemon_unix.go
--- a/daemon/daemon_unix.go 2021-01-28 13:43:36.000000000 -0800
+++ b/daemon/daemon_unix.go 2021-09-30 14:36:29.626220368 -0700
@@ -1226,21 +1226,21 @@
}
}
+ id := idtools.Identity{UID: idtools.CurrentIdentity().UID, GID: remappedRoot.GID}
+ // First make sure the current root dir has the correct perms.
+ if err := idtools.MkdirAllAndChown(config.Root, 0710, id); err != nil {
+ return errors.Wrapf(err, "could not create or set daemon root permissions: %s", config.Root)
+ }
+
// if user namespaces are enabled we will create a subtree underneath the specified root
// with any/all specified remapped root uid/gid options on the daemon creating
// a new subdirectory with ownership set to the remapped uid/gid (so as to allow
// `chdir()` to work for containers namespaced to that uid/gid)
if config.RemappedRoot != "" {
- id := idtools.CurrentIdentity()
- // First make sure the current root dir has the correct perms.
- if err := idtools.MkdirAllAndChown(config.Root, 0701, id); err != nil {
- return errors.Wrapf(err, "could not create or set daemon root permissions: %s", config.Root)
- }
-
config.Root = filepath.Join(rootDir, fmt.Sprintf("%d.%d", remappedRoot.UID, remappedRoot.GID))
logrus.Debugf("Creating user namespaced daemon root: %s", config.Root)
// Create the root directory if it doesn't exist
- if err := idtools.MkdirAllAndChown(config.Root, 0701, id); err != nil {
+ if err := idtools.MkdirAllAndChown(config.Root, 0710, id); err != nil {
return fmt.Errorf("Cannot create daemon root: %s: %v", config.Root, err)
}
// we also need to verify that any pre-existing directories in the path to
diff -Naur a/daemon/graphdriver/aufs/aufs.go b/daemon/graphdriver/aufs/aufs.go
--- a/daemon/graphdriver/aufs/aufs.go 2021-01-28 13:43:36.000000000 -0800
+++ b/daemon/graphdriver/aufs/aufs.go 2021-09-30 14:36:29.626220368 -0700
@@ -131,14 +131,23 @@
}
currentID := idtools.CurrentIdentity()
+ _, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps)
+ if err != nil {
+ return nil, err
+ }
+ dirID := idtools.Identity{
+ UID: currentID.UID,
+ GID: rootGID,
+ }
+
// Create the root aufs driver dir
- if err := idtools.MkdirAllAndChown(root, 0701, currentID); err != nil {
+ if err := idtools.MkdirAllAndChown(root, 0710, dirID); err != nil {
return nil, err
}
// Populate the dir structure
for _, p := range paths {
- if err := idtools.MkdirAllAndChown(path.Join(root, p), 0701, currentID); err != nil {
+ if err := idtools.MkdirAllAndChown(path.Join(root, p), 0710, dirID); err != nil {
return nil, err
}
}
diff -Naur a/daemon/graphdriver/btrfs/btrfs.go b/daemon/graphdriver/btrfs/btrfs.go
--- a/daemon/graphdriver/btrfs/btrfs.go 2021-01-28 13:43:36.000000000 -0800
+++ b/daemon/graphdriver/btrfs/btrfs.go 2021-09-30 14:36:29.626220368 -0700
@@ -70,7 +70,14 @@
return nil, graphdriver.ErrPrerequisites
}
- if err := idtools.MkdirAllAndChown(home, 0701, idtools.CurrentIdentity()); err != nil {
+ remappedRoot := idtools.NewIDMappingsFromMaps(uidMaps, gidMaps)
+ currentID := idtools.CurrentIdentity()
+ dirID := idtools.Identity{
+ UID: currentID.UID,
+ GID: remappedRoot.RootPair().GID,
+ }
+
+ if err := idtools.MkdirAllAndChown(home, 0710, dirID); err != nil {
return nil, err
}
@@ -521,7 +528,14 @@
if err != nil {
return err
}
- if err := idtools.MkdirAllAndChown(subvolumes, 0701, idtools.CurrentIdentity()); err != nil {
+
+ currentID := idtools.CurrentIdentity()
+ dirID := idtools.Identity{
+ UID: currentID.UID,
+ GID: rootGID,
+ }
+
+ if err := idtools.MkdirAllAndChown(subvolumes, 0710, dirID); err != nil {
return err
}
if parent == "" {
diff -Naur a/daemon/graphdriver/overlay/overlay.go b/daemon/graphdriver/overlay/overlay.go
--- a/daemon/graphdriver/overlay/overlay.go 2021-01-28 13:43:36.000000000 -0800
+++ b/daemon/graphdriver/overlay/overlay.go 2021-09-30 14:36:29.626220368 -0700
@@ -156,11 +156,20 @@
logrus.WithField("storage-driver", "overlay").Warn(overlayutils.ErrDTypeNotSupported("overlay", backingFs))
}
- // Create the driver home dir
- if err := idtools.MkdirAllAndChown(home, 0701, idtools.CurrentIdentity()); err != nil {
+ currentID := idtools.CurrentIdentity()
+ _, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps)
+ if err != nil {
return nil, err
}
+ dirID := idtools.Identity{
+ UID: currentID.UID,
+ GID: rootGID,
+ }
+ // Create the driver home dir
+ if err := idtools.MkdirAllAndChown(home, 0710, dirID); err != nil {
+ return nil, err
+ }
d := &Driver{
home: home,
uidMaps: uidMaps,
@@ -262,10 +271,11 @@
root := idtools.Identity{UID: rootUID, GID: rootGID}
currentID := idtools.CurrentIdentity()
- if err := idtools.MkdirAllAndChown(path.Dir(dir), 0701, currentID); err != nil {
- return err
+ dirID := idtools.Identity{
+ UID: currentID.UID,
+ GID: rootGID,
}
- if err := idtools.MkdirAndChown(dir, 0701, currentID); err != nil {
+ if err := idtools.MkdirAndChown(dir, 0710, dirID); err != nil {
return err
}
diff -Naur a/daemon/graphdriver/overlay2/overlay.go b/daemon/graphdriver/overlay2/overlay.go
--- a/daemon/graphdriver/overlay2/overlay.go 2021-01-28 13:43:36.000000000 -0800
+++ b/daemon/graphdriver/overlay2/overlay.go 2021-09-30 14:36:29.626220368 -0700
@@ -165,7 +165,20 @@
logger.Warn(overlayutils.ErrDTypeNotSupported("overlay2", backingFs))
}
- if err := idtools.MkdirAllAndChown(path.Join(home, linkDir), 0701, idtools.CurrentIdentity()); err != nil {
+ _, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps)
+ if err != nil {
+ return nil, err
+ }
+
+ cur := idtools.CurrentIdentity()
+ dirID := idtools.Identity{
+ UID: cur.UID,
+ GID: rootGID,
+ }
+ if err := idtools.MkdirAllAndChown(home, 0710, dirID); err != nil {
+ return nil, err
+ }
+ if err := idtools.MkdirAllAndChown(path.Join(home, linkDir), 0700, cur); err != nil {
return nil, err
}
@@ -334,12 +347,15 @@
return err
}
root := idtools.Identity{UID: rootUID, GID: rootGID}
- current := idtools.CurrentIdentity()
+ dirID := idtools.Identity{
+ UID: idtools.CurrentIdentity().UID,
+ GID: rootGID,
+ }
- if err := idtools.MkdirAllAndChown(path.Dir(dir), 0701, current); err != nil {
+ if err := idtools.MkdirAllAndChown(path.Dir(dir), 0710, dirID); err != nil {
return err
}
- if err := idtools.MkdirAndChown(dir, 0701, current); err != nil {
+ if err := idtools.MkdirAndChown(dir, 0710, dirID); err != nil {
return err
}
diff -Naur a/daemon/graphdriver/vfs/driver.go b/daemon/graphdriver/vfs/driver.go
--- a/daemon/graphdriver/vfs/driver.go 2021-01-28 13:43:36.000000000 -0800
+++ b/daemon/graphdriver/vfs/driver.go 2021-09-30 14:36:29.630220338 -0700
@@ -37,8 +37,16 @@
if err := d.parseOptions(options); err != nil {
return nil, err
}
+ _, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps)
+ if err != nil {
+ return nil, err
+ }
- if err := idtools.MkdirAllAndChown(home, 0701, idtools.CurrentIdentity()); err != nil {
+ dirID := idtools.Identity{
+ UID: idtools.CurrentIdentity().UID,
+ GID: rootGID,
+ }
+ if err := idtools.MkdirAllAndChown(home, 0710, dirID); err != nil {
return nil, err
}
@@ -140,7 +148,12 @@
func (d *Driver) create(id, parent string, size uint64) error {
dir := d.dir(id)
rootIDs := d.idMapping.RootPair()
- if err := idtools.MkdirAllAndChown(filepath.Dir(dir), 0701, idtools.CurrentIdentity()); err != nil {
+
+ dirID := idtools.Identity{
+ UID: idtools.CurrentIdentity().UID,
+ GID: rootIDs.GID,
+ }
+ if err := idtools.MkdirAllAndChown(filepath.Dir(dir), 0710, dirID); err != nil {
return err
}
if err := idtools.MkdirAndChown(dir, 0755, rootIDs); err != nil {
diff -Naur a/daemon/graphdriver/zfs/zfs.go b/daemon/graphdriver/zfs/zfs.go
--- a/daemon/graphdriver/zfs/zfs.go 2021-01-28 13:43:36.000000000 -0800
+++ b/daemon/graphdriver/zfs/zfs.go 2021-09-30 14:36:29.630220338 -0700
@@ -103,7 +103,16 @@
return nil, fmt.Errorf("BUG: zfs get all -t filesystem -rHp '%s' should contain '%s'", options.fsName, options.fsName)
}
- if err := idtools.MkdirAllAndChown(base, 0701, idtools.CurrentIdentity()); err != nil {
+ _, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps)
+ if err != nil {
+ return nil, err
+ }
+
+ dirID := idtools.Identity{
+ UID: idtools.CurrentIdentity().UID,
+ GID: rootGID,
+ }
+ if err := idtools.MkdirAllAndChown(base, 0710, dirID); err != nil {
return nil, fmt.Errorf("Failed to create '%s': %v", base, err)
}
--
2.33.0

View File

@ -1,7 +1,7 @@
Summary: The open-source application container engine
Name: moby-engine
Version: 19.03.15+azure
Release: 2%{?dist}
Release: 4%{?dist}
License: ASL 2.0
Group: Tools/Container
@ -27,6 +27,8 @@ Source2: docker.service
Source3: docker.socket
Source4: LICENSE
Source5: NOTICE
Patch0: CVE-2021-41091.patch
Patch1: CVE-2021-41089.patch
URL: https://mobyproject.org
Vendor: Microsoft Corporation
Distribution: Mariner
@ -76,7 +78,7 @@ Moby is an open-source project created by Docker to enable and accelerate softwa
%define OUR_GOPATH %{_topdir}/.gopath
%prep
%setup -q -n %{name}-%{version} -c
%autosetup -p1 -c
mkdir -p %{OUR_GOPATH}/src/github.com/docker
ln -sfT %{_topdir}/BUILD/%{name}-%{version}/libnetwork %{OUR_GOPATH}/src/github.com/docker/libnetwork
mkdir -p '%{OUR_GOPATH}/src/github.com/docker'
@ -149,6 +151,13 @@ fi
/usr/share/doc/%{name}-%{version}/*
%changelog
* Mon Oct 04 2021 Henry Beberman <henry.beberman@microsoft.com> 19.03.15+azure-4
- Patch CVE-2021-41091 and CVE-2021-41089
- Switch to autosetup
* Fri Aug 06 2021 Nicolas Guibourge <nicolasg@microsoft.com> 19.03.15+azure-3
- Increment release to force republishing using golang 1.16.7.
* Tue Jun 08 2021 Henry Beberman <henry.beberman@microsoft.com> 19.03.15+azure-2
- Increment release to force republishing using golang 1.15.13.