Bug#1000448: bullseye-pu: package containerd/1.4.12~ds1-1~deb11u1
Package: release.debian.org
Severity: normal
Tags: bullseye
User: release.debian.org@packages.debian.org
Usertags: pu
X-Debbugs-Cc: zhsj@debian.org
[ Reason ]
I'd like to update containerd in bullseye to latest upstream
patch version. Upstream does maintain a stable release branch
1.4.x with only backporting important bugfix.
Notably:
1.4.12~ds1-1~deb11u1 will have:
+ Workaround for "clone3" syscall. So users can run images like
fedora:rawhide, ubuntu:impish, which has enabled clone3 syscall
in glibc.
See also https://bugs.launchpad.net/cloud-images/+bug/1943049
+ Mitigate CVE-2021-41190: Handle ambiguous OCI manifest parsing
+ Backport RPi1/RPi0 workaround #998909
[ Impact ]
Same as above three notable changes.
[ Tests ]
+ Extensive unit tests in upstream source
+ Manually install it on bullseye system. I can successfully run:
ctr run --net-host --seccomp --rm registry.fedoraproject.org/fedora:rawhide test1 /usr/bin/curl www.debian.org
+ I don't have RPi1 or RPi0 to test, but the backported patch is fairly simple.
[ Risks ]
There are 7 patch releases from the version in bullseye.
So the change is not small.
[ Checklist ]
[x] *all* changes are documented in the d/changelog
[x] I reviewed all changes and I approve them
[x] attach debdiff against the package in (old)stable
[x] the issue is verified as fixed in unstable
[ Changes ]
I will copy filtered diff here, and attach full diff as attachment.
filter command:
cat containerd_1.4.12~ds1-1~deb11u1.patch|filterdiff -x '*/patches/*CVE-2021*' -x '*_windows.*' -x '*_test.*' -x '*.toml' -x '*.yml' -x '*.yaml' -x '*/vendor.conf' -x '*/Dockerfile.test'
diffstat:
.mailmap | 3
Vagrantfile | 2
archive/tar_unix.go | 2
content/local/store.go | 2
contrib/seccomp/seccomp_default.go | 11
debian/changelog | 31 ++
debian/patches/0004-Add-cgo-tag-to-btrfs-plugin.patch | 2
debian/patches/0005-backport-github.com-containerd-containerd-remotes.patch | 114 ++++++----
debian/patches/0008-Add-RPi1-RPi0-workaround.patch | 35 +++
debian/patches/series | 5
images/image.go | 55 ++++
metadata/containers.go | 2
metadata/content.go | 6
remotes/docker/authorizer.go | 7
remotes/docker/fetcher.go | 12 -
remotes/docker/pusher.go | 5
remotes/docker/resolver.go | 51 +++-
remotes/docker/schema1/converter.go | 9
runtime/v1/linux/bundle.go | 56 ++++
runtime/v2/bundle.go | 5
runtime/v2/bundle_default.go | 24 ++
runtime/v2/bundle_linux.go | 74 ++++++
script/setup/runc-version | 2
snapshots/btrfs/btrfs.go | 8
snapshots/devmapper/snapshotter.go | 4
vendor/github.com/containerd/cri/pkg/os/os.go | 13 -
vendor/github.com/containerd/cri/pkg/os/os_unix.go | 15 +
vendor/github.com/containerd/cri/pkg/server/sandbox_run.go | 4
version/version.go | 2
29 files changed, 471 insertions(+), 90 deletions(-)
diff -Nru containerd-1.4.5~ds1/archive/tar_unix.go containerd-1.4.12~ds1/archive/tar_unix.go
--- containerd-1.4.5~ds1/archive/tar_unix.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/archive/tar_unix.go 2021-11-18 03:52:12.000000000 +0800
@@ -113,7 +113,7 @@
func handleLChmod(hdr *tar.Header, path string, hdrInfo os.FileInfo) error {
if hdr.Typeflag == tar.TypeLink {
- if fi, err := os.Lstat(hdr.Linkname); err == nil && (fi.Mode()&os.ModeSymlink == 0) {
+ if fi, err := os.Lstat(path); err == nil && (fi.Mode()&os.ModeSymlink == 0) {
if err := os.Chmod(path, hdrInfo.Mode()); err != nil && !os.IsNotExist(err) {
return err
}
diff -Nru containerd-1.4.5~ds1/content/local/store.go containerd-1.4.12~ds1/content/local/store.go
--- containerd-1.4.5~ds1/content/local/store.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/content/local/store.go 2021-11-18 03:52:12.000000000 +0800
@@ -502,7 +502,7 @@
if ref != status.Ref {
// NOTE(stevvooe): This is fairly catastrophic. Either we have some
// layout corruption or a hash collision for the ref key.
- return status, errors.Wrapf(err, "ref key does not match: %v != %v", ref, status.Ref)
+ return status, errors.Errorf("ref key does not match: %v != %v", ref, status.Ref)
}
if total > 0 && status.Total > 0 && total != status.Total {
diff -Nru containerd-1.4.5~ds1/contrib/seccomp/seccomp_default.go containerd-1.4.12~ds1/contrib/seccomp/seccomp_default.go
--- containerd-1.4.5~ds1/contrib/seccomp/seccomp_default.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/contrib/seccomp/seccomp_default.go 2021-11-18 03:52:12.000000000 +0800
@@ -49,6 +49,7 @@
// DefaultProfile defines the allowed syscalls for the default seccomp profile.
func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
+ nosys := uint(unix.ENOSYS)
syscalls := []specs.LinuxSyscall{
{
Names: []string{
@@ -524,6 +525,7 @@
Names: []string{
"bpf",
"clone",
+ "clone3",
"fanotify_init",
"lookup_dcookie",
"mount",
@@ -648,6 +650,15 @@
},
})
}
+ // clone3 is explicitly requested to give ENOSYS instead of the default EPERM, when CAP_SYS_ADMIN is unset
+ // https://github.com/moby/moby/pull/42681
+ s.Syscalls = append(s.Syscalls, specs.LinuxSyscall{
+ Names: []string{
+ "clone3",
+ },
+ Action: specs.ActErrno,
+ ErrnoRet: &nosys,
+ })
}
return s
diff -Nru containerd-1.4.5~ds1/debian/changelog containerd-1.4.12~ds1/debian/changelog
--- containerd-1.4.5~ds1/debian/changelog 2021-10-05 18:45:47.000000000 +0800
+++ containerd-1.4.12~ds1/debian/changelog 2021-11-23 18:42:16.000000000 +0800
@@ -1,3 +1,34 @@
+containerd (1.4.12~ds1-1~deb11u1) bullseye; urgency=medium
+
+ * New upstream version 1.4.12~ds1
+ + 1.4.12
+ * Mitigate CVE-2021-41190: Handle ambiguous OCI manifest parsing
+ * Update pull to try next mirror for non-404 errors
+ * Update pull to handle of non-https urls in descriptors
+ + 1.4.11
+ * CVE-2021-41103: Fix insufficiently restricted permissions on container
+ root and plugin directories
+ + 1.4.10
+ * Support "clone3" in default seccomp profile
+ * Fix panic in metadata content writer on copy error
+ + 1.4.9
+ * Update pull authorization logic on redirect
+ * Fix user agent used for fetching registry authentication tokens
+ + 1.4.8
+ * CVE-2021-32760: Archive package allows chmod of file outside of unpack
+ target directory
+ + 1.4.7
+ * Fix invalid validation error checking
+ * Fix error on image pull resume
+ * Refresh patches
+ + Drop CVE-2021-32760 patch
+ + Drop CVE-2021-41103 patch
+ + Refresh 0005-backport-github.com-containerd-containerd-remotes.patch
+ with latest 1.5 release branch
+ * Backport RPi1/RPi0 workaround (Closes: #998909)
+
+ -- Shengjing Zhu <zhsj@debian.org> Tue, 23 Nov 2021 18:42:16 +0800
+
containerd (1.4.5~ds1-2+deb11u1) bullseye-security; urgency=high
* CVE-2021-41103: Insufficiently restricted permissions on container
diff -Nru containerd-1.4.5~ds1/debian/patches/0004-Add-cgo-tag-to-btrfs-plugin.patch containerd-1.4.12~ds1/debian/patches/0004-Add-cgo-tag-to-btrfs-plugin.patch
--- containerd-1.4.5~ds1/debian/patches/0004-Add-cgo-tag-to-btrfs-plugin.patch 2021-10-05 18:45:47.000000000 +0800
+++ containerd-1.4.12~ds1/debian/patches/0004-Add-cgo-tag-to-btrfs-plugin.patch 2021-11-23 18:42:16.000000000 +0800
@@ -20,7 +20,7 @@
/*
Copyright The containerd Authors.
diff --git a/snapshots/btrfs/btrfs.go b/snapshots/btrfs/btrfs.go
-index ea90853..eef883b 100644
+index 78f825c..778b783 100644
--- a/snapshots/btrfs/btrfs.go
+++ b/snapshots/btrfs/btrfs.go
@@ -1,4 +1,4 @@
diff -Nru containerd-1.4.5~ds1/debian/patches/0005-backport-github.com-containerd-containerd-remotes.patch containerd-1.4.12~ds1/debian/patches/0005-backport-github.com-containerd-containerd-remotes.patch
--- containerd-1.4.5~ds1/debian/patches/0005-backport-github.com-containerd-containerd-remotes.patch 2021-10-05 18:45:47.000000000 +0800
+++ containerd-1.4.12~ds1/debian/patches/0005-backport-github.com-containerd-containerd-remotes.patch 2021-11-23 18:42:16.000000000 +0800
@@ -1,6 +1,7 @@
From: Shengjing Zhu <zhsj@debian.org>
-Date: Fri, 5 Mar 2021 16:35:17 +0800
-Subject: backport_github=2Ecom/containerd/containerd/remotes
+Date: Tue, 23 Nov 2021 15:49:57 +0800
+Subject: =?utf-8?q?backport_github=2Ecom/containerd/containerd/remotes?=
+ =?utf-8?q?=C2=AC?=
For building docker.io 20.10
@@ -10,19 +11,19 @@
Forwarded: not-needed
---
- remotes/docker/auth.go | 198 ---------------------------
- remotes/docker/auth/fetch.go | 202 +++++++++++++++++++++++++++
- remotes/docker/auth/parse.go | 203 ++++++++++++++++++++++++++++
- remotes/docker/authorizer.go | 285 ++++++++++-----------------------------
+ remotes/docker/auth.go | 198 --------------------------
+ remotes/docker/auth/fetch.go | 209 ++++++++++++++++++++++++++++
+ remotes/docker/auth/parse.go | 203 +++++++++++++++++++++++++++
+ remotes/docker/authorizer.go | 292 +++++++++------------------------------
remotes/docker/errcode.go | 2 +-
remotes/docker/fetcher.go | 2 +-
remotes/docker/httpreadseeker.go | 2 +-
- remotes/docker/pusher.go | 36 +++--
- remotes/docker/resolver.go | 47 +++----
+ remotes/docker/pusher.go | 38 +++--
+ remotes/docker/resolver.go | 49 +++----
remotes/docker/scope.go | 14 +-
remotes/docker/scope_test.go | 4 +-
- remotes/errors/errors.go | 46 +++++++
- 12 files changed, 573 insertions(+), 468 deletions(-)
+ remotes/errors/errors.go | 46 ++++++
+ 12 files changed, 581 insertions(+), 478 deletions(-)
delete mode 100644 remotes/docker/auth.go
create mode 100644 remotes/docker/auth/fetch.go
create mode 100644 remotes/docker/auth/parse.go
@@ -234,10 +235,10 @@
-}
diff --git a/remotes/docker/auth/fetch.go b/remotes/docker/auth/fetch.go
new file mode 100644
-index 0000000..0d01c81
+index 0000000..8b0a87e
--- /dev/null
+++ b/remotes/docker/auth/fetch.go
-@@ -0,0 +1,202 @@
+@@ -0,0 +1,209 @@
+/*
+ Copyright The containerd Authors.
+
@@ -266,6 +267,7 @@
+
+ "github.com/containerd/containerd/log"
+ remoteserrors "github.com/containerd/containerd/remotes/errors"
++ "github.com/containerd/containerd/version"
+ "github.com/pkg/errors"
+ "golang.org/x/net/context/ctxhttp"
+)
@@ -349,6 +351,9 @@
+ for k, v := range headers {
+ req.Header[k] = append(req.Header[k], v...)
+ }
++ if len(req.Header.Get("User-Agent")) == 0 {
++ req.Header.Set("User-Agent", "containerd/"+version.Version)
++ }
+
+ resp, err := ctxhttp.Do(ctx, client, req)
+ if err != nil {
@@ -393,6 +398,9 @@
+ for k, v := range headers {
+ req.Header[k] = append(req.Header[k], v...)
+ }
++ if len(req.Header.Get("User-Agent")) == 0 {
++ req.Header.Set("User-Agent", "containerd/"+version.Version)
++ }
+
+ reqParams := req.URL.Query()
+
@@ -650,10 +658,10 @@
+ return "", ""
+}
diff --git a/remotes/docker/authorizer.go b/remotes/docker/authorizer.go
-index 001423a..67e4aea 100644
+index 2f459b7..67e4aea 100644
--- a/remotes/docker/authorizer.go
+++ b/remotes/docker/authorizer.go
-@@ -19,21 +19,17 @@ package docker
+@@ -19,22 +19,17 @@ package docker
import (
"context"
"encoding/base64"
@@ -669,6 +677,7 @@
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/log"
+- "github.com/containerd/containerd/version"
+ "github.com/containerd/containerd/remotes/docker/auth"
+ remoteerrors "github.com/containerd/containerd/remotes/errors"
"github.com/pkg/errors"
@@ -677,7 +686,7 @@
)
type dockerAuthorizer struct {
-@@ -135,8 +131,8 @@ func (a *dockerAuthorizer) AddResponses(ctx context.Context, responses []*http.R
+@@ -136,8 +131,8 @@ func (a *dockerAuthorizer) AddResponses(ctx context.Context, responses []*http.R
a.mu.Lock()
defer a.mu.Unlock()
@@ -688,7 +697,7 @@
if err := invalidAuthorization(c, responses); err != nil {
delete(a.handlers, host)
return err
-@@ -152,26 +148,35 @@ func (a *dockerAuthorizer) AddResponses(ctx context.Context, responses []*http.R
+@@ -153,26 +148,35 @@ func (a *dockerAuthorizer) AddResponses(ctx context.Context, responses []*http.R
return nil
}
@@ -731,7 +740,7 @@
return nil
}
}
-@@ -179,38 +184,6 @@ func (a *dockerAuthorizer) AddResponses(ctx context.Context, responses []*http.R
+@@ -180,38 +184,6 @@ func (a *dockerAuthorizer) AddResponses(ctx context.Context, responses []*http.R
return errors.Wrap(errdefs.ErrNotImplemented, "failed to find supported auth scheme")
}
@@ -770,7 +779,7 @@
// authResult is used to control limit rate.
type authResult struct {
sync.WaitGroup
-@@ -227,17 +200,17 @@ type authHandler struct {
+@@ -228,17 +200,17 @@ type authHandler struct {
client *http.Client
// only support basic and bearer schemes
@@ -791,7 +800,7 @@
return &authHandler{
header: hdr,
client: client,
-@@ -249,17 +222,17 @@ func newAuthHandler(client *http.Client, hdr http.Header, scheme authenticationS
+@@ -250,17 +222,17 @@ func newAuthHandler(client *http.Client, hdr http.Header, scheme authenticationS
func (ah *authHandler) authorize(ctx context.Context) (string, error) {
switch ah.scheme {
@@ -813,7 +822,7 @@
if username == "" || secret == "" {
return "", fmt.Errorf("failed to handle basic auth because missing username or secret")
-@@ -269,14 +242,14 @@ func (ah *authHandler) doBasicAuth(ctx context.Context) (string, error) {
+@@ -270,14 +242,14 @@ func (ah *authHandler) doBasicAuth(ctx context.Context) (string, error) {
return fmt.Sprintf("Basic %s", auth), nil
}
@@ -831,7 +840,7 @@
ah.Lock()
if r, exist := ah.scopedTokens[scoped]; exist {
-@@ -291,174 +264,52 @@ func (ah *authHandler) doBearerAuth(ctx context.Context) (string, error) {
+@@ -292,180 +264,52 @@ func (ah *authHandler) doBearerAuth(ctx context.Context) (string, error) {
ah.scopedTokens[scoped] = r
ah.Unlock()
@@ -910,6 +919,9 @@
- req.Header[k] = append(req.Header[k], v...)
- }
- }
+- if len(req.Header.Get("User-Agent")) == 0 {
+- req.Header.Set("User-Agent", "containerd/"+version.Version)
+- }
-
- resp, err := ctxhttp.Do(ctx, ah.client, req)
- if err != nil {
@@ -984,6 +996,9 @@
}
+ return resp.AccessToken, nil
}
+- if len(req.Header.Get("User-Agent")) == 0 {
+- req.Header.Set("User-Agent", "containerd/"+version.Version)
+- }
-
- reqParams := req.URL.Query()
-
@@ -1058,7 +1073,7 @@
Message string
diff --git a/remotes/docker/fetcher.go b/remotes/docker/fetcher.go
-index cd0168b..9d6708d 100644
+index 5aaaf9e..4b2c10e 100644
--- a/remotes/docker/fetcher.go
+++ b/remotes/docker/fetcher.go
@@ -45,7 +45,7 @@ func (r dockerFetcher) Fetch(ctx context.Context, desc ocispec.Descriptor) (io.R
@@ -1084,7 +1099,7 @@
if hrs.rc != nil {
diff --git a/remotes/docker/pusher.go b/remotes/docker/pusher.go
-index d95e0c8..94a270c 100644
+index d46396b..c367b1e 100644
--- a/remotes/docker/pusher.go
+++ b/remotes/docker/pusher.go
@@ -30,6 +30,7 @@ import (
@@ -1104,19 +1119,20 @@
if err != nil {
return nil, err
}
-@@ -112,8 +113,9 @@ func (p dockerPusher) Push(ctx context.Context, desc ocispec.Descriptor) (conten
+@@ -113,9 +114,10 @@ func (p dockerPusher) Push(ctx context.Context, desc ocispec.Descriptor) (conten
return nil, errors.Wrapf(errdefs.ErrAlreadyExists, "content %v on remote", desc.Digest)
}
} else if resp.StatusCode != http.StatusNotFound {
-- // TODO: log error
-- return nil, errors.Errorf("unexpected response: %s", resp.Status)
+ err := remoteserrors.NewUnexpectedStatusErr(resp)
+ log.G(ctx).WithField("resp", resp).WithField("body", string(err.(remoteserrors.ErrUnexpectedStatus).Body)).Debug("unexpected response")
+ resp.Body.Close()
+- // TODO: log error
+- return nil, errors.Errorf("unexpected response: %s", resp.Status)
+ return nil, err
}
+ resp.Body.Close()
}
-
-@@ -128,7 +130,7 @@ func (p dockerPusher) Push(ctx context.Context, desc ocispec.Descriptor) (conten
+@@ -131,7 +133,7 @@ func (p dockerPusher) Push(ctx context.Context, desc ocispec.Descriptor) (conten
var resp *http.Response
if fromRepo := selectRepositoryMountCandidate(p.refspec, desc.Annotations); fromRepo != "" {
preq := requestWithMountFrom(req, desc.Digest.String(), fromRepo)
@@ -1125,7 +1141,7 @@
// NOTE: the fromRepo might be private repo and
// auth service still can grant token without error.
-@@ -166,8 +168,9 @@ func (p dockerPusher) Push(ctx context.Context, desc ocispec.Descriptor) (conten
+@@ -170,8 +172,9 @@ func (p dockerPusher) Push(ctx context.Context, desc ocispec.Descriptor) (conten
})
return nil, errors.Wrapf(errdefs.ErrAlreadyExists, "content %v on remote", desc.Digest)
default:
@@ -1137,7 +1153,7 @@
}
var (
-@@ -219,7 +222,7 @@ func (p dockerPusher) Push(ctx context.Context, desc ocispec.Descriptor) (conten
+@@ -223,7 +226,7 @@ func (p dockerPusher) Push(ctx context.Context, desc ocispec.Descriptor) (conten
// TODO: Support chunked upload
pr, pw := io.Pipe()
@@ -1146,7 +1162,7 @@
body := ioutil.NopCloser(pr)
req.body = func() (io.ReadCloser, error) {
-@@ -237,6 +240,7 @@ func (p dockerPusher) Push(ctx context.Context, desc ocispec.Descriptor) (conten
+@@ -241,6 +244,7 @@ func (p dockerPusher) Push(ctx context.Context, desc ocispec.Descriptor) (conten
defer close(respC)
resp, err := req.doWithRetries(ctx, nil)
if err != nil {
@@ -1154,7 +1170,7 @@
pr.CloseWithError(err)
return
}
-@@ -244,10 +248,11 @@ func (p dockerPusher) Push(ctx context.Context, desc ocispec.Descriptor) (conten
+@@ -248,10 +252,11 @@ func (p dockerPusher) Push(ctx context.Context, desc ocispec.Descriptor) (conten
switch resp.StatusCode {
case http.StatusOK, http.StatusCreated, http.StatusNoContent:
default:
@@ -1169,7 +1185,7 @@
}()
return &pushWriter{
-@@ -280,12 +285,17 @@ func getManifestPath(object string, dgst digest.Digest) []string {
+@@ -284,12 +289,17 @@ func getManifestPath(object string, dgst digest.Digest) []string {
return []string{"manifests", object}
}
@@ -1188,7 +1204,7 @@
isManifest bool
expected digest.Digest
-@@ -335,8 +345,8 @@ func (pw *pushWriter) Commit(ctx context.Context, size int64, expected digest.Di
+@@ -339,10 +349,10 @@ func (pw *pushWriter) Commit(ctx context.Context, size int64, expected digest.Di
// TODO: timeout waiting for response
resp := <-pw.responseC
@@ -1197,10 +1213,13 @@
+ if resp.err != nil {
+ return resp.err
}
+- defer resp.Body.Close()
++ defer resp.Response.Body.Close()
// 201 is specified return status, some registries return
+ // 200, 202 or 204.
diff --git a/remotes/docker/resolver.go b/remotes/docker/resolver.go
-index aea092c..866379e 100644
+index 40831f1..d6ccd70 100644
--- a/remotes/docker/resolver.go
+++ b/remotes/docker/resolver.go
@@ -41,10 +41,6 @@ import (
@@ -1235,8 +1254,8 @@
- }
-
var (
- lastErr error
- paths [][]string
+ firstErr error
+ paths [][]string
@@ -267,7 +258,7 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
return "", ocispec.Descriptor{}, errors.Wrap(errdefs.ErrNotFound, "no resolve hosts")
}
@@ -1246,7 +1265,22 @@
if err != nil {
return "", ocispec.Descriptor{}, err
}
-@@ -393,12 +384,7 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
+@@ -295,14 +286,12 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
+ if firstErr == nil {
+ firstErr = err
+ }
+- log.G(ctx).WithError(err).Info("trying next host")
+ continue // try another host
+ }
+ resp.Body.Close() // don't care about body contents.
+
+ if resp.StatusCode > 299 {
+ if resp.StatusCode == http.StatusNotFound {
+- log.G(ctx).Info("trying next host - response was http.StatusNotFound")
+ continue
+ }
+ if resp.StatusCode > 399 {
+@@ -404,12 +393,7 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
}
func (r *dockerResolver) Fetcher(ctx context.Context, ref string) (remotes.Fetcher, error) {
@@ -1260,7 +1294,7 @@
if err != nil {
return nil, err
}
-@@ -409,23 +395,27 @@ func (r *dockerResolver) Fetcher(ctx context.Context, ref string) (remotes.Fetch
+@@ -420,23 +404,27 @@ func (r *dockerResolver) Fetcher(ctx context.Context, ref string) (remotes.Fetch
}
func (r *dockerResolver) Pusher(ctx context.Context, ref string) (remotes.Pusher, error) {
@@ -1295,7 +1329,7 @@
type dockerBase struct {
refspec reference.Spec
repository string
-@@ -457,10 +447,11 @@ func (r *dockerBase) filterHosts(caps HostCapabilities) (hosts []RegistryHost) {
+@@ -468,10 +456,11 @@ func (r *dockerBase) filterHosts(caps HostCapabilities) (hosts []RegistryHost) {
}
func (r *dockerBase) request(host RegistryHost, method string, ps ...string) *request {
diff -Nru containerd-1.4.5~ds1/debian/patches/0008-Add-RPi1-RPi0-workaround.patch containerd-1.4.12~ds1/debian/patches/0008-Add-RPi1-RPi0-workaround.patch
--- containerd-1.4.5~ds1/debian/patches/0008-Add-RPi1-RPi0-workaround.patch 1970-01-01 08:00:00.000000000 +0800
+++ containerd-1.4.12~ds1/debian/patches/0008-Add-RPi1-RPi0-workaround.patch 2021-11-23 18:42:16.000000000 +0800
@@ -0,0 +1,35 @@
+From: Tianon Gravi <admwiggin@gmail.com>
+Date: Fri, 4 Sep 2020 14:12:04 -0700
+Subject: Add RPi1/RPi0 workaround
+
+On the very popular Raspberry Pi 1 and Zero devices, the CPU is actually ARMv6, but the chip happens to support the feature bit the kernel uses to differentiate v6/v7, so it gets reported as "CPU architecture: 7" and thus fails to run many of the images that get pulled.
+
+To account for this very popular edge case, this also checks "model name" which on these chips will begin with "ARMv6-compatible" -- we could also check uname, but getCPUInfo is already handy, low overhead, and mirrors the code before this.
+
+Signed-off-by: Tianon Gravi <admwiggin@gmail.com>
+
+Origin: backport, https://github.com/containerd/containerd/commit/2055e12953bb538228d8d9fe627fa545d7cf82be
+---
+ platforms/cpuinfo.go | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/platforms/cpuinfo.go b/platforms/cpuinfo.go
+index db65a72..0512bc9 100644
+--- a/platforms/cpuinfo.go
++++ b/platforms/cpuinfo.go
+@@ -96,6 +96,15 @@ func getCPUVariant() string {
+ return ""
+ }
+
++ // handle edge case for Raspberry Pi ARMv6 devices (which due to a kernel quirk, report "CPU architecture: 7")
++ // https://www.raspberrypi.org/forums/viewtopic.php?t=12614
++ if runtime.GOARCH == "arm" && variant == "7" {
++ model, err := getCPUInfo("model name")
++ if err == nil && strings.HasPrefix(strings.ToLower(model), "armv6-compatible") {
++ variant = "6"
++ }
++ }
++
+ switch strings.ToLower(variant) {
+ case "8", "aarch64":
+ // special case: if running a 32-bit userspace on aarch64, the variant should be "v7"
diff -Nru containerd-1.4.5~ds1/debian/patches/series containerd-1.4.12~ds1/debian/patches/series
--- containerd-1.4.5~ds1/debian/patches/series 2021-10-05 18:45:47.000000000 +0800
+++ containerd-1.4.12~ds1/debian/patches/series 2021-11-23 18:42:16.000000000 +0800
@@ -5,7 +5,4 @@
0005-backport-github.com-containerd-containerd-remotes.patch
0006-backport-apparmor-handle-signal-mediation.patch
0007-backport-runtime-ignore-file-already-closed-error.patch
-0008-CVE-2021-32760.patch
-0009-CVE-2021-41103/0009-v2-runtime-reduce-permissions-for-bundle-dir.patch
-0009-CVE-2021-41103/0010-v1-runtime-reduce-permissions-for-bundle-dir.patch
-0009-CVE-2021-41103/0011-btrfs-reduce-permissions-on-plugin-directories.patch
+0008-Add-RPi1-RPi0-workaround.patch
diff -Nru containerd-1.4.5~ds1/images/image.go containerd-1.4.12~ds1/images/image.go
--- containerd-1.4.5~ds1/images/image.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/images/image.go 2021-11-18 03:52:12.000000000 +0800
@@ -19,6 +19,7 @@
import (
"context"
"encoding/json"
+ "fmt"
"sort"
"time"
@@ -154,6 +155,10 @@
return nil, err
}
+ if err := validateMediaType(p, desc.MediaType); err != nil {
+ return nil, errors.Wrapf(err, "manifest: invalid desc %s", desc.Digest)
+ }
+
var manifest ocispec.Manifest
if err := json.Unmarshal(p, &manifest); err != nil {
return nil, err
@@ -194,6 +199,10 @@
return nil, err
}
+ if err := validateMediaType(p, desc.MediaType); err != nil {
+ return nil, errors.Wrapf(err, "manifest: invalid desc %s", desc.Digest)
+ }
+
var idx ocispec.Index
if err := json.Unmarshal(p, &idx); err != nil {
return nil, err
@@ -336,6 +345,10 @@
return nil, err
}
+ if err := validateMediaType(p, desc.MediaType); err != nil {
+ return nil, errors.Wrapf(err, "children: invalid desc %s", desc.Digest)
+ }
+
// TODO(stevvooe): We just assume oci manifest, for now. There may be
// subtle differences from the docker version.
var manifest ocispec.Manifest
@@ -351,6 +364,10 @@
return nil, err
}
+ if err := validateMediaType(p, desc.MediaType); err != nil {
+ return nil, errors.Wrapf(err, "children: invalid desc %s", desc.Digest)
+ }
+
var index ocispec.Index
if err := json.Unmarshal(p, &index); err != nil {
return nil, err
@@ -368,6 +385,44 @@
return descs, nil
}
+// unknownDocument represents a manifest, manifest list, or index that has not
+// yet been validated.
+type unknownDocument struct {
+ MediaType string `json:"mediaType,omitempty"`
+ Config json.RawMessage `json:"config,omitempty"`
+ Layers json.RawMessage `json:"layers,omitempty"`
+ Manifests json.RawMessage `json:"manifests,omitempty"`
+ FSLayers json.RawMessage `json:"fsLayers,omitempty"` // schema 1
+}
+
+// validateMediaType returns an error if the byte slice is invalid JSON or if
+// the media type identifies the blob as one format but it contains elements of
+// another format.
+func validateMediaType(b []byte, mt string) error {
+ var doc unknownDocument
+ if err := json.Unmarshal(b, &doc); err != nil {
+ return err
+ }
+ if len(doc.FSLayers) != 0 {
+ return fmt.Errorf("media-type: schema 1 not supported")
+ }
+ switch mt {
+ case MediaTypeDockerSchema2Manifest, ocispec.MediaTypeImageManifest:
+ if len(doc.Manifests) != 0 ||
+ doc.MediaType == MediaTypeDockerSchema2ManifestList ||
+ doc.MediaType == ocispec.MediaTypeImageIndex {
+ return fmt.Errorf("media-type: expected manifest but found index (%s)", mt)
+ }
+ case MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex:
+ if len(doc.Config) != 0 || len(doc.Layers) != 0 ||
+ doc.MediaType == MediaTypeDockerSchema2Manifest ||
+ doc.MediaType == ocispec.MediaTypeImageManifest {
+ return fmt.Errorf("media-type: expected index but found manifest (%s)", mt)
+ }
+ }
+ return nil
+}
+
// RootFS returns the unpacked diffids that make up and images rootfs.
//
// These are used to verify that a set of layers unpacked to the expected
diff -Nru containerd-1.4.5~ds1/.mailmap containerd-1.4.12~ds1/.mailmap
--- containerd-1.4.5~ds1/.mailmap 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/.mailmap 2021-11-18 03:52:12.000000000 +0800
@@ -17,6 +17,7 @@
Cao Zhihao <caozhihao@163.com>
Cao Zhihao <caozhihao@163.com> <caozhihao.xd@bytedance.com>
Carlos Eduardo <me@carlosedp.com> <me@carlosedp.com>
+Cory Bennett <cbennett@netflix.com>
Cristian Staretu <cristian.staretu@gmail.com>
Cristian Staretu <cristian.staretu@gmail.com> <unclejack@users.noreply.github.com>
Daniel Dao <dqminh89@gmail.com>
@@ -73,6 +74,7 @@
Nishchay Kumar <mrawesomenix@gmail.com>
Oliver Stenbom <oliver@stenbom.eu> <ostenbom@pivotal.io>
Phil Estes <estesp@gmail.com> <estesp@linux.vnet.ibm.com>
+Phil Estes <estesp@gmail.com> <estesp@amazon.com>
Reid Li <reid.li@utexas.edu>
Ross Boucher <rboucher@gmail.com>
Ruediger Maass <ruediger.maass@de.ibm.com>
@@ -90,6 +92,7 @@
Su Fei <fesu@ebay.com> <fesu@ebay.com>
Ted Yu <yuzhihong@gmail.com>
Tõnis Tiigi <tonistiigi@gmail.com>
+Wei Fu <fuweid89@gmail.com>
Wei Fu <fuweid89@gmail.com> <fhfuwei@163.com>
Xiaodong Zhang <a4012017@sina.com>
Xuean Yan <yan.xuean@zte.com.cn>
diff -Nru containerd-1.4.5~ds1/metadata/containers.go containerd-1.4.12~ds1/metadata/containers.go
--- containerd-1.4.5~ds1/metadata/containers.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/metadata/containers.go 2021-11-18 03:52:12.000000000 +0800
@@ -290,7 +290,7 @@
// image has no validation
for k, v := range container.Labels {
- if err := labels.Validate(k, v); err == nil {
+ if err := labels.Validate(k, v); err != nil {
return errors.Wrapf(err, "containers.Labels")
}
}
diff -Nru containerd-1.4.5~ds1/metadata/content.go containerd-1.4.12~ds1/metadata/content.go
--- containerd-1.4.5~ds1/metadata/content.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/metadata/content.go 2021-11-18 03:52:12.000000000 +0800
@@ -551,13 +551,13 @@
if desc.Size > 0 {
ra, err := nw.provider.ReaderAt(ctx, nw.desc)
if err != nil {
+ w.Close()
return err
}
defer ra.Close()
if err := content.CopyReaderAt(w, ra, desc.Size); err != nil {
- nw.w.Close()
- nw.w = nil
+ w.Close()
return err
}
}
@@ -708,7 +708,7 @@
func validateInfo(info *content.Info) error {
for k, v := range info.Labels {
- if err := labels.Validate(k, v); err == nil {
+ if err := labels.Validate(k, v); err != nil {
return errors.Wrapf(err, "info.Labels")
}
}
diff -Nru containerd-1.4.5~ds1/remotes/docker/authorizer.go containerd-1.4.12~ds1/remotes/docker/authorizer.go
--- containerd-1.4.5~ds1/remotes/docker/authorizer.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/remotes/docker/authorizer.go 2021-11-18 03:52:12.000000000 +0800
@@ -31,6 +31,7 @@
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/log"
+ "github.com/containerd/containerd/version"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/net/context/ctxhttp"
@@ -356,6 +357,9 @@
req.Header[k] = append(req.Header[k], v...)
}
}
+ if len(req.Header.Get("User-Agent")) == 0 {
+ req.Header.Set("User-Agent", "containerd/"+version.Version)
+ }
resp, err := ctxhttp.Do(ctx, ah.client, req)
if err != nil {
@@ -408,6 +412,9 @@
req.Header[k] = append(req.Header[k], v...)
}
}
+ if len(req.Header.Get("User-Agent")) == 0 {
+ req.Header.Set("User-Agent", "containerd/"+version.Version)
+ }
reqParams := req.URL.Query()
diff -Nru containerd-1.4.5~ds1/remotes/docker/fetcher.go containerd-1.4.12~ds1/remotes/docker/fetcher.go
--- containerd-1.4.5~ds1/remotes/docker/fetcher.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/remotes/docker/fetcher.go 2021-11-18 03:52:12.000000000 +0800
@@ -60,6 +60,10 @@
log.G(ctx).WithError(err).Debug("failed to parse")
continue
}
+ if u.Scheme != "http" && u.Scheme != "https" {
+ log.G(ctx).Debug("non-http(s) alternative url is unsupported")
+ continue
+ }
log.G(ctx).Debug("trying alternative url")
// Try this first, parse it
@@ -148,7 +152,7 @@
})
}
-func (r dockerFetcher) open(ctx context.Context, req *request, mediatype string, offset int64) (io.ReadCloser, error) {
+func (r dockerFetcher) open(ctx context.Context, req *request, mediatype string, offset int64) (_ io.ReadCloser, retErr error) {
req.header.Set("Accept", strings.Join([]string{mediatype, `*/*`}, ", "))
if offset > 0 {
@@ -162,13 +166,17 @@
if err != nil {
return nil, err
}
+ defer func() {
+ if retErr != nil {
+ resp.Body.Close()
+ }
+ }()
if resp.StatusCode > 299 {
// TODO(stevvooe): When doing a offset specific request, we should
// really distinguish between a 206 and a 200. In the case of 200, we
// can discard the bytes, hiding the seek behavior from the
// implementation.
- defer resp.Body.Close()
if resp.StatusCode == http.StatusNotFound {
return nil, errors.Wrapf(errdefs.ErrNotFound, "content at %v not found", req.String())
diff -Nru containerd-1.4.5~ds1/remotes/docker/pusher.go containerd-1.4.12~ds1/remotes/docker/pusher.go
--- containerd-1.4.5~ds1/remotes/docker/pusher.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/remotes/docker/pusher.go 2021-11-18 03:52:12.000000000 +0800
@@ -109,12 +109,15 @@
// TODO: Set updated time?
},
})
+ resp.Body.Close()
return nil, errors.Wrapf(errdefs.ErrAlreadyExists, "content %v on remote", desc.Digest)
}
} else if resp.StatusCode != http.StatusNotFound {
+ resp.Body.Close()
// TODO: log error
return nil, errors.Errorf("unexpected response: %s", resp.Status)
}
+ resp.Body.Close()
}
if isManifest {
@@ -155,6 +158,7 @@
return nil, err
}
}
+ defer resp.Body.Close()
switch resp.StatusCode {
case http.StatusOK, http.StatusAccepted, http.StatusNoContent:
@@ -338,6 +342,7 @@
if resp == nil {
return errors.New("no response")
}
+ defer resp.Body.Close()
// 201 is specified return status, some registries return
// 200, 202 or 204.
diff -Nru containerd-1.4.5~ds1/remotes/docker/resolver.go containerd-1.4.12~ds1/remotes/docker/resolver.go
--- containerd-1.4.5~ds1/remotes/docker/resolver.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/remotes/docker/resolver.go 2021-11-18 03:52:12.000000000 +0800
@@ -238,10 +238,10 @@
}
var (
- lastErr error
- paths [][]string
- dgst = refspec.Digest()
- caps = HostCapabilityPull
+ firstErr error
+ paths [][]string
+ dgst = refspec.Digest()
+ caps = HostCapabilityPull
)
if dgst != "" {
@@ -292,8 +292,8 @@
err = errors.Wrapf(err, "pull access denied, repository does not exist or may require authorization")
}
// Store the error for referencing later
- if lastErr == nil {
- lastErr = err
+ if firstErr == nil {
+ firstErr = err
}
log.G(ctx).WithError(err).Info("trying next host")
continue // try another host
@@ -305,7 +305,14 @@
log.G(ctx).Info("trying next host - response was http.StatusNotFound")
continue
}
- return "", ocispec.Descriptor{}, errors.Errorf("unexpected status code %v: %v", u, resp.Status)
+ if resp.StatusCode > 399 {
+ // Set firstErr when encountering the first non-404 status code.
+ if firstErr == nil {
+ firstErr = errors.Errorf("pulling from host %s failed with status code %v: %v", host.Host, u, resp.Status)
+ }
+ continue // try another host
+ }
+ return "", ocispec.Descriptor{}, errors.Errorf("pulling from host %s failed with unexpected status code %v: %v", host.Host, u, resp.Status)
}
size := resp.ContentLength
contentType := getManifestMediaType(resp)
@@ -368,8 +375,8 @@
}
// Prevent resolving to excessively large manifests
if size > MaxManifestSize {
- if lastErr == nil {
- lastErr = errors.Wrapf(errdefs.ErrNotFound, "rejecting %d byte manifest for %s", size, ref)
+ if firstErr == nil {
+ firstErr = errors.Wrapf(errdefs.ErrNotFound, "rejecting %d byte manifest for %s", size, ref)
}
continue
}
@@ -385,11 +392,15 @@
}
}
- if lastErr == nil {
- lastErr = errors.Wrap(errdefs.ErrNotFound, ref)
+ // If above loop terminates without return, then there was an error.
+ // "firstErr" contains the first non-404 error. That is, "firstErr == nil"
+ // means that either no registries were given or each registry returned 404.
+
+ if firstErr == nil {
+ firstErr = errors.Wrap(errdefs.ErrNotFound, ref)
}
- return "", ocispec.Descriptor{}, lastErr
+ return "", ocispec.Descriptor{}, firstErr
}
func (r *dockerResolver) Fetcher(ctx context.Context, ref string) (remotes.Fetcher, error) {
@@ -548,7 +559,21 @@
if err := r.authorize(ctx, req); err != nil {
return nil, errors.Wrap(err, "failed to authorize")
}
- resp, err := ctxhttp.Do(ctx, r.host.Client, req)
+
+ var client = &http.Client{}
+ if r.host.Client != nil {
+ *client = *r.host.Client
+ }
+ if client.CheckRedirect == nil {
+ client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
+ if len(via) >= 10 {
+ return errors.New("stopped after 10 redirects")
+ }
+ return errors.Wrap(r.authorize(ctx, req), "failed to authorize redirect")
+ }
+ }
+
+ resp, err := ctxhttp.Do(ctx, client, req)
if err != nil {
return nil, errors.Wrap(err, "failed to do request")
}
diff -Nru containerd-1.4.5~ds1/remotes/docker/schema1/converter.go containerd-1.4.12~ds1/remotes/docker/schema1/converter.go
--- containerd-1.4.5~ds1/remotes/docker/schema1/converter.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/remotes/docker/schema1/converter.go 2021-11-18 03:52:12.000000000 +0800
@@ -256,6 +256,9 @@
if err := json.Unmarshal(b, &m); err != nil {
return err
}
+ if len(m.Manifests) != 0 || len(m.Layers) != 0 {
+ return errors.New("converter: expected schema1 document but found extra keys")
+ }
c.pulledManifest = &m
return nil
@@ -472,8 +475,10 @@
}
type manifest struct {
- FSLayers []fsLayer `json:"fsLayers"`
- History []history `json:"history"`
+ FSLayers []fsLayer `json:"fsLayers"`
+ History []history `json:"history"`
+ Layers json.RawMessage `json:"layers,omitempty"` // OCI manifest
+ Manifests json.RawMessage `json:"manifests,omitempty"` // OCI index
}
type v1History struct {
diff -Nru containerd-1.4.5~ds1/runtime/v1/linux/bundle.go containerd-1.4.12~ds1/runtime/v1/linux/bundle.go
--- containerd-1.4.5~ds1/runtime/v1/linux/bundle.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/runtime/v1/linux/bundle.go 2021-11-18 03:52:12.000000000 +0800
@@ -21,6 +21,7 @@
import (
"context"
"crypto/sha256"
+ "encoding/json"
"fmt"
"io/ioutil"
"os"
@@ -30,6 +31,7 @@
"github.com/containerd/containerd/runtime/linux/runctypes"
"github.com/containerd/containerd/runtime/v1/shim"
"github.com/containerd/containerd/runtime/v1/shim/client"
+ "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
)
@@ -48,7 +50,7 @@
return nil, err
}
path = filepath.Join(path, id)
- if err := os.Mkdir(path, 0711); err != nil {
+ if err := os.Mkdir(path, 0700); err != nil {
return nil, err
}
defer func() {
@@ -56,6 +58,9 @@
os.RemoveAll(path)
}
}()
+ if err := prepareBundleDirectoryPermissions(path, spec); err != nil {
+ return nil, err
+ }
workDir = filepath.Join(workDir, id)
if err := os.MkdirAll(workDir, 0711); err != nil {
return nil, err
@@ -77,6 +82,55 @@
}, err
}
+// prepareBundleDirectoryPermissions prepares the permissions of the bundle
+// directory. When user namespaces are enabled, the permissions are modified
+// to allow the remapped root GID to access the bundle.
+func prepareBundleDirectoryPermissions(path string, spec []byte) error {
+ gid, err := remappedGID(spec)
+ if err != nil {
+ return err
+ }
+ if gid == 0 {
+ return nil
+ }
+ if err := os.Chown(path, -1, int(gid)); err != nil {
+ return err
+ }
+ return os.Chmod(path, 0710)
+}
+
+// ociSpecUserNS is a subset of specs.Spec used to reduce garbage during
+// unmarshal.
+type ociSpecUserNS struct {
+ Linux *linuxSpecUserNS
+}
+
+// linuxSpecUserNS is a subset of specs.Linux used to reduce garbage during
+// unmarshal.
+type linuxSpecUserNS struct {
+ GIDMappings []specs.LinuxIDMapping
+}
+
+// remappedGID reads the remapped GID 0 from the OCI spec, if it exists. If
+// there is no remapping, remappedGID returns 0. If the spec cannot be parsed,
+// remappedGID returns an error.
+func remappedGID(spec []byte) (uint32, error) {
+ var ociSpec ociSpecUserNS
+ err := json.Unmarshal(spec, &ociSpec)
+ if err != nil {
+ return 0, err
+ }
+ if ociSpec.Linux == nil || len(ociSpec.Linux.GIDMappings) == 0 {
+ return 0, nil
+ }
+ for _, mapping := range ociSpec.Linux.GIDMappings {
+ if mapping.ContainerID == 0 {
+ return mapping.HostID, nil
+ }
+ }
+ return 0, nil
+}
+
type bundle struct {
id string
path string
diff -Nru containerd-1.4.5~ds1/runtime/v2/bundle_default.go containerd-1.4.12~ds1/runtime/v2/bundle_default.go
--- containerd-1.4.5~ds1/runtime/v2/bundle_default.go 1970-01-01 08:00:00.000000000 +0800
+++ containerd-1.4.12~ds1/runtime/v2/bundle_default.go 2021-11-18 03:52:12.000000000 +0800
@@ -0,0 +1,24 @@
+//go:build !linux
+// +build !linux
+
+/*
+ Copyright The containerd Authors.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package v2
+
+// prepareBundleDirectoryPermissions prepares the permissions of the bundle
+// directory according to the needs of the current platform.
+func prepareBundleDirectoryPermissions(path string, spec []byte) error { return nil }
diff -Nru containerd-1.4.5~ds1/runtime/v2/bundle.go containerd-1.4.12~ds1/runtime/v2/bundle.go
--- containerd-1.4.5~ds1/runtime/v2/bundle.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/runtime/v2/bundle.go 2021-11-18 03:52:12.000000000 +0800
@@ -72,7 +72,10 @@
if err := os.MkdirAll(filepath.Dir(b.Path), 0711); err != nil {
return nil, err
}
- if err := os.Mkdir(b.Path, 0711); err != nil {
+ if err := os.Mkdir(b.Path, 0700); err != nil {
+ return nil, err
+ }
+ if err := prepareBundleDirectoryPermissions(b.Path, spec); err != nil {
return nil, err
}
paths = append(paths, b.Path)
diff -Nru containerd-1.4.5~ds1/runtime/v2/bundle_linux.go containerd-1.4.12~ds1/runtime/v2/bundle_linux.go
--- containerd-1.4.5~ds1/runtime/v2/bundle_linux.go 1970-01-01 08:00:00.000000000 +0800
+++ containerd-1.4.12~ds1/runtime/v2/bundle_linux.go 2021-11-18 03:52:12.000000000 +0800
@@ -0,0 +1,74 @@
+/*
+ Copyright The containerd Authors.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package v2
+
+import (
+ "encoding/json"
+ "os"
+
+ "github.com/opencontainers/runtime-spec/specs-go"
+)
+
+// prepareBundleDirectoryPermissions prepares the permissions of the bundle
+// directory according to the needs of the current platform.
+// On Linux when user namespaces are enabled, the permissions are modified to
+// allow the remapped root GID to access the bundle.
+func prepareBundleDirectoryPermissions(path string, spec []byte) error {
+ gid, err := remappedGID(spec)
+ if err != nil {
+ return err
+ }
+ if gid == 0 {
+ return nil
+ }
+ if err := os.Chown(path, -1, int(gid)); err != nil {
+ return err
+ }
+ return os.Chmod(path, 0710)
+}
+
+// ociSpecUserNS is a subset of specs.Spec used to reduce garbage during
+// unmarshal.
+type ociSpecUserNS struct {
+ Linux *linuxSpecUserNS
+}
+
+// linuxSpecUserNS is a subset of specs.Linux used to reduce garbage during
+// unmarshal.
+type linuxSpecUserNS struct {
+ GIDMappings []specs.LinuxIDMapping
+}
+
+// remappedGID reads the remapped GID 0 from the OCI spec, if it exists. If
+// there is no remapping, remappedGID returns 0. If the spec cannot be parsed,
+// remappedGID returns an error.
+func remappedGID(spec []byte) (uint32, error) {
+ var ociSpec ociSpecUserNS
+ err := json.Unmarshal(spec, &ociSpec)
+ if err != nil {
+ return 0, err
+ }
+ if ociSpec.Linux == nil || len(ociSpec.Linux.GIDMappings) == 0 {
+ return 0, nil
+ }
+ for _, mapping := range ociSpec.Linux.GIDMappings {
+ if mapping.ContainerID == 0 {
+ return mapping.HostID, nil
+ }
+ }
+ return 0, nil
+}
diff -Nru containerd-1.4.5~ds1/script/setup/runc-version containerd-1.4.12~ds1/script/setup/runc-version
--- containerd-1.4.5~ds1/script/setup/runc-version 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/script/setup/runc-version 2021-11-18 03:52:12.000000000 +0800
@@ -1 +1 @@
-v1.0.0-rc94
+v1.0.2
diff -Nru containerd-1.4.5~ds1/snapshots/btrfs/btrfs.go containerd-1.4.12~ds1/snapshots/btrfs/btrfs.go
--- containerd-1.4.5~ds1/snapshots/btrfs/btrfs.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/snapshots/btrfs/btrfs.go 2021-11-18 03:52:12.000000000 +0800
@@ -63,11 +63,15 @@
// root needs to be a mount point of btrfs.
func NewSnapshotter(root string) (snapshots.Snapshotter, error) {
// If directory does not exist, create it
- if _, err := os.Stat(root); err != nil {
+ if st, err := os.Stat(root); err != nil {
if !os.IsNotExist(err) {
return nil, err
}
- if err := os.Mkdir(root, 0755); err != nil {
+ if err := os.Mkdir(root, 0700); err != nil {
+ return nil, err
+ }
+ } else if st.Mode()&os.ModePerm != 0700 {
+ if err := os.Chmod(root, 0700); err != nil {
return nil, err
}
}
diff -Nru containerd-1.4.5~ds1/snapshots/devmapper/snapshotter.go containerd-1.4.12~ds1/snapshots/devmapper/snapshotter.go
--- containerd-1.4.5~ds1/snapshots/devmapper/snapshotter.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/snapshots/devmapper/snapshotter.go 2021-11-18 03:52:12.000000000 +0800
@@ -232,7 +232,7 @@
// View creates readonly thin device for the given snapshot key
func (s *Snapshotter) View(ctx context.Context, key, parent string, opts ...snapshots.Opt) ([]mount.Mount, error) {
- log.G(ctx).WithFields(logrus.Fields{"key": key, "parent": parent}).Debug("prepare")
+ log.G(ctx).WithFields(logrus.Fields{"key": key, "parent": parent}).Debug("view")
var (
mounts []mount.Mount
@@ -511,6 +511,8 @@
}
func (s *Snapshotter) Cleanup(ctx context.Context) error {
+ log.G(ctx).Debug("cleanup")
+
var removedDevices []*DeviceInfo
if !s.config.AsyncRemove {
diff -Nru containerd-1.4.5~ds1/Vagrantfile containerd-1.4.12~ds1/Vagrantfile
--- containerd-1.4.5~ds1/Vagrantfile 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/Vagrantfile 2021-11-18 03:52:12.000000000 +0800
@@ -77,7 +77,7 @@
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.15.11",
+ 'GO_VERSION': ENV['GO_VERSION'] || "1.16.10",
}
sh.inline = <<~SHELL
#!/usr/bin/env bash
diff -Nru containerd-1.4.5~ds1/vendor/github.com/containerd/cri/pkg/os/os.go containerd-1.4.12~ds1/vendor/github.com/containerd/cri/pkg/os/os.go
--- containerd-1.4.5~ds1/vendor/github.com/containerd/cri/pkg/os/os.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/vendor/github.com/containerd/cri/pkg/os/os.go 2021-11-18 03:52:12.000000000 +0800
@@ -20,7 +20,6 @@
"io"
"io/ioutil"
"os"
- "path/filepath"
"github.com/docker/docker/pkg/symlink"
)
@@ -56,18 +55,6 @@
return os.Stat(name)
}
-// ResolveSymbolicLink will follow any symbolic links
-func (RealOS) ResolveSymbolicLink(path string) (string, error) {
- info, err := os.Lstat(path)
- if err != nil {
- return "", err
- }
- if info.Mode()&os.ModeSymlink != os.ModeSymlink {
- return path, nil
- }
- return filepath.EvalSymlinks(path)
-}
-
// FollowSymlinkInScope will call symlink.FollowSymlinkInScope.
func (RealOS) FollowSymlinkInScope(path, scope string) (string, error) {
return symlink.FollowSymlinkInScope(path, scope)
diff -Nru containerd-1.4.5~ds1/vendor/github.com/containerd/cri/pkg/os/os_unix.go containerd-1.4.12~ds1/vendor/github.com/containerd/cri/pkg/os/os_unix.go
--- containerd-1.4.5~ds1/vendor/github.com/containerd/cri/pkg/os/os_unix.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/vendor/github.com/containerd/cri/pkg/os/os_unix.go 2021-11-18 03:52:12.000000000 +0800
@@ -19,6 +19,9 @@
package os
import (
+ "os"
+ "path/filepath"
+
"github.com/containerd/containerd/mount"
"golang.org/x/sys/unix"
)
@@ -57,3 +60,15 @@
return err
}
+
+// ResolveSymbolicLink will follow any symbolic links
+func (RealOS) ResolveSymbolicLink(path string) (string, error) {
+ info, err := os.Lstat(path)
+ if err != nil {
+ return "", err
+ }
+ if info.Mode()&os.ModeSymlink != os.ModeSymlink {
+ return path, nil
+ }
+ return filepath.EvalSymlinks(path)
+}
diff -Nru containerd-1.4.5~ds1/vendor/github.com/containerd/cri/pkg/server/sandbox_run.go containerd-1.4.12~ds1/vendor/github.com/containerd/cri/pkg/server/sandbox_run.go
--- containerd-1.4.5~ds1/vendor/github.com/containerd/cri/pkg/server/sandbox_run.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/vendor/github.com/containerd/cri/pkg/server/sandbox_run.go 2021-11-18 03:52:12.000000000 +0800
@@ -124,8 +124,10 @@
sandbox.NetNSPath = sandbox.NetNS.GetPath()
defer func() {
if retErr != nil {
+ deferCtx, deferCancel := ctrdutil.DeferContext()
+ defer deferCancel()
// Teardown network if an error is returned.
- if err := c.teardownPodNetwork(ctx, sandbox); err != nil {
+ if err := c.teardownPodNetwork(deferCtx, sandbox); err != nil {
log.G(ctx).WithError(err).Errorf("Failed to destroy network for sandbox %q", id)
}
diff -Nru containerd-1.4.5~ds1/version/version.go containerd-1.4.12~ds1/version/version.go
--- containerd-1.4.5~ds1/version/version.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/version/version.go 2021-11-18 03:52:12.000000000 +0800
@@ -23,7 +23,7 @@
Package = "github.com/containerd/containerd"
// Version holds the complete version number. Filled in at linking time.
- Version = "1.4.5+unknown"
+ Version = "1.4.12+unknown"
// Revision is filled with the VCS (e.g. git) revision being used to build
// the program at linking time.
[ Other info ]
Since it's a Go package, and containerd as library is static linked in other packages.
However I don't think we need to rebuild other packages. The most fixes are targeted
for containerd as a program.
The RPi0/RPi1 workaround may need to rebuild docker.io. But I think we can skip this
time. As I think docker.io needs its own update for bullseye as well, to fix things
like supporting "clone3" syscall.
diff -Nru containerd-1.4.5~ds1/archive/tar_test.go containerd-1.4.12~ds1/archive/tar_test.go
--- containerd-1.4.5~ds1/archive/tar_test.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/archive/tar_test.go 2021-11-18 03:52:12.000000000 +0800
@@ -243,6 +243,11 @@
return nil
}
errFileDiff := errors.New("files differ")
+ td, err := ioutil.TempDir("", "test-breakouts-")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer os.RemoveAll(td)
isSymlinkFile := func(f string) func(string) error {
return func(root string) error {
@@ -744,6 +749,36 @@
// resolution ends up just removing etc
validator: fileNotExists("etc/passwd"),
},
+ {
+
+ name: "HardlinkSymlinkChmod",
+ w: func() tartest.WriterToTar {
+ p := filepath.Join(td, "perm400")
+ if err := ioutil.WriteFile(p, []byte("..."), 0400); err != nil {
+ t.Fatal(err)
+ }
+ ep := filepath.Join(td, "also-exists-outside-root")
+ if err := ioutil.WriteFile(ep, []byte("..."), 0640); err != nil {
+ t.Fatal(err)
+ }
+
+ return tartest.TarAll(
+ tc.Symlink(p, ep),
+ tc.Link(ep, "sketchylink"),
+ )
+ }(),
+ validator: func(string) error {
+ p := filepath.Join(td, "perm400")
+ fi, err := os.Lstat(p)
+ if err != nil {
+ return err
+ }
+ if perm := fi.Mode() & os.ModePerm; perm != 0400 {
+ return errors.Errorf("%s perm changed from 0400 to %04o", p, perm)
+ }
+ return nil
+ },
+ },
}
for _, bo := range breakouts {
diff -Nru containerd-1.4.5~ds1/archive/tar_unix.go containerd-1.4.12~ds1/archive/tar_unix.go
--- containerd-1.4.5~ds1/archive/tar_unix.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/archive/tar_unix.go 2021-11-18 03:52:12.000000000 +0800
@@ -113,7 +113,7 @@
func handleLChmod(hdr *tar.Header, path string, hdrInfo os.FileInfo) error {
if hdr.Typeflag == tar.TypeLink {
- if fi, err := os.Lstat(hdr.Linkname); err == nil && (fi.Mode()&os.ModeSymlink == 0) {
+ if fi, err := os.Lstat(path); err == nil && (fi.Mode()&os.ModeSymlink == 0) {
if err := os.Chmod(path, hdrInfo.Mode()); err != nil && !os.IsNotExist(err) {
return err
}
diff -Nru containerd-1.4.5~ds1/client_test.go containerd-1.4.12~ds1/client_test.go
--- containerd-1.4.5~ds1/client_test.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/client_test.go 2021-11-18 03:52:12.000000000 +0800
@@ -309,7 +309,7 @@
defer cancel()
cs := client.ContentStore()
- img, err := client.Fetch(ctx, "docker.io/library/busybox:latest")
+ img, err := client.Fetch(ctx, "ghcr.io/containerd/busybox:latest")
if err != nil {
t.Fatal(err)
}
diff -Nru containerd-1.4.5~ds1/client_unix_test.go containerd-1.4.12~ds1/client_unix_test.go
--- containerd-1.4.5~ds1/client_unix_test.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/client_unix_test.go 2021-11-18 03:52:12.000000000 +0800
@@ -40,17 +40,17 @@
func init() {
switch runtime.GOARCH {
case "386":
- testImage = "docker.io/i386/alpine:latest"
+ testImage = "ghcr.io/containerd/alpine:latest-i386"
case "arm":
- testImage = "docker.io/arm32v6/alpine:latest"
+ testImage = "ghcr.io/containerd/alpine:latest-arm32v6"
case "arm64":
- testImage = "docker.io/arm64v8/alpine:latest"
+ testImage = "ghcr.io/containerd/alpine:latest-arm64v8"
case "ppc64le":
- testImage = "docker.io/ppc64le/alpine:latest"
+ testImage = "ghcr.io/containerd/alpine:latest-ppc64le"
case "s390x":
- testImage = "docker.io/s390x/alpine:latest"
+ testImage = "ghcr.io/containerd/alpine:latest-s390x"
default:
- testImage = "docker.io/library/alpine:latest"
+ testImage = "ghcr.io/containerd/alpine:latest"
}
}
diff -Nru containerd-1.4.5~ds1/content/local/store.go containerd-1.4.12~ds1/content/local/store.go
--- containerd-1.4.5~ds1/content/local/store.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/content/local/store.go 2021-11-18 03:52:12.000000000 +0800
@@ -502,7 +502,7 @@
if ref != status.Ref {
// NOTE(stevvooe): This is fairly catastrophic. Either we have some
// layout corruption or a hash collision for the ref key.
- return status, errors.Wrapf(err, "ref key does not match: %v != %v", ref, status.Ref)
+ return status, errors.Errorf("ref key does not match: %v != %v", ref, status.Ref)
}
if total > 0 && status.Total > 0 && total != status.Total {
diff -Nru containerd-1.4.5~ds1/contrib/Dockerfile.test containerd-1.4.12~ds1/contrib/Dockerfile.test
--- containerd-1.4.5~ds1/contrib/Dockerfile.test 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/contrib/Dockerfile.test 2021-11-18 03:52:12.000000000 +0800
@@ -10,7 +10,7 @@
#
# docker build -t containerd-test --build-arg RUNC_VERSION=v1.0.0-rc93 -f Dockerfile.test ../
-ARG GOLANG_VERSION=1.15.11
+ARG GOLANG_VERSION=1.16.10
FROM golang:${GOLANG_VERSION} AS golang-base
RUN mkdir -p /go/src/github.com/containerd/containerd
diff -Nru containerd-1.4.5~ds1/contrib/seccomp/seccomp_default.go containerd-1.4.12~ds1/contrib/seccomp/seccomp_default.go
--- containerd-1.4.5~ds1/contrib/seccomp/seccomp_default.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/contrib/seccomp/seccomp_default.go 2021-11-18 03:52:12.000000000 +0800
@@ -49,6 +49,7 @@
// DefaultProfile defines the allowed syscalls for the default seccomp profile.
func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
+ nosys := uint(unix.ENOSYS)
syscalls := []specs.LinuxSyscall{
{
Names: []string{
@@ -524,6 +525,7 @@
Names: []string{
"bpf",
"clone",
+ "clone3",
"fanotify_init",
"lookup_dcookie",
"mount",
@@ -648,6 +650,15 @@
},
})
}
+ // clone3 is explicitly requested to give ENOSYS instead of the default EPERM, when CAP_SYS_ADMIN is unset
+ // https://github.com/moby/moby/pull/42681
+ s.Syscalls = append(s.Syscalls, specs.LinuxSyscall{
+ Names: []string{
+ "clone3",
+ },
+ Action: specs.ActErrno,
+ ErrnoRet: &nosys,
+ })
}
return s
diff -Nru containerd-1.4.5~ds1/debian/changelog containerd-1.4.12~ds1/debian/changelog
--- containerd-1.4.5~ds1/debian/changelog 2021-10-05 18:45:47.000000000 +0800
+++ containerd-1.4.12~ds1/debian/changelog 2021-11-23 18:42:16.000000000 +0800
@@ -1,3 +1,34 @@
+containerd (1.4.12~ds1-1~deb11u1) bullseye; urgency=medium
+
+ * New upstream version 1.4.12~ds1
+ + 1.4.12
+ * Mitigate CVE-2021-41190: Handle ambiguous OCI manifest parsing
+ * Update pull to try next mirror for non-404 errors
+ * Update pull to handle of non-https urls in descriptors
+ + 1.4.11
+ * CVE-2021-41103: Fix insufficiently restricted permissions on container
+ root and plugin directories
+ + 1.4.10
+ * Support "clone3" in default seccomp profile
+ * Fix panic in metadata content writer on copy error
+ + 1.4.9
+ * Update pull authorization logic on redirect
+ * Fix user agent used for fetching registry authentication tokens
+ + 1.4.8
+ * CVE-2021-32760: Archive package allows chmod of file outside of unpack
+ target directory
+ + 1.4.7
+ * Fix invalid validation error checking
+ * Fix error on image pull resume
+ * Refresh patches
+ + Drop CVE-2021-32760 patch
+ + Drop CVE-2021-41103 patch
+ + Refresh 0005-backport-github.com-containerd-containerd-remotes.patch
+ with latest 1.5 release branch
+ * Backport RPi1/RPi0 workaround (Closes: #998909)
+
+ -- Shengjing Zhu <zhsj@debian.org> Tue, 23 Nov 2021 18:42:16 +0800
+
containerd (1.4.5~ds1-2+deb11u1) bullseye-security; urgency=high
* CVE-2021-41103: Insufficiently restricted permissions on container
diff -Nru containerd-1.4.5~ds1/debian/patches/0004-Add-cgo-tag-to-btrfs-plugin.patch containerd-1.4.12~ds1/debian/patches/0004-Add-cgo-tag-to-btrfs-plugin.patch
--- containerd-1.4.5~ds1/debian/patches/0004-Add-cgo-tag-to-btrfs-plugin.patch 2021-10-05 18:45:47.000000000 +0800
+++ containerd-1.4.12~ds1/debian/patches/0004-Add-cgo-tag-to-btrfs-plugin.patch 2021-11-23 18:42:16.000000000 +0800
@@ -20,7 +20,7 @@
/*
Copyright The containerd Authors.
diff --git a/snapshots/btrfs/btrfs.go b/snapshots/btrfs/btrfs.go
-index ea90853..eef883b 100644
+index 78f825c..778b783 100644
--- a/snapshots/btrfs/btrfs.go
+++ b/snapshots/btrfs/btrfs.go
@@ -1,4 +1,4 @@
diff -Nru containerd-1.4.5~ds1/debian/patches/0005-backport-github.com-containerd-containerd-remotes.patch containerd-1.4.12~ds1/debian/patches/0005-backport-github.com-containerd-containerd-remotes.patch
--- containerd-1.4.5~ds1/debian/patches/0005-backport-github.com-containerd-containerd-remotes.patch 2021-10-05 18:45:47.000000000 +0800
+++ containerd-1.4.12~ds1/debian/patches/0005-backport-github.com-containerd-containerd-remotes.patch 2021-11-23 18:42:16.000000000 +0800
@@ -1,6 +1,7 @@
From: Shengjing Zhu <zhsj@debian.org>
-Date: Fri, 5 Mar 2021 16:35:17 +0800
-Subject: backport_github=2Ecom/containerd/containerd/remotes
+Date: Tue, 23 Nov 2021 15:49:57 +0800
+Subject: =?utf-8?q?backport_github=2Ecom/containerd/containerd/remotes?=
+ =?utf-8?q?=C2=AC?=
For building docker.io 20.10
@@ -10,19 +11,19 @@
Forwarded: not-needed
---
- remotes/docker/auth.go | 198 ---------------------------
- remotes/docker/auth/fetch.go | 202 +++++++++++++++++++++++++++
- remotes/docker/auth/parse.go | 203 ++++++++++++++++++++++++++++
- remotes/docker/authorizer.go | 285 ++++++++++-----------------------------
+ remotes/docker/auth.go | 198 --------------------------
+ remotes/docker/auth/fetch.go | 209 ++++++++++++++++++++++++++++
+ remotes/docker/auth/parse.go | 203 +++++++++++++++++++++++++++
+ remotes/docker/authorizer.go | 292 +++++++++------------------------------
remotes/docker/errcode.go | 2 +-
remotes/docker/fetcher.go | 2 +-
remotes/docker/httpreadseeker.go | 2 +-
- remotes/docker/pusher.go | 36 +++--
- remotes/docker/resolver.go | 47 +++----
+ remotes/docker/pusher.go | 38 +++--
+ remotes/docker/resolver.go | 49 +++----
remotes/docker/scope.go | 14 +-
remotes/docker/scope_test.go | 4 +-
- remotes/errors/errors.go | 46 +++++++
- 12 files changed, 573 insertions(+), 468 deletions(-)
+ remotes/errors/errors.go | 46 ++++++
+ 12 files changed, 581 insertions(+), 478 deletions(-)
delete mode 100644 remotes/docker/auth.go
create mode 100644 remotes/docker/auth/fetch.go
create mode 100644 remotes/docker/auth/parse.go
@@ -234,10 +235,10 @@
-}
diff --git a/remotes/docker/auth/fetch.go b/remotes/docker/auth/fetch.go
new file mode 100644
-index 0000000..0d01c81
+index 0000000..8b0a87e
--- /dev/null
+++ b/remotes/docker/auth/fetch.go
-@@ -0,0 +1,202 @@
+@@ -0,0 +1,209 @@
+/*
+ Copyright The containerd Authors.
+
@@ -266,6 +267,7 @@
+
+ "github.com/containerd/containerd/log"
+ remoteserrors "github.com/containerd/containerd/remotes/errors"
++ "github.com/containerd/containerd/version"
+ "github.com/pkg/errors"
+ "golang.org/x/net/context/ctxhttp"
+)
@@ -349,6 +351,9 @@
+ for k, v := range headers {
+ req.Header[k] = append(req.Header[k], v...)
+ }
++ if len(req.Header.Get("User-Agent")) == 0 {
++ req.Header.Set("User-Agent", "containerd/"+version.Version)
++ }
+
+ resp, err := ctxhttp.Do(ctx, client, req)
+ if err != nil {
@@ -393,6 +398,9 @@
+ for k, v := range headers {
+ req.Header[k] = append(req.Header[k], v...)
+ }
++ if len(req.Header.Get("User-Agent")) == 0 {
++ req.Header.Set("User-Agent", "containerd/"+version.Version)
++ }
+
+ reqParams := req.URL.Query()
+
@@ -650,10 +658,10 @@
+ return "", ""
+}
diff --git a/remotes/docker/authorizer.go b/remotes/docker/authorizer.go
-index 001423a..67e4aea 100644
+index 2f459b7..67e4aea 100644
--- a/remotes/docker/authorizer.go
+++ b/remotes/docker/authorizer.go
-@@ -19,21 +19,17 @@ package docker
+@@ -19,22 +19,17 @@ package docker
import (
"context"
"encoding/base64"
@@ -669,6 +677,7 @@
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/log"
+- "github.com/containerd/containerd/version"
+ "github.com/containerd/containerd/remotes/docker/auth"
+ remoteerrors "github.com/containerd/containerd/remotes/errors"
"github.com/pkg/errors"
@@ -677,7 +686,7 @@
)
type dockerAuthorizer struct {
-@@ -135,8 +131,8 @@ func (a *dockerAuthorizer) AddResponses(ctx context.Context, responses []*http.R
+@@ -136,8 +131,8 @@ func (a *dockerAuthorizer) AddResponses(ctx context.Context, responses []*http.R
a.mu.Lock()
defer a.mu.Unlock()
@@ -688,7 +697,7 @@
if err := invalidAuthorization(c, responses); err != nil {
delete(a.handlers, host)
return err
-@@ -152,26 +148,35 @@ func (a *dockerAuthorizer) AddResponses(ctx context.Context, responses []*http.R
+@@ -153,26 +148,35 @@ func (a *dockerAuthorizer) AddResponses(ctx context.Context, responses []*http.R
return nil
}
@@ -731,7 +740,7 @@
return nil
}
}
-@@ -179,38 +184,6 @@ func (a *dockerAuthorizer) AddResponses(ctx context.Context, responses []*http.R
+@@ -180,38 +184,6 @@ func (a *dockerAuthorizer) AddResponses(ctx context.Context, responses []*http.R
return errors.Wrap(errdefs.ErrNotImplemented, "failed to find supported auth scheme")
}
@@ -770,7 +779,7 @@
// authResult is used to control limit rate.
type authResult struct {
sync.WaitGroup
-@@ -227,17 +200,17 @@ type authHandler struct {
+@@ -228,17 +200,17 @@ type authHandler struct {
client *http.Client
// only support basic and bearer schemes
@@ -791,7 +800,7 @@
return &authHandler{
header: hdr,
client: client,
-@@ -249,17 +222,17 @@ func newAuthHandler(client *http.Client, hdr http.Header, scheme authenticationS
+@@ -250,17 +222,17 @@ func newAuthHandler(client *http.Client, hdr http.Header, scheme authenticationS
func (ah *authHandler) authorize(ctx context.Context) (string, error) {
switch ah.scheme {
@@ -813,7 +822,7 @@
if username == "" || secret == "" {
return "", fmt.Errorf("failed to handle basic auth because missing username or secret")
-@@ -269,14 +242,14 @@ func (ah *authHandler) doBasicAuth(ctx context.Context) (string, error) {
+@@ -270,14 +242,14 @@ func (ah *authHandler) doBasicAuth(ctx context.Context) (string, error) {
return fmt.Sprintf("Basic %s", auth), nil
}
@@ -831,7 +840,7 @@
ah.Lock()
if r, exist := ah.scopedTokens[scoped]; exist {
-@@ -291,174 +264,52 @@ func (ah *authHandler) doBearerAuth(ctx context.Context) (string, error) {
+@@ -292,180 +264,52 @@ func (ah *authHandler) doBearerAuth(ctx context.Context) (string, error) {
ah.scopedTokens[scoped] = r
ah.Unlock()
@@ -910,6 +919,9 @@
- req.Header[k] = append(req.Header[k], v...)
- }
- }
+- if len(req.Header.Get("User-Agent")) == 0 {
+- req.Header.Set("User-Agent", "containerd/"+version.Version)
+- }
-
- resp, err := ctxhttp.Do(ctx, ah.client, req)
- if err != nil {
@@ -984,6 +996,9 @@
}
+ return resp.AccessToken, nil
}
+- if len(req.Header.Get("User-Agent")) == 0 {
+- req.Header.Set("User-Agent", "containerd/"+version.Version)
+- }
-
- reqParams := req.URL.Query()
-
@@ -1058,7 +1073,7 @@
Message string
diff --git a/remotes/docker/fetcher.go b/remotes/docker/fetcher.go
-index cd0168b..9d6708d 100644
+index 5aaaf9e..4b2c10e 100644
--- a/remotes/docker/fetcher.go
+++ b/remotes/docker/fetcher.go
@@ -45,7 +45,7 @@ func (r dockerFetcher) Fetch(ctx context.Context, desc ocispec.Descriptor) (io.R
@@ -1084,7 +1099,7 @@
if hrs.rc != nil {
diff --git a/remotes/docker/pusher.go b/remotes/docker/pusher.go
-index d95e0c8..94a270c 100644
+index d46396b..c367b1e 100644
--- a/remotes/docker/pusher.go
+++ b/remotes/docker/pusher.go
@@ -30,6 +30,7 @@ import (
@@ -1104,19 +1119,20 @@
if err != nil {
return nil, err
}
-@@ -112,8 +113,9 @@ func (p dockerPusher) Push(ctx context.Context, desc ocispec.Descriptor) (conten
+@@ -113,9 +114,10 @@ func (p dockerPusher) Push(ctx context.Context, desc ocispec.Descriptor) (conten
return nil, errors.Wrapf(errdefs.ErrAlreadyExists, "content %v on remote", desc.Digest)
}
} else if resp.StatusCode != http.StatusNotFound {
-- // TODO: log error
-- return nil, errors.Errorf("unexpected response: %s", resp.Status)
+ err := remoteserrors.NewUnexpectedStatusErr(resp)
+ log.G(ctx).WithField("resp", resp).WithField("body", string(err.(remoteserrors.ErrUnexpectedStatus).Body)).Debug("unexpected response")
+ resp.Body.Close()
+- // TODO: log error
+- return nil, errors.Errorf("unexpected response: %s", resp.Status)
+ return nil, err
}
+ resp.Body.Close()
}
-
-@@ -128,7 +130,7 @@ func (p dockerPusher) Push(ctx context.Context, desc ocispec.Descriptor) (conten
+@@ -131,7 +133,7 @@ func (p dockerPusher) Push(ctx context.Context, desc ocispec.Descriptor) (conten
var resp *http.Response
if fromRepo := selectRepositoryMountCandidate(p.refspec, desc.Annotations); fromRepo != "" {
preq := requestWithMountFrom(req, desc.Digest.String(), fromRepo)
@@ -1125,7 +1141,7 @@
// NOTE: the fromRepo might be private repo and
// auth service still can grant token without error.
-@@ -166,8 +168,9 @@ func (p dockerPusher) Push(ctx context.Context, desc ocispec.Descriptor) (conten
+@@ -170,8 +172,9 @@ func (p dockerPusher) Push(ctx context.Context, desc ocispec.Descriptor) (conten
})
return nil, errors.Wrapf(errdefs.ErrAlreadyExists, "content %v on remote", desc.Digest)
default:
@@ -1137,7 +1153,7 @@
}
var (
-@@ -219,7 +222,7 @@ func (p dockerPusher) Push(ctx context.Context, desc ocispec.Descriptor) (conten
+@@ -223,7 +226,7 @@ func (p dockerPusher) Push(ctx context.Context, desc ocispec.Descriptor) (conten
// TODO: Support chunked upload
pr, pw := io.Pipe()
@@ -1146,7 +1162,7 @@
body := ioutil.NopCloser(pr)
req.body = func() (io.ReadCloser, error) {
-@@ -237,6 +240,7 @@ func (p dockerPusher) Push(ctx context.Context, desc ocispec.Descriptor) (conten
+@@ -241,6 +244,7 @@ func (p dockerPusher) Push(ctx context.Context, desc ocispec.Descriptor) (conten
defer close(respC)
resp, err := req.doWithRetries(ctx, nil)
if err != nil {
@@ -1154,7 +1170,7 @@
pr.CloseWithError(err)
return
}
-@@ -244,10 +248,11 @@ func (p dockerPusher) Push(ctx context.Context, desc ocispec.Descriptor) (conten
+@@ -248,10 +252,11 @@ func (p dockerPusher) Push(ctx context.Context, desc ocispec.Descriptor) (conten
switch resp.StatusCode {
case http.StatusOK, http.StatusCreated, http.StatusNoContent:
default:
@@ -1169,7 +1185,7 @@
}()
return &pushWriter{
-@@ -280,12 +285,17 @@ func getManifestPath(object string, dgst digest.Digest) []string {
+@@ -284,12 +289,17 @@ func getManifestPath(object string, dgst digest.Digest) []string {
return []string{"manifests", object}
}
@@ -1188,7 +1204,7 @@
isManifest bool
expected digest.Digest
-@@ -335,8 +345,8 @@ func (pw *pushWriter) Commit(ctx context.Context, size int64, expected digest.Di
+@@ -339,10 +349,10 @@ func (pw *pushWriter) Commit(ctx context.Context, size int64, expected digest.Di
// TODO: timeout waiting for response
resp := <-pw.responseC
@@ -1197,10 +1213,13 @@
+ if resp.err != nil {
+ return resp.err
}
+- defer resp.Body.Close()
++ defer resp.Response.Body.Close()
// 201 is specified return status, some registries return
+ // 200, 202 or 204.
diff --git a/remotes/docker/resolver.go b/remotes/docker/resolver.go
-index aea092c..866379e 100644
+index 40831f1..d6ccd70 100644
--- a/remotes/docker/resolver.go
+++ b/remotes/docker/resolver.go
@@ -41,10 +41,6 @@ import (
@@ -1235,8 +1254,8 @@
- }
-
var (
- lastErr error
- paths [][]string
+ firstErr error
+ paths [][]string
@@ -267,7 +258,7 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
return "", ocispec.Descriptor{}, errors.Wrap(errdefs.ErrNotFound, "no resolve hosts")
}
@@ -1246,7 +1265,22 @@
if err != nil {
return "", ocispec.Descriptor{}, err
}
-@@ -393,12 +384,7 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
+@@ -295,14 +286,12 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
+ if firstErr == nil {
+ firstErr = err
+ }
+- log.G(ctx).WithError(err).Info("trying next host")
+ continue // try another host
+ }
+ resp.Body.Close() // don't care about body contents.
+
+ if resp.StatusCode > 299 {
+ if resp.StatusCode == http.StatusNotFound {
+- log.G(ctx).Info("trying next host - response was http.StatusNotFound")
+ continue
+ }
+ if resp.StatusCode > 399 {
+@@ -404,12 +393,7 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
}
func (r *dockerResolver) Fetcher(ctx context.Context, ref string) (remotes.Fetcher, error) {
@@ -1260,7 +1294,7 @@
if err != nil {
return nil, err
}
-@@ -409,23 +395,27 @@ func (r *dockerResolver) Fetcher(ctx context.Context, ref string) (remotes.Fetch
+@@ -420,23 +404,27 @@ func (r *dockerResolver) Fetcher(ctx context.Context, ref string) (remotes.Fetch
}
func (r *dockerResolver) Pusher(ctx context.Context, ref string) (remotes.Pusher, error) {
@@ -1295,7 +1329,7 @@
type dockerBase struct {
refspec reference.Spec
repository string
-@@ -457,10 +447,11 @@ func (r *dockerBase) filterHosts(caps HostCapabilities) (hosts []RegistryHost) {
+@@ -468,10 +456,11 @@ func (r *dockerBase) filterHosts(caps HostCapabilities) (hosts []RegistryHost) {
}
func (r *dockerBase) request(host RegistryHost, method string, ps ...string) *request {
diff -Nru containerd-1.4.5~ds1/debian/patches/0008-Add-RPi1-RPi0-workaround.patch containerd-1.4.12~ds1/debian/patches/0008-Add-RPi1-RPi0-workaround.patch
--- containerd-1.4.5~ds1/debian/patches/0008-Add-RPi1-RPi0-workaround.patch 1970-01-01 08:00:00.000000000 +0800
+++ containerd-1.4.12~ds1/debian/patches/0008-Add-RPi1-RPi0-workaround.patch 2021-11-23 18:42:16.000000000 +0800
@@ -0,0 +1,35 @@
+From: Tianon Gravi <admwiggin@gmail.com>
+Date: Fri, 4 Sep 2020 14:12:04 -0700
+Subject: Add RPi1/RPi0 workaround
+
+On the very popular Raspberry Pi 1 and Zero devices, the CPU is actually ARMv6, but the chip happens to support the feature bit the kernel uses to differentiate v6/v7, so it gets reported as "CPU architecture: 7" and thus fails to run many of the images that get pulled.
+
+To account for this very popular edge case, this also checks "model name" which on these chips will begin with "ARMv6-compatible" -- we could also check uname, but getCPUInfo is already handy, low overhead, and mirrors the code before this.
+
+Signed-off-by: Tianon Gravi <admwiggin@gmail.com>
+
+Origin: backport, https://github.com/containerd/containerd/commit/2055e12953bb538228d8d9fe627fa545d7cf82be
+---
+ platforms/cpuinfo.go | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/platforms/cpuinfo.go b/platforms/cpuinfo.go
+index db65a72..0512bc9 100644
+--- a/platforms/cpuinfo.go
++++ b/platforms/cpuinfo.go
+@@ -96,6 +96,15 @@ func getCPUVariant() string {
+ return ""
+ }
+
++ // handle edge case for Raspberry Pi ARMv6 devices (which due to a kernel quirk, report "CPU architecture: 7")
++ // https://www.raspberrypi.org/forums/viewtopic.php?t=12614
++ if runtime.GOARCH == "arm" && variant == "7" {
++ model, err := getCPUInfo("model name")
++ if err == nil && strings.HasPrefix(strings.ToLower(model), "armv6-compatible") {
++ variant = "6"
++ }
++ }
++
+ switch strings.ToLower(variant) {
+ case "8", "aarch64":
+ // special case: if running a 32-bit userspace on aarch64, the variant should be "v7"
diff -Nru containerd-1.4.5~ds1/debian/patches/0008-CVE-2021-32760.patch containerd-1.4.12~ds1/debian/patches/0008-CVE-2021-32760.patch
--- containerd-1.4.5~ds1/debian/patches/0008-CVE-2021-32760.patch 2021-10-05 18:45:47.000000000 +0800
+++ containerd-1.4.12~ds1/debian/patches/0008-CVE-2021-32760.patch 1970-01-01 08:00:00.000000000 +0800
@@ -1,91 +0,0 @@
-From 03aa748c11663e87a72fab92b7ab7c88c28bf13e Mon Sep 17 00:00:00 2001
-From: Derek McGowan <derek@mcg.dev>
-Date: Tue, 6 Jul 2021 12:37:54 -0700
-Subject: [PATCH 1/2] Use chmod path for checking symlink
-
-Signed-off-by: Derek McGowan <derek@mcg.dev>
-(cherry picked from commit 27597ccfd30d8aa06b448062896bccfb33ad8f22)
-Signed-off-by: Derek McGowan <derek@mcg.dev>
----
- archive/tar_unix.go | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/archive/tar_unix.go b/archive/tar_unix.go
-index 6e89d2fdbc9..c22e79bf2be 100644
---- a/archive/tar_unix.go
-+++ b/archive/tar_unix.go
-@@ -113,7 +113,7 @@ func handleTarTypeBlockCharFifo(hdr *tar.Header, path string) error {
-
- func handleLChmod(hdr *tar.Header, path string, hdrInfo os.FileInfo) error {
- if hdr.Typeflag == tar.TypeLink {
-- if fi, err := os.Lstat(hdr.Linkname); err == nil && (fi.Mode()&os.ModeSymlink == 0) {
-+ if fi, err := os.Lstat(path); err == nil && (fi.Mode()&os.ModeSymlink == 0) {
- if err := os.Chmod(path, hdrInfo.Mode()); err != nil && !os.IsNotExist(err) {
- return err
- }
-
-From 664f93ead6c613a9f0e9932dfa75c602dbe35f41 Mon Sep 17 00:00:00 2001
-From: Derek McGowan <derek@mcg.dev>
-Date: Tue, 6 Jul 2021 16:23:03 -0700
-Subject: [PATCH 2/2] Add test for archive breakout test for lchmod
-
-Signed-off-by: Derek McGowan <derek@mcg.dev>
-(cherry picked from commit ad81d76219a75559cb9d74a214efe0d779d7cbef)
-Signed-off-by: Derek McGowan <derek@mcg.dev>
----
- archive/tar_test.go | 35 +++++++++++++++++++++++++++++++++++
- 1 file changed, 35 insertions(+)
-
-diff --git a/archive/tar_test.go b/archive/tar_test.go
-index 568f5a95f1c..8ffd3f221b8 100644
---- a/archive/tar_test.go
-+++ b/archive/tar_test.go
-@@ -243,6 +243,11 @@ func TestBreakouts(t *testing.T) {
- return nil
- }
- errFileDiff := errors.New("files differ")
-+ td, err := ioutil.TempDir("", "test-breakouts-")
-+ if err != nil {
-+ t.Fatal(err)
-+ }
-+ defer os.RemoveAll(td)
-
- isSymlinkFile := func(f string) func(string) error {
- return func(root string) error {
-@@ -744,6 +749,36 @@ func TestBreakouts(t *testing.T) {
- // resolution ends up just removing etc
- validator: fileNotExists("etc/passwd"),
- },
-+ {
-+
-+ name: "HardlinkSymlinkChmod",
-+ w: func() tartest.WriterToTar {
-+ p := filepath.Join(td, "perm400")
-+ if err := ioutil.WriteFile(p, []byte("..."), 0400); err != nil {
-+ t.Fatal(err)
-+ }
-+ ep := filepath.Join(td, "also-exists-outside-root")
-+ if err := ioutil.WriteFile(ep, []byte("..."), 0640); err != nil {
-+ t.Fatal(err)
-+ }
-+
-+ return tartest.TarAll(
-+ tc.Symlink(p, ep),
-+ tc.Link(ep, "sketchylink"),
-+ )
-+ }(),
-+ validator: func(string) error {
-+ p := filepath.Join(td, "perm400")
-+ fi, err := os.Lstat(p)
-+ if err != nil {
-+ return err
-+ }
-+ if perm := fi.Mode() & os.ModePerm; perm != 0400 {
-+ return errors.Errorf("%s perm changed from 0400 to %04o", p, perm)
-+ }
-+ return nil
-+ },
-+ },
- }
-
- for _, bo := range breakouts {
diff -Nru containerd-1.4.5~ds1/debian/patches/0009-CVE-2021-41103/0009-v2-runtime-reduce-permissions-for-bundle-dir.patch containerd-1.4.12~ds1/debian/patches/0009-CVE-2021-41103/0009-v2-runtime-reduce-permissions-for-bundle-dir.patch
--- containerd-1.4.5~ds1/debian/patches/0009-CVE-2021-41103/0009-v2-runtime-reduce-permissions-for-bundle-dir.patch 2021-10-05 18:45:47.000000000 +0800
+++ containerd-1.4.12~ds1/debian/patches/0009-CVE-2021-41103/0009-v2-runtime-reduce-permissions-for-bundle-dir.patch 1970-01-01 08:00:00.000000000 +0800
@@ -1,349 +0,0 @@
-From: Samuel Karp <skarp@amazon.com>
-Date: Mon, 20 Sep 2021 16:20:26 -0700
-Subject: v2 runtime: reduce permissions for bundle dir
-
-Bundle directory permissions should be 0700 by default. On Linux with
-user namespaces enabled, the remapped root also needs access to the
-bundle directory. In this case, the bundle directory is modified to
-0710 and group ownership is changed to the remapped root group.
-
-Signed-off-by: Samuel Karp <skarp@amazon.com>
----
- runtime/v2/bundle.go | 5 +-
- runtime/v2/bundle_default.go | 24 ++++++
- runtime/v2/bundle_linux.go | 74 ++++++++++++++++++
- runtime/v2/bundle_linux_test.go | 166 ++++++++++++++++++++++++++++++++++++++++
- runtime/v2/bundle_test.go | 23 ++++++
- 5 files changed, 291 insertions(+), 1 deletion(-)
- create mode 100644 runtime/v2/bundle_default.go
- create mode 100644 runtime/v2/bundle_linux.go
- create mode 100644 runtime/v2/bundle_linux_test.go
- create mode 100644 runtime/v2/bundle_test.go
-
-diff --git a/runtime/v2/bundle.go b/runtime/v2/bundle.go
-index 1a58e62..954163b 100644
---- a/runtime/v2/bundle.go
-+++ b/runtime/v2/bundle.go
-@@ -72,7 +72,10 @@ func NewBundle(ctx context.Context, root, state, id string, spec []byte) (b *Bun
- if err := os.MkdirAll(filepath.Dir(b.Path), 0711); err != nil {
- return nil, err
- }
-- if err := os.Mkdir(b.Path, 0711); err != nil {
-+ if err := os.Mkdir(b.Path, 0700); err != nil {
-+ return nil, err
-+ }
-+ if err := prepareBundleDirectoryPermissions(b.Path, spec); err != nil {
- return nil, err
- }
- paths = append(paths, b.Path)
-diff --git a/runtime/v2/bundle_default.go b/runtime/v2/bundle_default.go
-new file mode 100644
-index 0000000..2be40c8
---- /dev/null
-+++ b/runtime/v2/bundle_default.go
-@@ -0,0 +1,24 @@
-+//go:build !linux
-+// +build !linux
-+
-+/*
-+ Copyright The containerd Authors.
-+
-+ Licensed under the Apache License, Version 2.0 (the "License");
-+ you may not use this file except in compliance with the License.
-+ You may obtain a copy of the License at
-+
-+ http://www.apache.org/licenses/LICENSE-2.0
-+
-+ Unless required by applicable law or agreed to in writing, software
-+ distributed under the License is distributed on an "AS IS" BASIS,
-+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ See the License for the specific language governing permissions and
-+ limitations under the License.
-+*/
-+
-+package v2
-+
-+// prepareBundleDirectoryPermissions prepares the permissions of the bundle
-+// directory according to the needs of the current platform.
-+func prepareBundleDirectoryPermissions(path string, spec []byte) error { return nil }
-diff --git a/runtime/v2/bundle_linux.go b/runtime/v2/bundle_linux.go
-new file mode 100644
-index 0000000..5f1915d
---- /dev/null
-+++ b/runtime/v2/bundle_linux.go
-@@ -0,0 +1,74 @@
-+/*
-+ Copyright The containerd Authors.
-+
-+ Licensed under the Apache License, Version 2.0 (the "License");
-+ you may not use this file except in compliance with the License.
-+ You may obtain a copy of the License at
-+
-+ http://www.apache.org/licenses/LICENSE-2.0
-+
-+ Unless required by applicable law or agreed to in writing, software
-+ distributed under the License is distributed on an "AS IS" BASIS,
-+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ See the License for the specific language governing permissions and
-+ limitations under the License.
-+*/
-+
-+package v2
-+
-+import (
-+ "encoding/json"
-+ "os"
-+
-+ "github.com/opencontainers/runtime-spec/specs-go"
-+)
-+
-+// prepareBundleDirectoryPermissions prepares the permissions of the bundle
-+// directory according to the needs of the current platform.
-+// On Linux when user namespaces are enabled, the permissions are modified to
-+// allow the remapped root GID to access the bundle.
-+func prepareBundleDirectoryPermissions(path string, spec []byte) error {
-+ gid, err := remappedGID(spec)
-+ if err != nil {
-+ return err
-+ }
-+ if gid == 0 {
-+ return nil
-+ }
-+ if err := os.Chown(path, -1, int(gid)); err != nil {
-+ return err
-+ }
-+ return os.Chmod(path, 0710)
-+}
-+
-+// ociSpecUserNS is a subset of specs.Spec used to reduce garbage during
-+// unmarshal.
-+type ociSpecUserNS struct {
-+ Linux *linuxSpecUserNS
-+}
-+
-+// linuxSpecUserNS is a subset of specs.Linux used to reduce garbage during
-+// unmarshal.
-+type linuxSpecUserNS struct {
-+ GIDMappings []specs.LinuxIDMapping
-+}
-+
-+// remappedGID reads the remapped GID 0 from the OCI spec, if it exists. If
-+// there is no remapping, remappedGID returns 0. If the spec cannot be parsed,
-+// remappedGID returns an error.
-+func remappedGID(spec []byte) (uint32, error) {
-+ var ociSpec ociSpecUserNS
-+ err := json.Unmarshal(spec, &ociSpec)
-+ if err != nil {
-+ return 0, err
-+ }
-+ if ociSpec.Linux == nil || len(ociSpec.Linux.GIDMappings) == 0 {
-+ return 0, nil
-+ }
-+ for _, mapping := range ociSpec.Linux.GIDMappings {
-+ if mapping.ContainerID == 0 {
-+ return mapping.HostID, nil
-+ }
-+ }
-+ return 0, nil
-+}
-diff --git a/runtime/v2/bundle_linux_test.go b/runtime/v2/bundle_linux_test.go
-new file mode 100644
-index 0000000..617b105
---- /dev/null
-+++ b/runtime/v2/bundle_linux_test.go
-@@ -0,0 +1,166 @@
-+/*
-+ Copyright The containerd Authors.
-+
-+ Licensed under the Apache License, Version 2.0 (the "License");
-+ you may not use this file except in compliance with the License.
-+ You may obtain a copy of the License at
-+
-+ http://www.apache.org/licenses/LICENSE-2.0
-+
-+ Unless required by applicable law or agreed to in writing, software
-+ distributed under the License is distributed on an "AS IS" BASIS,
-+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ See the License for the specific language governing permissions and
-+ limitations under the License.
-+*/
-+
-+package v2
-+
-+import (
-+ "context"
-+ "encoding/json"
-+ "fmt"
-+ "io/ioutil"
-+ "os"
-+ "path/filepath"
-+ "strconv"
-+ "syscall"
-+ "testing"
-+
-+ "github.com/containerd/containerd/namespaces"
-+ "github.com/containerd/containerd/oci"
-+ "github.com/containerd/containerd/pkg/testutil"
-+ "github.com/opencontainers/runtime-spec/specs-go"
-+)
-+
-+func TestNewBundle(t *testing.T) {
-+ testutil.RequiresRoot(t)
-+ tests := []struct {
-+ userns bool
-+ }{{
-+ userns: false,
-+ }, {
-+ userns: true,
-+ }}
-+ const usernsGID = 4200
-+
-+ for i, tc := range tests {
-+ t.Run(strconv.Itoa(i), func(t *testing.T) {
-+ dir, err := ioutil.TempDir("", "test-new-bundle")
-+ if err != nil {
-+ t.Fatal("failed to create test directory", err)
-+ }
-+ defer os.RemoveAll(dir)
-+ work := filepath.Join(dir, "work")
-+ state := filepath.Join(dir, "state")
-+ id := fmt.Sprintf("new-bundle-%d", i)
-+ spec := oci.Spec{}
-+ if tc.userns {
-+ spec.Linux = &specs.Linux{
-+ GIDMappings: []specs.LinuxIDMapping{{ContainerID: 0, HostID: usernsGID}},
-+ }
-+ }
-+ specBytes, err := json.Marshal(&spec)
-+ if err != nil {
-+ t.Fatal("failed to marshal spec", err)
-+ }
-+
-+ ctx := namespaces.WithNamespace(context.TODO(), namespaces.Default)
-+ b, err := NewBundle(ctx, work, state, id, specBytes)
-+ if err != nil {
-+ t.Fatal("NewBundle should succeed", err)
-+ }
-+ if b == nil {
-+ t.Fatal("bundle should not be nil")
-+ }
-+
-+ fi, err := os.Stat(b.Path)
-+ if err != nil {
-+ t.Error("should be able to stat bundle path", err)
-+ }
-+ if tc.userns {
-+ if fi.Mode() != os.ModeDir|0710 {
-+ t.Error("bundle path should be a directory with perm 0710")
-+ }
-+ } else {
-+ if fi.Mode() != os.ModeDir|0700 {
-+ t.Error("bundle path should be a directory with perm 0700")
-+ }
-+ }
-+ stat, ok := fi.Sys().(*syscall.Stat_t)
-+ if !ok {
-+ t.Fatal("should assert to *syscall.Stat_t")
-+ }
-+ expectedGID := uint32(0)
-+ if tc.userns {
-+ expectedGID = usernsGID
-+ }
-+ if expectedGID != stat.Gid {
-+ t.Error("gid should match", expectedGID, stat.Gid)
-+ }
-+ })
-+ }
-+}
-+
-+func TestRemappedGID(t *testing.T) {
-+ tests := []struct {
-+ spec oci.Spec
-+ gid uint32
-+ }{{
-+ // empty spec
-+ spec: oci.Spec{},
-+ gid: 0,
-+ }, {
-+ // empty Linux section
-+ spec: oci.Spec{
-+ Linux: &specs.Linux{},
-+ },
-+ gid: 0,
-+ }, {
-+ // empty ID mappings
-+ spec: oci.Spec{
-+ Linux: &specs.Linux{
-+ GIDMappings: make([]specs.LinuxIDMapping, 0),
-+ },
-+ },
-+ gid: 0,
-+ }, {
-+ // valid ID mapping
-+ spec: oci.Spec{
-+ Linux: &specs.Linux{
-+ GIDMappings: []specs.LinuxIDMapping{{
-+ ContainerID: 0,
-+ HostID: 1000,
-+ }},
-+ },
-+ },
-+ gid: 1000,
-+ }, {
-+ // missing ID mapping
-+ spec: oci.Spec{
-+ Linux: &specs.Linux{
-+ GIDMappings: []specs.LinuxIDMapping{{
-+ ContainerID: 100,
-+ HostID: 1000,
-+ }},
-+ },
-+ },
-+ gid: 0,
-+ }}
-+
-+ for i, tc := range tests {
-+ t.Run(strconv.Itoa(i), func(t *testing.T) {
-+ s, err := json.Marshal(tc.spec)
-+ if err != nil {
-+ t.Fatal("failed to marshal spec", err)
-+ }
-+ gid, err := remappedGID(s)
-+ if err != nil {
-+ t.Error("should unmarshal successfully", err)
-+ }
-+ if tc.gid != gid {
-+ t.Error("expected GID to match", tc.gid, gid)
-+ }
-+ })
-+ }
-+}
-diff --git a/runtime/v2/bundle_test.go b/runtime/v2/bundle_test.go
-new file mode 100644
-index 0000000..54e5f24
---- /dev/null
-+++ b/runtime/v2/bundle_test.go
-@@ -0,0 +1,23 @@
-+/*
-+ Copyright The containerd Authors.
-+
-+ Licensed under the Apache License, Version 2.0 (the "License");
-+ you may not use this file except in compliance with the License.
-+ You may obtain a copy of the License at
-+
-+ http://www.apache.org/licenses/LICENSE-2.0
-+
-+ Unless required by applicable law or agreed to in writing, software
-+ distributed under the License is distributed on an "AS IS" BASIS,
-+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ See the License for the specific language governing permissions and
-+ limitations under the License.
-+*/
-+
-+package v2
-+
-+import (
-+ // When testutil is imported for one platform (bundle_linux_test.go) it
-+ // should be imported for all platforms.
-+ _ "github.com/containerd/containerd/pkg/testutil"
-+)
diff -Nru containerd-1.4.5~ds1/debian/patches/0009-CVE-2021-41103/0010-v1-runtime-reduce-permissions-for-bundle-dir.patch containerd-1.4.12~ds1/debian/patches/0009-CVE-2021-41103/0010-v1-runtime-reduce-permissions-for-bundle-dir.patch
--- containerd-1.4.5~ds1/debian/patches/0009-CVE-2021-41103/0010-v1-runtime-reduce-permissions-for-bundle-dir.patch 2021-10-05 18:45:47.000000000 +0800
+++ containerd-1.4.12~ds1/debian/patches/0009-CVE-2021-41103/0010-v1-runtime-reduce-permissions-for-bundle-dir.patch 1970-01-01 08:00:00.000000000 +0800
@@ -1,285 +0,0 @@
-From: Samuel Karp <skarp@amazon.com>
-Date: Tue, 21 Sep 2021 13:46:40 -0700
-Subject: v1 runtime: reduce permissions for bundle dir
-
-Bundle directory permissions should be 0700 by default. On Linux with
-user namespaces enabled, the remapped root also needs access to the
-bundle directory. In this case, the bundle directory is modified to
-0710 and group ownership is changed to the remapped root group.
-
-Port of the same change for the v2 runtime
-
-Signed-off-by: Samuel Karp <skarp@amazon.com>
----
- runtime/v1/linux/bundle.go | 56 +++++++++++++-
- runtime/v1/linux/bundle_test.go | 166 ++++++++++++++++++++++++++++++++++++++++
- 2 files changed, 221 insertions(+), 1 deletion(-)
- create mode 100644 runtime/v1/linux/bundle_test.go
-
-diff --git a/runtime/v1/linux/bundle.go b/runtime/v1/linux/bundle.go
-index 9d0a6c4..48d81e8 100644
---- a/runtime/v1/linux/bundle.go
-+++ b/runtime/v1/linux/bundle.go
-@@ -21,6 +21,7 @@ package linux
- import (
- "context"
- "crypto/sha256"
-+ "encoding/json"
- "fmt"
- "io/ioutil"
- "os"
-@@ -30,6 +31,7 @@ import (
- "github.com/containerd/containerd/runtime/linux/runctypes"
- "github.com/containerd/containerd/runtime/v1/shim"
- "github.com/containerd/containerd/runtime/v1/shim/client"
-+ "github.com/opencontainers/runtime-spec/specs-go"
- "github.com/pkg/errors"
- )
-
-@@ -48,7 +50,7 @@ func newBundle(id, path, workDir string, spec []byte) (b *bundle, err error) {
- return nil, err
- }
- path = filepath.Join(path, id)
-- if err := os.Mkdir(path, 0711); err != nil {
-+ if err := os.Mkdir(path, 0700); err != nil {
- return nil, err
- }
- defer func() {
-@@ -56,6 +58,9 @@ func newBundle(id, path, workDir string, spec []byte) (b *bundle, err error) {
- os.RemoveAll(path)
- }
- }()
-+ if err := prepareBundleDirectoryPermissions(path, spec); err != nil {
-+ return nil, err
-+ }
- workDir = filepath.Join(workDir, id)
- if err := os.MkdirAll(workDir, 0711); err != nil {
- return nil, err
-@@ -77,6 +82,55 @@ func newBundle(id, path, workDir string, spec []byte) (b *bundle, err error) {
- }, err
- }
-
-+// prepareBundleDirectoryPermissions prepares the permissions of the bundle
-+// directory. When user namespaces are enabled, the permissions are modified
-+// to allow the remapped root GID to access the bundle.
-+func prepareBundleDirectoryPermissions(path string, spec []byte) error {
-+ gid, err := remappedGID(spec)
-+ if err != nil {
-+ return err
-+ }
-+ if gid == 0 {
-+ return nil
-+ }
-+ if err := os.Chown(path, -1, int(gid)); err != nil {
-+ return err
-+ }
-+ return os.Chmod(path, 0710)
-+}
-+
-+// ociSpecUserNS is a subset of specs.Spec used to reduce garbage during
-+// unmarshal.
-+type ociSpecUserNS struct {
-+ Linux *linuxSpecUserNS
-+}
-+
-+// linuxSpecUserNS is a subset of specs.Linux used to reduce garbage during
-+// unmarshal.
-+type linuxSpecUserNS struct {
-+ GIDMappings []specs.LinuxIDMapping
-+}
-+
-+// remappedGID reads the remapped GID 0 from the OCI spec, if it exists. If
-+// there is no remapping, remappedGID returns 0. If the spec cannot be parsed,
-+// remappedGID returns an error.
-+func remappedGID(spec []byte) (uint32, error) {
-+ var ociSpec ociSpecUserNS
-+ err := json.Unmarshal(spec, &ociSpec)
-+ if err != nil {
-+ return 0, err
-+ }
-+ if ociSpec.Linux == nil || len(ociSpec.Linux.GIDMappings) == 0 {
-+ return 0, nil
-+ }
-+ for _, mapping := range ociSpec.Linux.GIDMappings {
-+ if mapping.ContainerID == 0 {
-+ return mapping.HostID, nil
-+ }
-+ }
-+ return 0, nil
-+}
-+
- type bundle struct {
- id string
- path string
-diff --git a/runtime/v1/linux/bundle_test.go b/runtime/v1/linux/bundle_test.go
-new file mode 100644
-index 0000000..adf39b4
---- /dev/null
-+++ b/runtime/v1/linux/bundle_test.go
-@@ -0,0 +1,166 @@
-+//go:build linux
-+// +build linux
-+
-+/*
-+ Copyright The containerd Authors.
-+
-+ Licensed under the Apache License, Version 2.0 (the "License");
-+ you may not use this file except in compliance with the License.
-+ You may obtain a copy of the License at
-+
-+ http://www.apache.org/licenses/LICENSE-2.0
-+
-+ Unless required by applicable law or agreed to in writing, software
-+ distributed under the License is distributed on an "AS IS" BASIS,
-+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ See the License for the specific language governing permissions and
-+ limitations under the License.
-+*/
-+
-+package linux
-+
-+import (
-+ "encoding/json"
-+ "fmt"
-+ "io/ioutil"
-+ "os"
-+ "path/filepath"
-+ "strconv"
-+ "syscall"
-+ "testing"
-+
-+ "github.com/containerd/containerd/oci"
-+ "github.com/containerd/continuity/testutil"
-+ "github.com/opencontainers/runtime-spec/specs-go"
-+)
-+
-+func TestNewBundle(t *testing.T) {
-+ testutil.RequiresRoot(t)
-+ tests := []struct {
-+ userns bool
-+ }{{
-+ userns: false,
-+ }, {
-+ userns: true,
-+ }}
-+ const usernsGID = 4200
-+
-+ for i, tc := range tests {
-+ t.Run(strconv.Itoa(i), func(t *testing.T) {
-+ dir, err := ioutil.TempDir("", "test-new-bundle")
-+ if err != nil {
-+ t.Fatal("failed to create test directory", err)
-+ }
-+ defer os.RemoveAll(dir)
-+ work := filepath.Join(dir, "work")
-+ state := filepath.Join(dir, "state")
-+ id := fmt.Sprintf("new-bundle-%d", i)
-+ spec := oci.Spec{}
-+ if tc.userns {
-+ spec.Linux = &specs.Linux{
-+ GIDMappings: []specs.LinuxIDMapping{{ContainerID: 0, HostID: usernsGID}},
-+ }
-+ }
-+ specBytes, err := json.Marshal(&spec)
-+ if err != nil {
-+ t.Fatal("failed to marshal spec", err)
-+ }
-+
-+ b, err := newBundle(id, work, state, specBytes)
-+ if err != nil {
-+ t.Fatal("newBundle should succeed", err)
-+ }
-+ if b == nil {
-+ t.Fatal("bundle should not be nil")
-+ }
-+
-+ fi, err := os.Stat(b.path)
-+ if err != nil {
-+ t.Error("should be able to stat bundle path", err)
-+ }
-+ if tc.userns {
-+ if fi.Mode() != os.ModeDir|0710 {
-+ t.Error("bundle path should be a directory with perm 0710")
-+ }
-+ } else {
-+ if fi.Mode() != os.ModeDir|0700 {
-+ t.Error("bundle path should be a directory with perm 0700")
-+ }
-+ }
-+ stat, ok := fi.Sys().(*syscall.Stat_t)
-+ if !ok {
-+ t.Fatal("should assert to *syscall.Stat_t")
-+ }
-+ expectedGID := uint32(0)
-+ if tc.userns {
-+ expectedGID = usernsGID
-+ }
-+ if stat.Gid != expectedGID {
-+ t.Error("gid should match", expectedGID, stat.Gid)
-+ }
-+ })
-+ }
-+}
-+
-+func TestRemappedGID(t *testing.T) {
-+ tests := []struct {
-+ spec oci.Spec
-+ gid uint32
-+ }{{
-+ // empty spec
-+ spec: oci.Spec{},
-+ gid: 0,
-+ }, {
-+ // empty Linux section
-+ spec: oci.Spec{
-+ Linux: &specs.Linux{},
-+ },
-+ gid: 0,
-+ }, {
-+ // empty ID mappings
-+ spec: oci.Spec{
-+ Linux: &specs.Linux{
-+ GIDMappings: make([]specs.LinuxIDMapping, 0),
-+ },
-+ },
-+ gid: 0,
-+ }, {
-+ // valid ID mapping
-+ spec: oci.Spec{
-+ Linux: &specs.Linux{
-+ GIDMappings: []specs.LinuxIDMapping{{
-+ ContainerID: 0,
-+ HostID: 1000,
-+ }},
-+ },
-+ },
-+ gid: 1000,
-+ }, {
-+ // missing ID mapping
-+ spec: oci.Spec{
-+ Linux: &specs.Linux{
-+ GIDMappings: []specs.LinuxIDMapping{{
-+ ContainerID: 100,
-+ HostID: 1000,
-+ }},
-+ },
-+ },
-+ gid: 0,
-+ }}
-+
-+ for i, tc := range tests {
-+ t.Run(strconv.Itoa(i), func(t *testing.T) {
-+ s, err := json.Marshal(tc.spec)
-+ if err != nil {
-+ t.Fatal("failed to marshal spec", err)
-+ }
-+ gid, err := remappedGID(s)
-+ if err != nil {
-+ t.Error("should unmarshal successfully", err)
-+ }
-+ if gid != tc.gid {
-+ t.Error("expected GID to match", tc.gid, gid)
-+ }
-+ })
-+ }
-+}
diff -Nru containerd-1.4.5~ds1/debian/patches/0009-CVE-2021-41103/0011-btrfs-reduce-permissions-on-plugin-directories.patch containerd-1.4.12~ds1/debian/patches/0009-CVE-2021-41103/0011-btrfs-reduce-permissions-on-plugin-directories.patch
--- containerd-1.4.5~ds1/debian/patches/0009-CVE-2021-41103/0011-btrfs-reduce-permissions-on-plugin-directories.patch 2021-10-05 18:45:47.000000000 +0800
+++ containerd-1.4.12~ds1/debian/patches/0009-CVE-2021-41103/0011-btrfs-reduce-permissions-on-plugin-directories.patch 1970-01-01 08:00:00.000000000 +0800
@@ -1,36 +0,0 @@
-From: Derek McGowan <derek@mcg.dev>
-Date: Wed, 15 Sep 2021 17:57:13 -0700
-Subject: btrfs: reduce permissions on plugin directories
-
-Disallow traversal into directories that may contain
-unpacked or mounted image filesystems.
-
-Signed-off-by: Derek McGowan <derek@mcg.dev>
-Signed-off-by: Samuel Karp <skarp@amazon.com>
-(cherry picked from commit 7c621e1fcc08bcf5a1a48b837342cc22eada1685)
----
- snapshots/btrfs/btrfs.go | 8 ++++++--
- 1 file changed, 6 insertions(+), 2 deletions(-)
-
-diff --git a/snapshots/btrfs/btrfs.go b/snapshots/btrfs/btrfs.go
-index eef883b..778b783 100644
---- a/snapshots/btrfs/btrfs.go
-+++ b/snapshots/btrfs/btrfs.go
-@@ -63,11 +63,15 @@ type snapshotter struct {
- // root needs to be a mount point of btrfs.
- func NewSnapshotter(root string) (snapshots.Snapshotter, error) {
- // If directory does not exist, create it
-- if _, err := os.Stat(root); err != nil {
-+ if st, err := os.Stat(root); err != nil {
- if !os.IsNotExist(err) {
- return nil, err
- }
-- if err := os.Mkdir(root, 0755); err != nil {
-+ if err := os.Mkdir(root, 0700); err != nil {
-+ return nil, err
-+ }
-+ } else if st.Mode()&os.ModePerm != 0700 {
-+ if err := os.Chmod(root, 0700); err != nil {
- return nil, err
- }
- }
diff -Nru containerd-1.4.5~ds1/debian/patches/series containerd-1.4.12~ds1/debian/patches/series
--- containerd-1.4.5~ds1/debian/patches/series 2021-10-05 18:45:47.000000000 +0800
+++ containerd-1.4.12~ds1/debian/patches/series 2021-11-23 18:42:16.000000000 +0800
@@ -5,7 +5,4 @@
0005-backport-github.com-containerd-containerd-remotes.patch
0006-backport-apparmor-handle-signal-mediation.patch
0007-backport-runtime-ignore-file-already-closed-error.patch
-0008-CVE-2021-32760.patch
-0009-CVE-2021-41103/0009-v2-runtime-reduce-permissions-for-bundle-dir.patch
-0009-CVE-2021-41103/0010-v1-runtime-reduce-permissions-for-bundle-dir.patch
-0009-CVE-2021-41103/0011-btrfs-reduce-permissions-on-plugin-directories.patch
+0008-Add-RPi1-RPi0-workaround.patch
diff -Nru containerd-1.4.5~ds1/.github/workflows/ci.yml containerd-1.4.12~ds1/.github/workflows/ci.yml
--- containerd-1.4.5~ds1/.github/workflows/ci.yml 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/.github/workflows/ci.yml 2021-11-18 03:52:12.000000000 +0800
@@ -26,7 +26,7 @@
- name: Install Go
uses: actions/setup-go@v2
with:
- go-version: '1.15.11'
+ go-version: '1.16.10'
- name: Set env
shell: bash
@@ -47,6 +47,8 @@
working-directory: src/github.com/containerd/containerd
- name: Make check
+ env:
+ GO111MODULE: off
shell: bash
run: make check
working-directory: src/github.com/containerd/containerd
@@ -80,7 +82,7 @@
steps:
- uses: actions/setup-go@v2
with:
- go-version: '1.15.11'
+ go-version: '1.16.10'
- name: Set env
shell: bash
@@ -126,7 +128,7 @@
steps:
- uses: actions/setup-go@v2
with:
- go-version: '1.15.11'
+ go-version: '1.16.10'
- name: Set env
shell: bash
@@ -143,6 +145,8 @@
run: GO111MODULE=on go get github.com/cpuguy83/go-md2man/v2@v2.0.0
- name: Make
+ env:
+ GO111MODULE: off
run: make man
working-directory: src/github.com/containerd/containerd
@@ -162,7 +166,7 @@
steps:
- uses: actions/setup-go@v2
with:
- go-version: '1.15.11'
+ go-version: '1.16.10'
- name: Set env
shell: bash
@@ -176,6 +180,8 @@
path: src/github.com/containerd/containerd
- name: Make
+ env:
+ GO111MODULE: off
run: |
make build
make binaries
@@ -193,7 +199,7 @@
steps:
- uses: actions/setup-go@v2
with:
- go-version: '1.15.11'
+ go-version: '1.16.10'
- name: Set env
shell: bash
@@ -217,6 +223,8 @@
cd src/github.com/containerd/containerd
script/setup/install-dev-tools
- name: Binaries
+ env:
+ GO111MODULE: off
shell: bash
run: |
set -o xtrace
@@ -234,11 +242,14 @@
shell: bash
env:
CGO_ENABLED: 1
+ GO111MODULE: off
run: |
cd src/github.com/containerd/containerd
mingw32-make.exe test root-test
- name: Integration 1
+ env:
+ GO111MODULE: off
shell: bash
run: |
cd src/github.com/containerd/containerd
@@ -246,6 +257,8 @@
mingw32-make.exe integration
# Run the integration suite a second time. See discussion in github.com/containerd/containerd/pull/175
- name: Integration 2
+ env:
+ GO111MODULE: off
shell: bash
run: |
cd src/github.com/containerd/containerd
@@ -272,7 +285,7 @@
steps:
- uses: actions/setup-go@v2
with:
- go-version: '1.15.11'
+ go-version: '1.16.10'
- name: Set env
shell: bash
@@ -315,6 +328,7 @@
- name: Install containerd
env:
CGO_ENABLED: 1
+ GO111MODULE: off
run: |
make binaries
sudo -E PATH=$PATH make install
@@ -324,6 +338,7 @@
env:
GOPROXY: direct
SKIPTESTS: github.com/containerd/containerd/snapshots/devmapper
+ GO111MODULE: off
run: |
make test
sudo -E PATH=$PATH make root-test
@@ -334,6 +349,7 @@
GOPROXY: direct
TEST_RUNTIME: ${{ matrix.runtime }}
RUNC_FLAVOR: ${{ matrix.runc }}
+ GO111MODULE: off
run: |
sudo -E PATH=$PATH make integration EXTRA_TESTFLAGS=-no-criu TESTFLAGS_RACE=-race
working-directory: src/github.com/containerd/containerd
@@ -344,6 +360,7 @@
GOPROXY: direct
TEST_RUNTIME: ${{ matrix.runtime }}
RUNC_FLAVOR: ${{ matrix.runc }}
+ GO111MODULE: off
run: |
sudo -E PATH=$PATH TESTFLAGS_PARALLEL=1 make integration EXTRA_TESTFLAGS=-no-criu
working-directory: src/github.com/containerd/containerd
diff -Nru containerd-1.4.5~ds1/.github/workflows/nightly.yml containerd-1.4.12~ds1/.github/workflows/nightly.yml
--- containerd-1.4.5~ds1/.github/workflows/nightly.yml 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/.github/workflows/nightly.yml 2021-11-18 03:52:12.000000000 +0800
@@ -14,7 +14,7 @@
steps:
- uses: actions/setup-go@v2
with:
- go-version: '1.15.11'
+ go-version: '1.16.10'
- name: Checkout
uses: actions/checkout@v1
@@ -63,6 +63,7 @@
GOPATH: ${{ runner.workspace }}
GOOS: linux
GOARCH: amd64
+ GO111MODULE: off
run: |
make binaries
mv bin bin_amd64
@@ -74,6 +75,7 @@
GOARCH: arm64
CC: aarch64-linux-gnu-gcc
CGO_ENABLED: 1
+ GO111MODULE: off
run: |
make binaries
mv bin bin_arm64
@@ -85,6 +87,7 @@
GOARCH: s390x
CGO_ENABLED: 1
CC: s390x-linux-gnu-gcc
+ GO111MODULE: off
run: |
make binaries
mv bin bin_s390x
@@ -96,6 +99,7 @@
GOARCH: ppc64le
CGO_ENABLED: 1
CC: powerpc64le-linux-gnu-gcc
+ GO111MODULE: off
run: |
make binaries
mv bin bin_ppc64le
@@ -134,7 +138,7 @@
steps:
- uses: actions/setup-go@v2
with:
- go-version: '1.15.11'
+ go-version: '1.16.10'
- name: Checkout
uses: actions/checkout@v1
@@ -155,6 +159,7 @@
GOPATH: ${{ runner.workspace }}
GOOS: windows
GOARCH: amd64
+ GO111MODULE: off
run: |
make binaries
diff -Nru containerd-1.4.5~ds1/.github/workflows/release.yml containerd-1.4.12~ds1/.github/workflows/release.yml
--- containerd-1.4.5~ds1/.github/workflows/release.yml 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/.github/workflows/release.yml 2021-11-18 03:52:12.000000000 +0800
@@ -62,7 +62,7 @@
- name: Install Go
uses: actions/setup-go@v2
with:
- go-version: '1.15.11'
+ go-version: '1.16.10'
- name: Set env
shell: bash
@@ -103,6 +103,8 @@
path: src/github.com/Microsoft/hcsshim
- name: Make
+ env:
+ GO111MODULE: off
shell: bash
run: |
make build
diff -Nru containerd-1.4.5~ds1/images/image.go containerd-1.4.12~ds1/images/image.go
--- containerd-1.4.5~ds1/images/image.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/images/image.go 2021-11-18 03:52:12.000000000 +0800
@@ -19,6 +19,7 @@
import (
"context"
"encoding/json"
+ "fmt"
"sort"
"time"
@@ -154,6 +155,10 @@
return nil, err
}
+ if err := validateMediaType(p, desc.MediaType); err != nil {
+ return nil, errors.Wrapf(err, "manifest: invalid desc %s", desc.Digest)
+ }
+
var manifest ocispec.Manifest
if err := json.Unmarshal(p, &manifest); err != nil {
return nil, err
@@ -194,6 +199,10 @@
return nil, err
}
+ if err := validateMediaType(p, desc.MediaType); err != nil {
+ return nil, errors.Wrapf(err, "manifest: invalid desc %s", desc.Digest)
+ }
+
var idx ocispec.Index
if err := json.Unmarshal(p, &idx); err != nil {
return nil, err
@@ -336,6 +345,10 @@
return nil, err
}
+ if err := validateMediaType(p, desc.MediaType); err != nil {
+ return nil, errors.Wrapf(err, "children: invalid desc %s", desc.Digest)
+ }
+
// TODO(stevvooe): We just assume oci manifest, for now. There may be
// subtle differences from the docker version.
var manifest ocispec.Manifest
@@ -351,6 +364,10 @@
return nil, err
}
+ if err := validateMediaType(p, desc.MediaType); err != nil {
+ return nil, errors.Wrapf(err, "children: invalid desc %s", desc.Digest)
+ }
+
var index ocispec.Index
if err := json.Unmarshal(p, &index); err != nil {
return nil, err
@@ -368,6 +385,44 @@
return descs, nil
}
+// unknownDocument represents a manifest, manifest list, or index that has not
+// yet been validated.
+type unknownDocument struct {
+ MediaType string `json:"mediaType,omitempty"`
+ Config json.RawMessage `json:"config,omitempty"`
+ Layers json.RawMessage `json:"layers,omitempty"`
+ Manifests json.RawMessage `json:"manifests,omitempty"`
+ FSLayers json.RawMessage `json:"fsLayers,omitempty"` // schema 1
+}
+
+// validateMediaType returns an error if the byte slice is invalid JSON or if
+// the media type identifies the blob as one format but it contains elements of
+// another format.
+func validateMediaType(b []byte, mt string) error {
+ var doc unknownDocument
+ if err := json.Unmarshal(b, &doc); err != nil {
+ return err
+ }
+ if len(doc.FSLayers) != 0 {
+ return fmt.Errorf("media-type: schema 1 not supported")
+ }
+ switch mt {
+ case MediaTypeDockerSchema2Manifest, ocispec.MediaTypeImageManifest:
+ if len(doc.Manifests) != 0 ||
+ doc.MediaType == MediaTypeDockerSchema2ManifestList ||
+ doc.MediaType == ocispec.MediaTypeImageIndex {
+ return fmt.Errorf("media-type: expected manifest but found index (%s)", mt)
+ }
+ case MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex:
+ if len(doc.Config) != 0 || len(doc.Layers) != 0 ||
+ doc.MediaType == MediaTypeDockerSchema2Manifest ||
+ doc.MediaType == ocispec.MediaTypeImageManifest {
+ return fmt.Errorf("media-type: expected index but found manifest (%s)", mt)
+ }
+ }
+ return nil
+}
+
// RootFS returns the unpacked diffids that make up and images rootfs.
//
// These are used to verify that a set of layers unpacked to the expected
diff -Nru containerd-1.4.5~ds1/images/image_test.go containerd-1.4.12~ds1/images/image_test.go
--- containerd-1.4.5~ds1/images/image_test.go 1970-01-01 08:00:00.000000000 +0800
+++ containerd-1.4.12~ds1/images/image_test.go 2021-11-18 03:52:12.000000000 +0800
@@ -0,0 +1,150 @@
+/*
+ Copyright The containerd Authors.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package images
+
+import (
+ "encoding/json"
+ "testing"
+
+ ocispec "github.com/opencontainers/image-spec/specs-go/v1"
+)
+
+func TestValidateMediaType(t *testing.T) {
+ docTests := []struct {
+ mt string
+ index bool
+ }{
+ {MediaTypeDockerSchema2Manifest, false},
+ {ocispec.MediaTypeImageManifest, false},
+ {MediaTypeDockerSchema2ManifestList, true},
+ {ocispec.MediaTypeImageIndex, true},
+ }
+ for _, tc := range docTests {
+ t.Run("manifest-"+tc.mt, func(t *testing.T) {
+ manifest := ocispec.Manifest{
+ Config: ocispec.Descriptor{Size: 1},
+ Layers: []ocispec.Descriptor{{Size: 2}},
+ }
+ b, err := json.Marshal(manifest)
+ if err != nil {
+ t.Fatal("failed to marshal manifest", err)
+ }
+
+ err = validateMediaType(b, tc.mt)
+ if tc.index {
+ if err == nil {
+ t.Error("manifest should not be a valid index")
+ }
+ } else {
+ if err != nil {
+ t.Error("manifest should be valid")
+ }
+ }
+ })
+ t.Run("index-"+tc.mt, func(t *testing.T) {
+ index := ocispec.Index{
+ Manifests: []ocispec.Descriptor{{Size: 1}},
+ }
+ b, err := json.Marshal(index)
+ if err != nil {
+ t.Fatal("failed to marshal index", err)
+ }
+
+ err = validateMediaType(b, tc.mt)
+ if tc.index {
+ if err != nil {
+ t.Error("index should be valid")
+ }
+ } else {
+ if err == nil {
+ t.Error("index should not be a valid manifest")
+ }
+ }
+ })
+ }
+
+ mtTests := []struct {
+ mt string
+ valid []string
+ invalid []string
+ }{{
+ MediaTypeDockerSchema2Manifest,
+ []string{MediaTypeDockerSchema2Manifest, ocispec.MediaTypeImageManifest},
+ []string{MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex},
+ }, {
+ ocispec.MediaTypeImageManifest,
+ []string{MediaTypeDockerSchema2Manifest, ocispec.MediaTypeImageManifest},
+ []string{MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex},
+ }, {
+ MediaTypeDockerSchema2ManifestList,
+ []string{MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex},
+ []string{MediaTypeDockerSchema2Manifest, ocispec.MediaTypeImageManifest},
+ }, {
+ ocispec.MediaTypeImageIndex,
+ []string{MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex},
+ []string{MediaTypeDockerSchema2Manifest, ocispec.MediaTypeImageManifest},
+ }}
+ for _, tc := range mtTests {
+ for _, v := range tc.valid {
+ t.Run("valid-"+tc.mt+"-"+v, func(t *testing.T) {
+ doc := struct {
+ MediaType string `json:"mediaType"`
+ }{MediaType: v}
+ b, err := json.Marshal(doc)
+ if err != nil {
+ t.Fatal("failed to marshal document", err)
+ }
+
+ err = validateMediaType(b, tc.mt)
+ if err != nil {
+ t.Error("document should be valid", err)
+ }
+ })
+ }
+ for _, iv := range tc.invalid {
+ t.Run("invalid-"+tc.mt+"-"+iv, func(t *testing.T) {
+ doc := struct {
+ MediaType string `json:"mediaType"`
+ }{MediaType: iv}
+ b, err := json.Marshal(doc)
+ if err != nil {
+ t.Fatal("failed to marshal document", err)
+ }
+
+ err = validateMediaType(b, tc.mt)
+ if err == nil {
+ t.Error("document should not be valid")
+ }
+ })
+ }
+ }
+ t.Run("schema1", func(t *testing.T) {
+ doc := struct {
+ FSLayers []string `json:"fsLayers"`
+ }{FSLayers: []string{"1"}}
+ b, err := json.Marshal(doc)
+ if err != nil {
+ t.Fatal("failed to marshal document", err)
+ }
+
+ err = validateMediaType(b, "")
+ if err == nil {
+ t.Error("document should not be valid")
+ }
+
+ })
+}
diff -Nru containerd-1.4.5~ds1/image_test.go containerd-1.4.12~ds1/image_test.go
--- containerd-1.4.5~ds1/image_test.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/image_test.go 2021-11-18 03:52:12.000000000 +0800
@@ -34,7 +34,7 @@
t.Skip()
}
- const imageName = "docker.io/library/busybox:latest"
+ const imageName = "ghcr.io/containerd/busybox:latest"
ctx, cancel := testContext(t)
defer cancel()
@@ -140,7 +140,7 @@
t.Skip()
}
- imageName := "docker.io/library/busybox:latest"
+ imageName := "ghcr.io/containerd/busybox:latest"
ctx, cancel := testContext(t)
defer cancel()
diff -Nru containerd-1.4.5~ds1/lease_test.go containerd-1.4.12~ds1/lease_test.go
--- containerd-1.4.5~ds1/lease_test.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/lease_test.go 2021-11-18 03:52:12.000000000 +0800
@@ -54,7 +54,7 @@
defer ls.Delete(ctx, l, leases.SynchronousDelete)
// step 1: download image
- imageName := "docker.io/library/busybox:1.25"
+ imageName := "ghcr.io/containerd/busybox:1.28"
image, err := client.Pull(ctx, imageName, WithPullUnpack, WithPullSnapshotter("native"))
if err != nil {
diff -Nru containerd-1.4.5~ds1/.mailmap containerd-1.4.12~ds1/.mailmap
--- containerd-1.4.5~ds1/.mailmap 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/.mailmap 2021-11-18 03:52:12.000000000 +0800
@@ -17,6 +17,7 @@
Cao Zhihao <caozhihao@163.com>
Cao Zhihao <caozhihao@163.com> <caozhihao.xd@bytedance.com>
Carlos Eduardo <me@carlosedp.com> <me@carlosedp.com>
+Cory Bennett <cbennett@netflix.com>
Cristian Staretu <cristian.staretu@gmail.com>
Cristian Staretu <cristian.staretu@gmail.com> <unclejack@users.noreply.github.com>
Daniel Dao <dqminh89@gmail.com>
@@ -73,6 +74,7 @@
Nishchay Kumar <mrawesomenix@gmail.com>
Oliver Stenbom <oliver@stenbom.eu> <ostenbom@pivotal.io>
Phil Estes <estesp@gmail.com> <estesp@linux.vnet.ibm.com>
+Phil Estes <estesp@gmail.com> <estesp@amazon.com>
Reid Li <reid.li@utexas.edu>
Ross Boucher <rboucher@gmail.com>
Ruediger Maass <ruediger.maass@de.ibm.com>
@@ -90,6 +92,7 @@
Su Fei <fesu@ebay.com> <fesu@ebay.com>
Ted Yu <yuzhihong@gmail.com>
Tõnis Tiigi <tonistiigi@gmail.com>
+Wei Fu <fuweid89@gmail.com>
Wei Fu <fuweid89@gmail.com> <fhfuwei@163.com>
Xiaodong Zhang <a4012017@sina.com>
Xuean Yan <yan.xuean@zte.com.cn>
diff -Nru containerd-1.4.5~ds1/metadata/containers.go containerd-1.4.12~ds1/metadata/containers.go
--- containerd-1.4.5~ds1/metadata/containers.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/metadata/containers.go 2021-11-18 03:52:12.000000000 +0800
@@ -290,7 +290,7 @@
// image has no validation
for k, v := range container.Labels {
- if err := labels.Validate(k, v); err == nil {
+ if err := labels.Validate(k, v); err != nil {
return errors.Wrapf(err, "containers.Labels")
}
}
diff -Nru containerd-1.4.5~ds1/metadata/content.go containerd-1.4.12~ds1/metadata/content.go
--- containerd-1.4.5~ds1/metadata/content.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/metadata/content.go 2021-11-18 03:52:12.000000000 +0800
@@ -551,13 +551,13 @@
if desc.Size > 0 {
ra, err := nw.provider.ReaderAt(ctx, nw.desc)
if err != nil {
+ w.Close()
return err
}
defer ra.Close()
if err := content.CopyReaderAt(w, ra, desc.Size); err != nil {
- nw.w.Close()
- nw.w = nil
+ w.Close()
return err
}
}
@@ -708,7 +708,7 @@
func validateInfo(info *content.Info) error {
for k, v := range info.Labels {
- if err := labels.Validate(k, v); err == nil {
+ if err := labels.Validate(k, v); err != nil {
return errors.Wrapf(err, "info.Labels")
}
}
diff -Nru containerd-1.4.5~ds1/releases/v1.4.10.toml containerd-1.4.12~ds1/releases/v1.4.10.toml
--- containerd-1.4.5~ds1/releases/v1.4.10.toml 1970-01-01 08:00:00.000000000 +0800
+++ containerd-1.4.12~ds1/releases/v1.4.10.toml 2021-11-18 03:52:12.000000000 +0800
@@ -0,0 +1,24 @@
+# commit to be tagged for new release
+commit = "HEAD"
+
+project_name = "containerd"
+github_repo = "containerd/containerd"
+match_deps = "^github.com/(containerd/[a-zA-Z0-9-]+)$"
+
+# previous release
+previous = "v1.4.9"
+
+pre_release = false
+
+preface = """\
+The tenth patch release for containerd 1.4 contains minor fixes and updates
+including an updated runc and hcsshim.
+
+### Notable Updates
+
+* **Update runc to v1.0.2** [#5899](https://github.com/containerd/containerd/pull/5899)
+* **Update hcsshim to v0.8.21** [#5957](https://github.com/containerd/containerd/pull/5957)
+* **Support "clone3" in default seccomp profile** [#5982](https://github.com/containerd/containerd/pull/5982)
+* **Fix panic in metadata content writer on copy error** [#6043](https://github.com/containerd/containerd/pull/6043)
+
+See the changelog for complete list of changes"""
diff -Nru containerd-1.4.5~ds1/releases/v1.4.11.toml containerd-1.4.12~ds1/releases/v1.4.11.toml
--- containerd-1.4.5~ds1/releases/v1.4.11.toml 1970-01-01 08:00:00.000000000 +0800
+++ containerd-1.4.12~ds1/releases/v1.4.11.toml 2021-11-18 03:52:12.000000000 +0800
@@ -0,0 +1,20 @@
+# commit to be tagged for new release
+commit = "HEAD"
+
+project_name = "containerd"
+github_repo = "containerd/containerd"
+match_deps = "^github.com/(containerd/[a-zA-Z0-9-]+)$"
+
+# previous release
+previous = "v1.4.10"
+
+pre_release = false
+
+preface = """\
+The eleventh patch release for containerd 1.4 is a security release to fix CVE-2021-41103.
+
+### Notable Updates
+
+* **Fix insufficiently restricted permissions on container root and plugin directories** [GHSA-c2h3-6mxw-7mvq](https://github.com/containerd/containerd/security/advisories/GHSA-c2h3-6mxw-7mvq)
+
+See the changelog for complete list of changes"""
diff -Nru containerd-1.4.5~ds1/releases/v1.4.12.toml containerd-1.4.12~ds1/releases/v1.4.12.toml
--- containerd-1.4.5~ds1/releases/v1.4.12.toml 1970-01-01 08:00:00.000000000 +0800
+++ containerd-1.4.12~ds1/releases/v1.4.12.toml 2021-11-18 03:52:12.000000000 +0800
@@ -0,0 +1,23 @@
+# commit to be tagged for new release
+commit = "HEAD"
+
+project_name = "containerd"
+github_repo = "containerd/containerd"
+match_deps = "^github.com/(containerd/[a-zA-Z0-9-]+)$"
+
+# previous release
+previous = "v1.4.11"
+
+pre_release = false
+
+preface = """\
+The twelfth patch release for containerd 1.4 contains a few minor bug fixes
+and an update to mitigate [CVE-2021-41190](https://github.com/opencontainers/distribution-spec/security/advisories/GHSA-mc8v-mgrf-8f4m).
+
+### Notable Updates
+
+* **Handle ambiguous OCI manifest parsing** ([GHSA-5j5w-g665-5m35](https://github.com/containerd/containerd/security/advisories/GHSA-5j5w-g665-5m35))
+* **Update pull to try next mirror for non-404 errors** ([#5275](https://github.com/containerd/containerd/pull/5275))
+* **Update pull to handle of non-https urls in descriptors** ([#6221](https://github.com/containerd/containerd/pull/6221))
+
+See the changelog for complete list of changes"""
diff -Nru containerd-1.4.5~ds1/releases/v1.4.6.toml containerd-1.4.12~ds1/releases/v1.4.6.toml
--- containerd-1.4.5~ds1/releases/v1.4.6.toml 1970-01-01 08:00:00.000000000 +0800
+++ containerd-1.4.12~ds1/releases/v1.4.6.toml 2021-11-18 03:52:12.000000000 +0800
@@ -0,0 +1,15 @@
+# commit to be tagged for new release
+commit = "HEAD"
+
+project_name = "containerd"
+github_repo = "containerd/containerd"
+match_deps = "^github.com/(containerd/[a-zA-Z0-9-]+)$"
+
+# previous release
+previous = "v1.4.5"
+
+pre_release = false
+
+preface = """\
+The sixth patch release for containerd 1.4 is a security release to update
+runc for [CVE-2021-30465](https://github.com/opencontainers/runc/security/advisories/GHSA-c3xm-pvg7-gh7r)"""
diff -Nru containerd-1.4.5~ds1/releases/v1.4.7.toml containerd-1.4.12~ds1/releases/v1.4.7.toml
--- containerd-1.4.5~ds1/releases/v1.4.7.toml 1970-01-01 08:00:00.000000000 +0800
+++ containerd-1.4.12~ds1/releases/v1.4.7.toml 2021-11-18 03:52:12.000000000 +0800
@@ -0,0 +1,23 @@
+# commit to be tagged for new release
+commit = "HEAD"
+
+project_name = "containerd"
+github_repo = "containerd/containerd"
+match_deps = "^github.com/(containerd/[a-zA-Z0-9-]+)$"
+
+# previous release
+previous = "v1.4.6"
+
+pre_release = false
+
+preface = """\
+The seventh patch release for containerd 1.4 updates runc to 1.0.0 and contains
+various other fixes.
+
+### Notable Updates
+* **Update runc binary to 1.0.0** [5552](https://github.com/containerd/containerd/pull/5552)
+* **Fix invalid validation error checking** [#5565](https://github.com/containerd/containerd/pull/5565)
+* **Fix error on image pull resume** [#5560](https://github.com/containerd/containerd/pull/5560)
+* **Fix symlink resolution for disk mounts on Windows** [#5411](https://github.com/containerd/containerd/pull/5411)
+
+See the changelog for complete list of changes"""
diff -Nru containerd-1.4.5~ds1/releases/v1.4.8.toml containerd-1.4.12~ds1/releases/v1.4.8.toml
--- containerd-1.4.5~ds1/releases/v1.4.8.toml 1970-01-01 08:00:00.000000000 +0800
+++ containerd-1.4.12~ds1/releases/v1.4.8.toml 2021-11-18 03:52:12.000000000 +0800
@@ -0,0 +1,14 @@
+# commit to be tagged for new release
+commit = "HEAD"
+
+project_name = "containerd"
+github_repo = "containerd/containerd"
+match_deps = "^github.com/(containerd/[a-zA-Z0-9-]+)$"
+
+# previous release
+previous = "v1.4.7"
+
+pre_release = false
+
+preface = """\
+The eighth patch release for containerd 1.4 is a security release to address [CVE-2021-32760](https://github.com/containerd/containerd/security/advisories/GHSA-c72p-9xmj-rx3w)."""
diff -Nru containerd-1.4.5~ds1/releases/v1.4.9.toml containerd-1.4.12~ds1/releases/v1.4.9.toml
--- containerd-1.4.5~ds1/releases/v1.4.9.toml 1970-01-01 08:00:00.000000000 +0800
+++ containerd-1.4.12~ds1/releases/v1.4.9.toml 2021-11-18 03:52:12.000000000 +0800
@@ -0,0 +1,23 @@
+# commit to be tagged for new release
+commit = "HEAD"
+
+project_name = "containerd"
+github_repo = "containerd/containerd"
+match_deps = "^github.com/(containerd/[a-zA-Z0-9-]+)$"
+
+# previous release
+previous = "v1.4.8"
+
+pre_release = false
+
+preface = """\
+The ninth patch release for containerd 1.4 updates runc to 1.0.1 and contains
+other minor updates.
+
+### Notable Updates
+
+* **Update runc binary to 1.0.1** [#5751](https://github.com/containerd/containerd/pull/5751)
+* **Update pull authorization logic on redirect** [#5504](https://github.com/containerd/containerd/pull/5504)
+* **Fix user agent used for fetching registry authentication tokens** [#5761](https://github.com/containerd/containerd/pull/5761)
+
+See the changelog for complete list of changes"""
diff -Nru containerd-1.4.5~ds1/remotes/docker/authorizer.go containerd-1.4.12~ds1/remotes/docker/authorizer.go
--- containerd-1.4.5~ds1/remotes/docker/authorizer.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/remotes/docker/authorizer.go 2021-11-18 03:52:12.000000000 +0800
@@ -31,6 +31,7 @@
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/log"
+ "github.com/containerd/containerd/version"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/net/context/ctxhttp"
@@ -356,6 +357,9 @@
req.Header[k] = append(req.Header[k], v...)
}
}
+ if len(req.Header.Get("User-Agent")) == 0 {
+ req.Header.Set("User-Agent", "containerd/"+version.Version)
+ }
resp, err := ctxhttp.Do(ctx, ah.client, req)
if err != nil {
@@ -408,6 +412,9 @@
req.Header[k] = append(req.Header[k], v...)
}
}
+ if len(req.Header.Get("User-Agent")) == 0 {
+ req.Header.Set("User-Agent", "containerd/"+version.Version)
+ }
reqParams := req.URL.Query()
diff -Nru containerd-1.4.5~ds1/remotes/docker/fetcher.go containerd-1.4.12~ds1/remotes/docker/fetcher.go
--- containerd-1.4.5~ds1/remotes/docker/fetcher.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/remotes/docker/fetcher.go 2021-11-18 03:52:12.000000000 +0800
@@ -60,6 +60,10 @@
log.G(ctx).WithError(err).Debug("failed to parse")
continue
}
+ if u.Scheme != "http" && u.Scheme != "https" {
+ log.G(ctx).Debug("non-http(s) alternative url is unsupported")
+ continue
+ }
log.G(ctx).Debug("trying alternative url")
// Try this first, parse it
@@ -148,7 +152,7 @@
})
}
-func (r dockerFetcher) open(ctx context.Context, req *request, mediatype string, offset int64) (io.ReadCloser, error) {
+func (r dockerFetcher) open(ctx context.Context, req *request, mediatype string, offset int64) (_ io.ReadCloser, retErr error) {
req.header.Set("Accept", strings.Join([]string{mediatype, `*/*`}, ", "))
if offset > 0 {
@@ -162,13 +166,17 @@
if err != nil {
return nil, err
}
+ defer func() {
+ if retErr != nil {
+ resp.Body.Close()
+ }
+ }()
if resp.StatusCode > 299 {
// TODO(stevvooe): When doing a offset specific request, we should
// really distinguish between a 206 and a 200. In the case of 200, we
// can discard the bytes, hiding the seek behavior from the
// implementation.
- defer resp.Body.Close()
if resp.StatusCode == http.StatusNotFound {
return nil, errors.Wrapf(errdefs.ErrNotFound, "content at %v not found", req.String())
diff -Nru containerd-1.4.5~ds1/remotes/docker/pusher.go containerd-1.4.12~ds1/remotes/docker/pusher.go
--- containerd-1.4.5~ds1/remotes/docker/pusher.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/remotes/docker/pusher.go 2021-11-18 03:52:12.000000000 +0800
@@ -109,12 +109,15 @@
// TODO: Set updated time?
},
})
+ resp.Body.Close()
return nil, errors.Wrapf(errdefs.ErrAlreadyExists, "content %v on remote", desc.Digest)
}
} else if resp.StatusCode != http.StatusNotFound {
+ resp.Body.Close()
// TODO: log error
return nil, errors.Errorf("unexpected response: %s", resp.Status)
}
+ resp.Body.Close()
}
if isManifest {
@@ -155,6 +158,7 @@
return nil, err
}
}
+ defer resp.Body.Close()
switch resp.StatusCode {
case http.StatusOK, http.StatusAccepted, http.StatusNoContent:
@@ -338,6 +342,7 @@
if resp == nil {
return errors.New("no response")
}
+ defer resp.Body.Close()
// 201 is specified return status, some registries return
// 200, 202 or 204.
diff -Nru containerd-1.4.5~ds1/remotes/docker/resolver.go containerd-1.4.12~ds1/remotes/docker/resolver.go
--- containerd-1.4.5~ds1/remotes/docker/resolver.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/remotes/docker/resolver.go 2021-11-18 03:52:12.000000000 +0800
@@ -238,10 +238,10 @@
}
var (
- lastErr error
- paths [][]string
- dgst = refspec.Digest()
- caps = HostCapabilityPull
+ firstErr error
+ paths [][]string
+ dgst = refspec.Digest()
+ caps = HostCapabilityPull
)
if dgst != "" {
@@ -292,8 +292,8 @@
err = errors.Wrapf(err, "pull access denied, repository does not exist or may require authorization")
}
// Store the error for referencing later
- if lastErr == nil {
- lastErr = err
+ if firstErr == nil {
+ firstErr = err
}
log.G(ctx).WithError(err).Info("trying next host")
continue // try another host
@@ -305,7 +305,14 @@
log.G(ctx).Info("trying next host - response was http.StatusNotFound")
continue
}
- return "", ocispec.Descriptor{}, errors.Errorf("unexpected status code %v: %v", u, resp.Status)
+ if resp.StatusCode > 399 {
+ // Set firstErr when encountering the first non-404 status code.
+ if firstErr == nil {
+ firstErr = errors.Errorf("pulling from host %s failed with status code %v: %v", host.Host, u, resp.Status)
+ }
+ continue // try another host
+ }
+ return "", ocispec.Descriptor{}, errors.Errorf("pulling from host %s failed with unexpected status code %v: %v", host.Host, u, resp.Status)
}
size := resp.ContentLength
contentType := getManifestMediaType(resp)
@@ -368,8 +375,8 @@
}
// Prevent resolving to excessively large manifests
if size > MaxManifestSize {
- if lastErr == nil {
- lastErr = errors.Wrapf(errdefs.ErrNotFound, "rejecting %d byte manifest for %s", size, ref)
+ if firstErr == nil {
+ firstErr = errors.Wrapf(errdefs.ErrNotFound, "rejecting %d byte manifest for %s", size, ref)
}
continue
}
@@ -385,11 +392,15 @@
}
}
- if lastErr == nil {
- lastErr = errors.Wrap(errdefs.ErrNotFound, ref)
+ // If above loop terminates without return, then there was an error.
+ // "firstErr" contains the first non-404 error. That is, "firstErr == nil"
+ // means that either no registries were given or each registry returned 404.
+
+ if firstErr == nil {
+ firstErr = errors.Wrap(errdefs.ErrNotFound, ref)
}
- return "", ocispec.Descriptor{}, lastErr
+ return "", ocispec.Descriptor{}, firstErr
}
func (r *dockerResolver) Fetcher(ctx context.Context, ref string) (remotes.Fetcher, error) {
@@ -548,7 +559,21 @@
if err := r.authorize(ctx, req); err != nil {
return nil, errors.Wrap(err, "failed to authorize")
}
- resp, err := ctxhttp.Do(ctx, r.host.Client, req)
+
+ var client = &http.Client{}
+ if r.host.Client != nil {
+ *client = *r.host.Client
+ }
+ if client.CheckRedirect == nil {
+ client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
+ if len(via) >= 10 {
+ return errors.New("stopped after 10 redirects")
+ }
+ return errors.Wrap(r.authorize(ctx, req), "failed to authorize redirect")
+ }
+ }
+
+ resp, err := ctxhttp.Do(ctx, client, req)
if err != nil {
return nil, errors.Wrap(err, "failed to do request")
}
diff -Nru containerd-1.4.5~ds1/remotes/docker/schema1/converter.go containerd-1.4.12~ds1/remotes/docker/schema1/converter.go
--- containerd-1.4.5~ds1/remotes/docker/schema1/converter.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/remotes/docker/schema1/converter.go 2021-11-18 03:52:12.000000000 +0800
@@ -256,6 +256,9 @@
if err := json.Unmarshal(b, &m); err != nil {
return err
}
+ if len(m.Manifests) != 0 || len(m.Layers) != 0 {
+ return errors.New("converter: expected schema1 document but found extra keys")
+ }
c.pulledManifest = &m
return nil
@@ -472,8 +475,10 @@
}
type manifest struct {
- FSLayers []fsLayer `json:"fsLayers"`
- History []history `json:"history"`
+ FSLayers []fsLayer `json:"fsLayers"`
+ History []history `json:"history"`
+ Layers json.RawMessage `json:"layers,omitempty"` // OCI manifest
+ Manifests json.RawMessage `json:"manifests,omitempty"` // OCI index
}
type v1History struct {
diff -Nru containerd-1.4.5~ds1/runtime/v1/linux/bundle.go containerd-1.4.12~ds1/runtime/v1/linux/bundle.go
--- containerd-1.4.5~ds1/runtime/v1/linux/bundle.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/runtime/v1/linux/bundle.go 2021-11-18 03:52:12.000000000 +0800
@@ -21,6 +21,7 @@
import (
"context"
"crypto/sha256"
+ "encoding/json"
"fmt"
"io/ioutil"
"os"
@@ -30,6 +31,7 @@
"github.com/containerd/containerd/runtime/linux/runctypes"
"github.com/containerd/containerd/runtime/v1/shim"
"github.com/containerd/containerd/runtime/v1/shim/client"
+ "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
)
@@ -48,7 +50,7 @@
return nil, err
}
path = filepath.Join(path, id)
- if err := os.Mkdir(path, 0711); err != nil {
+ if err := os.Mkdir(path, 0700); err != nil {
return nil, err
}
defer func() {
@@ -56,6 +58,9 @@
os.RemoveAll(path)
}
}()
+ if err := prepareBundleDirectoryPermissions(path, spec); err != nil {
+ return nil, err
+ }
workDir = filepath.Join(workDir, id)
if err := os.MkdirAll(workDir, 0711); err != nil {
return nil, err
@@ -77,6 +82,55 @@
}, err
}
+// prepareBundleDirectoryPermissions prepares the permissions of the bundle
+// directory. When user namespaces are enabled, the permissions are modified
+// to allow the remapped root GID to access the bundle.
+func prepareBundleDirectoryPermissions(path string, spec []byte) error {
+ gid, err := remappedGID(spec)
+ if err != nil {
+ return err
+ }
+ if gid == 0 {
+ return nil
+ }
+ if err := os.Chown(path, -1, int(gid)); err != nil {
+ return err
+ }
+ return os.Chmod(path, 0710)
+}
+
+// ociSpecUserNS is a subset of specs.Spec used to reduce garbage during
+// unmarshal.
+type ociSpecUserNS struct {
+ Linux *linuxSpecUserNS
+}
+
+// linuxSpecUserNS is a subset of specs.Linux used to reduce garbage during
+// unmarshal.
+type linuxSpecUserNS struct {
+ GIDMappings []specs.LinuxIDMapping
+}
+
+// remappedGID reads the remapped GID 0 from the OCI spec, if it exists. If
+// there is no remapping, remappedGID returns 0. If the spec cannot be parsed,
+// remappedGID returns an error.
+func remappedGID(spec []byte) (uint32, error) {
+ var ociSpec ociSpecUserNS
+ err := json.Unmarshal(spec, &ociSpec)
+ if err != nil {
+ return 0, err
+ }
+ if ociSpec.Linux == nil || len(ociSpec.Linux.GIDMappings) == 0 {
+ return 0, nil
+ }
+ for _, mapping := range ociSpec.Linux.GIDMappings {
+ if mapping.ContainerID == 0 {
+ return mapping.HostID, nil
+ }
+ }
+ return 0, nil
+}
+
type bundle struct {
id string
path string
diff -Nru containerd-1.4.5~ds1/runtime/v1/linux/bundle_test.go containerd-1.4.12~ds1/runtime/v1/linux/bundle_test.go
--- containerd-1.4.5~ds1/runtime/v1/linux/bundle_test.go 1970-01-01 08:00:00.000000000 +0800
+++ containerd-1.4.12~ds1/runtime/v1/linux/bundle_test.go 2021-11-18 03:52:12.000000000 +0800
@@ -0,0 +1,166 @@
+//go:build linux
+// +build linux
+
+/*
+ Copyright The containerd Authors.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package linux
+
+import (
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "strconv"
+ "syscall"
+ "testing"
+
+ "github.com/containerd/containerd/oci"
+ "github.com/containerd/continuity/testutil"
+ "github.com/opencontainers/runtime-spec/specs-go"
+)
+
+func TestNewBundle(t *testing.T) {
+ testutil.RequiresRoot(t)
+ tests := []struct {
+ userns bool
+ }{{
+ userns: false,
+ }, {
+ userns: true,
+ }}
+ const usernsGID = 4200
+
+ for i, tc := range tests {
+ t.Run(strconv.Itoa(i), func(t *testing.T) {
+ dir, err := ioutil.TempDir("", "test-new-bundle")
+ if err != nil {
+ t.Fatal("failed to create test directory", err)
+ }
+ defer os.RemoveAll(dir)
+ work := filepath.Join(dir, "work")
+ state := filepath.Join(dir, "state")
+ id := fmt.Sprintf("new-bundle-%d", i)
+ spec := oci.Spec{}
+ if tc.userns {
+ spec.Linux = &specs.Linux{
+ GIDMappings: []specs.LinuxIDMapping{{ContainerID: 0, HostID: usernsGID}},
+ }
+ }
+ specBytes, err := json.Marshal(&spec)
+ if err != nil {
+ t.Fatal("failed to marshal spec", err)
+ }
+
+ b, err := newBundle(id, work, state, specBytes)
+ if err != nil {
+ t.Fatal("newBundle should succeed", err)
+ }
+ if b == nil {
+ t.Fatal("bundle should not be nil")
+ }
+
+ fi, err := os.Stat(b.path)
+ if err != nil {
+ t.Error("should be able to stat bundle path", err)
+ }
+ if tc.userns {
+ if fi.Mode() != os.ModeDir|0710 {
+ t.Error("bundle path should be a directory with perm 0710")
+ }
+ } else {
+ if fi.Mode() != os.ModeDir|0700 {
+ t.Error("bundle path should be a directory with perm 0700")
+ }
+ }
+ stat, ok := fi.Sys().(*syscall.Stat_t)
+ if !ok {
+ t.Fatal("should assert to *syscall.Stat_t")
+ }
+ expectedGID := uint32(0)
+ if tc.userns {
+ expectedGID = usernsGID
+ }
+ if stat.Gid != expectedGID {
+ t.Error("gid should match", expectedGID, stat.Gid)
+ }
+ })
+ }
+}
+
+func TestRemappedGID(t *testing.T) {
+ tests := []struct {
+ spec oci.Spec
+ gid uint32
+ }{{
+ // empty spec
+ spec: oci.Spec{},
+ gid: 0,
+ }, {
+ // empty Linux section
+ spec: oci.Spec{
+ Linux: &specs.Linux{},
+ },
+ gid: 0,
+ }, {
+ // empty ID mappings
+ spec: oci.Spec{
+ Linux: &specs.Linux{
+ GIDMappings: make([]specs.LinuxIDMapping, 0),
+ },
+ },
+ gid: 0,
+ }, {
+ // valid ID mapping
+ spec: oci.Spec{
+ Linux: &specs.Linux{
+ GIDMappings: []specs.LinuxIDMapping{{
+ ContainerID: 0,
+ HostID: 1000,
+ }},
+ },
+ },
+ gid: 1000,
+ }, {
+ // missing ID mapping
+ spec: oci.Spec{
+ Linux: &specs.Linux{
+ GIDMappings: []specs.LinuxIDMapping{{
+ ContainerID: 100,
+ HostID: 1000,
+ }},
+ },
+ },
+ gid: 0,
+ }}
+
+ for i, tc := range tests {
+ t.Run(strconv.Itoa(i), func(t *testing.T) {
+ s, err := json.Marshal(tc.spec)
+ if err != nil {
+ t.Fatal("failed to marshal spec", err)
+ }
+ gid, err := remappedGID(s)
+ if err != nil {
+ t.Error("should unmarshal successfully", err)
+ }
+ if gid != tc.gid {
+ t.Error("expected GID to match", tc.gid, gid)
+ }
+ })
+ }
+}
diff -Nru containerd-1.4.5~ds1/runtime/v2/bundle_default.go containerd-1.4.12~ds1/runtime/v2/bundle_default.go
--- containerd-1.4.5~ds1/runtime/v2/bundle_default.go 1970-01-01 08:00:00.000000000 +0800
+++ containerd-1.4.12~ds1/runtime/v2/bundle_default.go 2021-11-18 03:52:12.000000000 +0800
@@ -0,0 +1,24 @@
+//go:build !linux
+// +build !linux
+
+/*
+ Copyright The containerd Authors.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package v2
+
+// prepareBundleDirectoryPermissions prepares the permissions of the bundle
+// directory according to the needs of the current platform.
+func prepareBundleDirectoryPermissions(path string, spec []byte) error { return nil }
diff -Nru containerd-1.4.5~ds1/runtime/v2/bundle.go containerd-1.4.12~ds1/runtime/v2/bundle.go
--- containerd-1.4.5~ds1/runtime/v2/bundle.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/runtime/v2/bundle.go 2021-11-18 03:52:12.000000000 +0800
@@ -72,7 +72,10 @@
if err := os.MkdirAll(filepath.Dir(b.Path), 0711); err != nil {
return nil, err
}
- if err := os.Mkdir(b.Path, 0711); err != nil {
+ if err := os.Mkdir(b.Path, 0700); err != nil {
+ return nil, err
+ }
+ if err := prepareBundleDirectoryPermissions(b.Path, spec); err != nil {
return nil, err
}
paths = append(paths, b.Path)
diff -Nru containerd-1.4.5~ds1/runtime/v2/bundle_linux.go containerd-1.4.12~ds1/runtime/v2/bundle_linux.go
--- containerd-1.4.5~ds1/runtime/v2/bundle_linux.go 1970-01-01 08:00:00.000000000 +0800
+++ containerd-1.4.12~ds1/runtime/v2/bundle_linux.go 2021-11-18 03:52:12.000000000 +0800
@@ -0,0 +1,74 @@
+/*
+ Copyright The containerd Authors.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package v2
+
+import (
+ "encoding/json"
+ "os"
+
+ "github.com/opencontainers/runtime-spec/specs-go"
+)
+
+// prepareBundleDirectoryPermissions prepares the permissions of the bundle
+// directory according to the needs of the current platform.
+// On Linux when user namespaces are enabled, the permissions are modified to
+// allow the remapped root GID to access the bundle.
+func prepareBundleDirectoryPermissions(path string, spec []byte) error {
+ gid, err := remappedGID(spec)
+ if err != nil {
+ return err
+ }
+ if gid == 0 {
+ return nil
+ }
+ if err := os.Chown(path, -1, int(gid)); err != nil {
+ return err
+ }
+ return os.Chmod(path, 0710)
+}
+
+// ociSpecUserNS is a subset of specs.Spec used to reduce garbage during
+// unmarshal.
+type ociSpecUserNS struct {
+ Linux *linuxSpecUserNS
+}
+
+// linuxSpecUserNS is a subset of specs.Linux used to reduce garbage during
+// unmarshal.
+type linuxSpecUserNS struct {
+ GIDMappings []specs.LinuxIDMapping
+}
+
+// remappedGID reads the remapped GID 0 from the OCI spec, if it exists. If
+// there is no remapping, remappedGID returns 0. If the spec cannot be parsed,
+// remappedGID returns an error.
+func remappedGID(spec []byte) (uint32, error) {
+ var ociSpec ociSpecUserNS
+ err := json.Unmarshal(spec, &ociSpec)
+ if err != nil {
+ return 0, err
+ }
+ if ociSpec.Linux == nil || len(ociSpec.Linux.GIDMappings) == 0 {
+ return 0, nil
+ }
+ for _, mapping := range ociSpec.Linux.GIDMappings {
+ if mapping.ContainerID == 0 {
+ return mapping.HostID, nil
+ }
+ }
+ return 0, nil
+}
diff -Nru containerd-1.4.5~ds1/runtime/v2/bundle_linux_test.go containerd-1.4.12~ds1/runtime/v2/bundle_linux_test.go
--- containerd-1.4.5~ds1/runtime/v2/bundle_linux_test.go 1970-01-01 08:00:00.000000000 +0800
+++ containerd-1.4.12~ds1/runtime/v2/bundle_linux_test.go 2021-11-18 03:52:12.000000000 +0800
@@ -0,0 +1,166 @@
+/*
+ Copyright The containerd Authors.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package v2
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "strconv"
+ "syscall"
+ "testing"
+
+ "github.com/containerd/containerd/namespaces"
+ "github.com/containerd/containerd/oci"
+ "github.com/containerd/containerd/pkg/testutil"
+ "github.com/opencontainers/runtime-spec/specs-go"
+)
+
+func TestNewBundle(t *testing.T) {
+ testutil.RequiresRoot(t)
+ tests := []struct {
+ userns bool
+ }{{
+ userns: false,
+ }, {
+ userns: true,
+ }}
+ const usernsGID = 4200
+
+ for i, tc := range tests {
+ t.Run(strconv.Itoa(i), func(t *testing.T) {
+ dir, err := ioutil.TempDir("", "test-new-bundle")
+ if err != nil {
+ t.Fatal("failed to create test directory", err)
+ }
+ defer os.RemoveAll(dir)
+ work := filepath.Join(dir, "work")
+ state := filepath.Join(dir, "state")
+ id := fmt.Sprintf("new-bundle-%d", i)
+ spec := oci.Spec{}
+ if tc.userns {
+ spec.Linux = &specs.Linux{
+ GIDMappings: []specs.LinuxIDMapping{{ContainerID: 0, HostID: usernsGID}},
+ }
+ }
+ specBytes, err := json.Marshal(&spec)
+ if err != nil {
+ t.Fatal("failed to marshal spec", err)
+ }
+
+ ctx := namespaces.WithNamespace(context.TODO(), namespaces.Default)
+ b, err := NewBundle(ctx, work, state, id, specBytes)
+ if err != nil {
+ t.Fatal("NewBundle should succeed", err)
+ }
+ if b == nil {
+ t.Fatal("bundle should not be nil")
+ }
+
+ fi, err := os.Stat(b.Path)
+ if err != nil {
+ t.Error("should be able to stat bundle path", err)
+ }
+ if tc.userns {
+ if fi.Mode() != os.ModeDir|0710 {
+ t.Error("bundle path should be a directory with perm 0710")
+ }
+ } else {
+ if fi.Mode() != os.ModeDir|0700 {
+ t.Error("bundle path should be a directory with perm 0700")
+ }
+ }
+ stat, ok := fi.Sys().(*syscall.Stat_t)
+ if !ok {
+ t.Fatal("should assert to *syscall.Stat_t")
+ }
+ expectedGID := uint32(0)
+ if tc.userns {
+ expectedGID = usernsGID
+ }
+ if expectedGID != stat.Gid {
+ t.Error("gid should match", expectedGID, stat.Gid)
+ }
+ })
+ }
+}
+
+func TestRemappedGID(t *testing.T) {
+ tests := []struct {
+ spec oci.Spec
+ gid uint32
+ }{{
+ // empty spec
+ spec: oci.Spec{},
+ gid: 0,
+ }, {
+ // empty Linux section
+ spec: oci.Spec{
+ Linux: &specs.Linux{},
+ },
+ gid: 0,
+ }, {
+ // empty ID mappings
+ spec: oci.Spec{
+ Linux: &specs.Linux{
+ GIDMappings: make([]specs.LinuxIDMapping, 0),
+ },
+ },
+ gid: 0,
+ }, {
+ // valid ID mapping
+ spec: oci.Spec{
+ Linux: &specs.Linux{
+ GIDMappings: []specs.LinuxIDMapping{{
+ ContainerID: 0,
+ HostID: 1000,
+ }},
+ },
+ },
+ gid: 1000,
+ }, {
+ // missing ID mapping
+ spec: oci.Spec{
+ Linux: &specs.Linux{
+ GIDMappings: []specs.LinuxIDMapping{{
+ ContainerID: 100,
+ HostID: 1000,
+ }},
+ },
+ },
+ gid: 0,
+ }}
+
+ for i, tc := range tests {
+ t.Run(strconv.Itoa(i), func(t *testing.T) {
+ s, err := json.Marshal(tc.spec)
+ if err != nil {
+ t.Fatal("failed to marshal spec", err)
+ }
+ gid, err := remappedGID(s)
+ if err != nil {
+ t.Error("should unmarshal successfully", err)
+ }
+ if tc.gid != gid {
+ t.Error("expected GID to match", tc.gid, gid)
+ }
+ })
+ }
+}
diff -Nru containerd-1.4.5~ds1/runtime/v2/bundle_test.go containerd-1.4.12~ds1/runtime/v2/bundle_test.go
--- containerd-1.4.5~ds1/runtime/v2/bundle_test.go 1970-01-01 08:00:00.000000000 +0800
+++ containerd-1.4.12~ds1/runtime/v2/bundle_test.go 2021-11-18 03:52:12.000000000 +0800
@@ -0,0 +1,23 @@
+/*
+ Copyright The containerd Authors.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package v2
+
+import (
+ // When testutil is imported for one platform (bundle_linux_test.go) it
+ // should be imported for all platforms.
+ _ "github.com/containerd/containerd/pkg/testutil"
+)
diff -Nru containerd-1.4.5~ds1/script/setup/runc-version containerd-1.4.12~ds1/script/setup/runc-version
--- containerd-1.4.5~ds1/script/setup/runc-version 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/script/setup/runc-version 2021-11-18 03:52:12.000000000 +0800
@@ -1 +1 @@
-v1.0.0-rc94
+v1.0.2
diff -Nru containerd-1.4.5~ds1/snapshots/btrfs/btrfs.go containerd-1.4.12~ds1/snapshots/btrfs/btrfs.go
--- containerd-1.4.5~ds1/snapshots/btrfs/btrfs.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/snapshots/btrfs/btrfs.go 2021-11-18 03:52:12.000000000 +0800
@@ -63,11 +63,15 @@
// root needs to be a mount point of btrfs.
func NewSnapshotter(root string) (snapshots.Snapshotter, error) {
// If directory does not exist, create it
- if _, err := os.Stat(root); err != nil {
+ if st, err := os.Stat(root); err != nil {
if !os.IsNotExist(err) {
return nil, err
}
- if err := os.Mkdir(root, 0755); err != nil {
+ if err := os.Mkdir(root, 0700); err != nil {
+ return nil, err
+ }
+ } else if st.Mode()&os.ModePerm != 0700 {
+ if err := os.Chmod(root, 0700); err != nil {
return nil, err
}
}
diff -Nru containerd-1.4.5~ds1/snapshots/devmapper/snapshotter.go containerd-1.4.12~ds1/snapshots/devmapper/snapshotter.go
--- containerd-1.4.5~ds1/snapshots/devmapper/snapshotter.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/snapshots/devmapper/snapshotter.go 2021-11-18 03:52:12.000000000 +0800
@@ -232,7 +232,7 @@
// View creates readonly thin device for the given snapshot key
func (s *Snapshotter) View(ctx context.Context, key, parent string, opts ...snapshots.Opt) ([]mount.Mount, error) {
- log.G(ctx).WithFields(logrus.Fields{"key": key, "parent": parent}).Debug("prepare")
+ log.G(ctx).WithFields(logrus.Fields{"key": key, "parent": parent}).Debug("view")
var (
mounts []mount.Mount
@@ -511,6 +511,8 @@
}
func (s *Snapshotter) Cleanup(ctx context.Context) error {
+ log.G(ctx).Debug("cleanup")
+
var removedDevices []*DeviceInfo
if !s.config.AsyncRemove {
diff -Nru containerd-1.4.5~ds1/.travis.yml containerd-1.4.12~ds1/.travis.yml
--- containerd-1.4.5~ds1/.travis.yml 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/.travis.yml 2021-11-18 03:52:12.000000000 +0800
@@ -15,7 +15,7 @@
- linux
go:
- - "1.15.11"
+ - "1.16.10"
env:
- TRAVIS_GOOS=linux TEST_RUNTIME=io.containerd.runc.v1 TRAVIS_CGO_ENABLED=1 TRAVIS_DISTRO=bionic GOPROXY=direct
diff -Nru containerd-1.4.5~ds1/Vagrantfile containerd-1.4.12~ds1/Vagrantfile
--- containerd-1.4.5~ds1/Vagrantfile 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/Vagrantfile 2021-11-18 03:52:12.000000000 +0800
@@ -77,7 +77,7 @@
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.15.11",
+ 'GO_VERSION': ENV['GO_VERSION'] || "1.16.10",
}
sh.inline = <<~SHELL
#!/usr/bin/env bash
diff -Nru containerd-1.4.5~ds1/vendor/github.com/containerd/cri/pkg/os/os.go containerd-1.4.12~ds1/vendor/github.com/containerd/cri/pkg/os/os.go
--- containerd-1.4.5~ds1/vendor/github.com/containerd/cri/pkg/os/os.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/vendor/github.com/containerd/cri/pkg/os/os.go 2021-11-18 03:52:12.000000000 +0800
@@ -20,7 +20,6 @@
"io"
"io/ioutil"
"os"
- "path/filepath"
"github.com/docker/docker/pkg/symlink"
)
@@ -56,18 +55,6 @@
return os.Stat(name)
}
-// ResolveSymbolicLink will follow any symbolic links
-func (RealOS) ResolveSymbolicLink(path string) (string, error) {
- info, err := os.Lstat(path)
- if err != nil {
- return "", err
- }
- if info.Mode()&os.ModeSymlink != os.ModeSymlink {
- return path, nil
- }
- return filepath.EvalSymlinks(path)
-}
-
// FollowSymlinkInScope will call symlink.FollowSymlinkInScope.
func (RealOS) FollowSymlinkInScope(path, scope string) (string, error) {
return symlink.FollowSymlinkInScope(path, scope)
diff -Nru containerd-1.4.5~ds1/vendor/github.com/containerd/cri/pkg/os/os_unix.go containerd-1.4.12~ds1/vendor/github.com/containerd/cri/pkg/os/os_unix.go
--- containerd-1.4.5~ds1/vendor/github.com/containerd/cri/pkg/os/os_unix.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/vendor/github.com/containerd/cri/pkg/os/os_unix.go 2021-11-18 03:52:12.000000000 +0800
@@ -19,6 +19,9 @@
package os
import (
+ "os"
+ "path/filepath"
+
"github.com/containerd/containerd/mount"
"golang.org/x/sys/unix"
)
@@ -57,3 +60,15 @@
return err
}
+
+// ResolveSymbolicLink will follow any symbolic links
+func (RealOS) ResolveSymbolicLink(path string) (string, error) {
+ info, err := os.Lstat(path)
+ if err != nil {
+ return "", err
+ }
+ if info.Mode()&os.ModeSymlink != os.ModeSymlink {
+ return path, nil
+ }
+ return filepath.EvalSymlinks(path)
+}
diff -Nru containerd-1.4.5~ds1/vendor/github.com/containerd/cri/pkg/os/os_windows.go containerd-1.4.12~ds1/vendor/github.com/containerd/cri/pkg/os/os_windows.go
--- containerd-1.4.5~ds1/vendor/github.com/containerd/cri/pkg/os/os_windows.go 1970-01-01 08:00:00.000000000 +0800
+++ containerd-1.4.12~ds1/vendor/github.com/containerd/cri/pkg/os/os_windows.go 2021-11-18 03:52:12.000000000 +0800
@@ -0,0 +1,182 @@
+// +build windows
+
+/*
+ Copyright The containerd Authors.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package os
+
+import (
+ "os"
+ "strings"
+ "sync"
+ "unicode/utf16"
+
+ "golang.org/x/sys/windows"
+)
+
+// openPath takes a path, opens it, and returns the resulting handle.
+// It works for both file and directory paths.
+//
+// We are not able to use builtin Go functionality for opening a directory path:
+// - os.Open on a directory returns a os.File where Fd() is a search handle from FindFirstFile.
+// - syscall.Open does not provide a way to specify FILE_FLAG_BACKUP_SEMANTICS, which is needed to
+// open a directory.
+// We could use os.Open if the path is a file, but it's easier to just use the same code for both.
+// Therefore, we call windows.CreateFile directly.
+func openPath(path string) (windows.Handle, error) {
+ u16, err := windows.UTF16PtrFromString(path)
+ if err != nil {
+ return 0, err
+ }
+ h, err := windows.CreateFile(
+ u16,
+ 0,
+ windows.FILE_SHARE_READ|windows.FILE_SHARE_WRITE|windows.FILE_SHARE_DELETE,
+ nil,
+ windows.OPEN_EXISTING,
+ windows.FILE_FLAG_BACKUP_SEMANTICS, // Needed to open a directory handle.
+ 0)
+ if err != nil {
+ return 0, &os.PathError{
+ Op: "CreateFile",
+ Path: path,
+ Err: err,
+ }
+ }
+ return h, nil
+}
+
+// GetFinalPathNameByHandle flags.
+//nolint:golint
+const (
+ cFILE_NAME_OPENED = 0x8
+
+ cVOLUME_NAME_DOS = 0x0
+ cVOLUME_NAME_GUID = 0x1
+)
+
+var pool = sync.Pool{
+ New: func() interface{} {
+ // Size of buffer chosen somewhat arbitrarily to accommodate a large number of path strings.
+ // MAX_PATH (260) + size of volume GUID prefix (49) + null terminator = 310.
+ b := make([]uint16, 310)
+ return &b
+ },
+}
+
+// getFinalPathNameByHandle facilitates calling the Windows API GetFinalPathNameByHandle
+// with the given handle and flags. It transparently takes care of creating a buffer of the
+// correct size for the call.
+func getFinalPathNameByHandle(h windows.Handle, flags uint32) (string, error) {
+ b := *(pool.Get().(*[]uint16))
+ defer func() { pool.Put(&b) }()
+ for {
+ n, err := windows.GetFinalPathNameByHandle(h, &b[0], uint32(len(b)), flags)
+ if err != nil {
+ return "", err
+ }
+ // If the buffer wasn't large enough, n will be the total size needed (including null terminator).
+ // Resize and try again.
+ if n > uint32(len(b)) {
+ b = make([]uint16, n)
+ continue
+ }
+ // If the buffer is large enough, n will be the size not including the null terminator.
+ // Convert to a Go string and return.
+ return string(utf16.Decode(b[:n])), nil
+ }
+}
+
+// resolvePath implements path resolution for Windows. It attempts to return the "real" path to the
+// file or directory represented by the given path.
+// The resolution works by using the Windows API GetFinalPathNameByHandle, which takes a handle and
+// returns the final path to that file.
+func resolvePath(path string) (string, error) {
+ h, err := openPath(path)
+ if err != nil {
+ return "", err
+ }
+ defer windows.CloseHandle(h)
+
+ // We use the Windows API GetFinalPathNameByHandle to handle path resolution. GetFinalPathNameByHandle
+ // returns a resolved path name for a file or directory. The returned path can be in several different
+ // formats, based on the flags passed. There are several goals behind the design here:
+ // - Do as little manual path manipulation as possible. Since Windows path formatting can be quite
+ // complex, we try to just let the Windows APIs handle that for us.
+ // - Retain as much compatibility with existing Go path functions as we can. In particular, we try to
+ // ensure paths returned from resolvePath can be passed to EvalSymlinks.
+ //
+ // First, we query for the VOLUME_NAME_GUID path of the file. This will return a path in the form
+ // "\\?\Volume{8a25748f-cf34-4ac6-9ee2-c89400e886db}\dir\file.txt". If the path is a UNC share
+ // (e.g. "\\server\share\dir\file.txt"), then the VOLUME_NAME_GUID query will fail with ERROR_PATH_NOT_FOUND.
+ // In this case, we will next try a VOLUME_NAME_DOS query. This query will return a path for a UNC share
+ // in the form "\\?\UNC\server\share\dir\file.txt". This path will work with most functions, but EvalSymlinks
+ // fails on it. Therefore, we rewrite the path to the form "\\server\share\dir\file.txt" before returning it.
+ // This path rewrite may not be valid in all cases (see the notes in the next paragraph), but those should
+ // be very rare edge cases, and this case wouldn't have worked with EvalSymlinks anyways.
+ //
+ // The "\\?\" prefix indicates that no path parsing or normalization should be performed by Windows.
+ // Instead the path is passed directly to the object manager. The lack of parsing means that "." and ".." are
+ // interpreted literally and "\"" must be used as a path separator. Additionally, because normalization is
+ // not done, certain paths can only be represented in this format. For instance, "\\?\C:\foo." (with a trailing .)
+ // cannot be written as "C:\foo.", because path normalization will remove the trailing ".".
+ //
+ // We use FILE_NAME_OPENED instead of FILE_NAME_NORMALIZED, as FILE_NAME_NORMALIZED can fail on some
+ // UNC paths based on access restrictions. The additional normalization done is also quite minimal in
+ // most cases.
+ //
+ // Querying for VOLUME_NAME_DOS first instead of VOLUME_NAME_GUID would yield a "nicer looking" path in some cases.
+ // For instance, it could return "\\?\C:\dir\file.txt" instead of "\\?\Volume{8a25748f-cf34-4ac6-9ee2-c89400e886db}\dir\file.txt".
+ // However, we query for VOLUME_NAME_GUID first for two reasons:
+ // - The volume GUID path is more stable. A volume's mount point can change when it is remounted, but its
+ // volume GUID should not change.
+ // - If the volume is mounted at a non-drive letter path (e.g. mounted to "C:\mnt"), then VOLUME_NAME_DOS
+ // will return the mount path. EvalSymlinks fails on a path like this due to a bug.
+ //
+ // References:
+ // - GetFinalPathNameByHandle: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfinalpathnamebyhandlea
+ // - Naming Files, Paths, and Namespaces: https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file
+ // - Naming a Volume: https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-volume
+
+ rPath, err := getFinalPathNameByHandle(h, cFILE_NAME_OPENED|cVOLUME_NAME_GUID)
+ if err == windows.ERROR_PATH_NOT_FOUND {
+ // ERROR_PATH_NOT_FOUND is returned from the VOLUME_NAME_GUID query if the path is a
+ // network share (UNC path). In this case, query for the DOS name instead, then translate
+ // the returned path to make it more palatable to other path functions.
+ rPath, err = getFinalPathNameByHandle(h, cFILE_NAME_OPENED|cVOLUME_NAME_DOS)
+ if err != nil {
+ return "", err
+ }
+ if strings.HasPrefix(rPath, `\\?\UNC\`) {
+ // Convert \\?\UNC\server\share -> \\server\share. The \\?\UNC syntax does not work with
+ // some Go filepath functions such as EvalSymlinks. In the future if other components
+ // move away from EvalSymlinks and use GetFinalPathNameByHandle instead, we could remove
+ // this path munging.
+ rPath = `\\` + rPath[len(`\\?\UNC\`):]
+ }
+ } else if err != nil {
+ return "", err
+ }
+ return rPath, nil
+}
+
+// ResolveSymbolicLink will follow any symbolic links
+func (RealOS) ResolveSymbolicLink(path string) (string, error) {
+ // filepath.EvalSymlinks does not work very well on Windows, so instead we resolve the path
+ // via resolvePath which uses GetFinalPathNameByHandle. This returns either a path prefixed with `\\?\`,
+ // or a remote share path in the form \\server\share. These should work with most Go and Windows APIs.
+ return resolvePath(path)
+}
diff -Nru containerd-1.4.5~ds1/vendor/github.com/containerd/cri/pkg/server/sandbox_run.go containerd-1.4.12~ds1/vendor/github.com/containerd/cri/pkg/server/sandbox_run.go
--- containerd-1.4.5~ds1/vendor/github.com/containerd/cri/pkg/server/sandbox_run.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/vendor/github.com/containerd/cri/pkg/server/sandbox_run.go 2021-11-18 03:52:12.000000000 +0800
@@ -124,8 +124,10 @@
sandbox.NetNSPath = sandbox.NetNS.GetPath()
defer func() {
if retErr != nil {
+ deferCtx, deferCancel := ctrdutil.DeferContext()
+ defer deferCancel()
// Teardown network if an error is returned.
- if err := c.teardownPodNetwork(ctx, sandbox); err != nil {
+ if err := c.teardownPodNetwork(deferCtx, sandbox); err != nil {
log.G(ctx).WithError(err).Errorf("Failed to destroy network for sandbox %q", id)
}
diff -Nru containerd-1.4.5~ds1/vendor/github.com/containerd/cri/vendor.conf containerd-1.4.12~ds1/vendor/github.com/containerd/cri/vendor.conf
--- containerd-1.4.5~ds1/vendor/github.com/containerd/cri/vendor.conf 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/vendor/github.com/containerd/cri/vendor.conf 2021-11-18 03:52:12.000000000 +0800
@@ -10,8 +10,8 @@
github.com/cespare/xxhash/v2 v2.1.1
github.com/containerd/cgroups 318312a373405e5e91134d8063d04d59768a1bff
github.com/containerd/console v1.0.0
-github.com/containerd/containerd v1.4.1
-github.com/containerd/continuity efbc4488d8fe1bdc16bde3b2d2990d9b3a899165
+github.com/containerd/containerd 8263eb3eaee447b16856eeb8839d5df4c9cca71a
+github.com/containerd/continuity 1d9893e5674b5260c3fc11316d0d5fc0d12ea9e2
github.com/containerd/fifo f15a3290365b9d2627d189e619ab4008e0069caf
github.com/containerd/go-runc 7016d3ce2328dd2cb1192b2076ebd565c4e8df0c
github.com/containerd/ttrpc v1.0.1
@@ -33,11 +33,11 @@
github.com/imdario/mergo v0.3.7
github.com/konsorten/go-windows-terminal-sequences v1.0.3
github.com/matttproud/golang_protobuf_extensions v1.0.1
-github.com/Microsoft/go-winio v0.4.14
-github.com/Microsoft/hcsshim v0.8.9
+github.com/Microsoft/go-winio v0.4.19
+github.com/Microsoft/hcsshim v0.8.16
github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/image-spec v1.0.1
-github.com/opencontainers/runc v1.0.0-rc92
+github.com/opencontainers/runc v1.0.0-rc94
github.com/opencontainers/runtime-spec 4d89ac9fbff6c455f46a5bb59c6b1bb7184a5e43 # v1.0.3-0.20200728170252-4d89ac9fbff6
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.6.0
@@ -51,9 +51,9 @@
github.com/urfave/cli v1.22.1 # NOTE: urfave/cli must be <= v1.22.1 due to a regression: https://github.com/urfave/cli/issues/1092
go.etcd.io/bbolt v1.3.5
go.opencensus.io v0.22.0
-golang.org/x/net ab34263943818b32f575efc978a3d24e80b04bd7
-golang.org/x/sync 42b317875d0fa942474b76e1b46a6060d720ae6e
-golang.org/x/sys ed371f2e16b4b305ee99df548828de367527b76b
+golang.org/x/net 69a78807bb2bb6d1599c68698c6b009505012083
+golang.org/x/sync 67f06af15bc961c363a7260195bcd53487529a21
+golang.org/x/sys d19ff857e887eacb631721f188c7d365c2331456
golang.org/x/text v0.3.3
google.golang.org/genproto e50cd9704f63023d62cd06a1994b98227fc4d21a
google.golang.org/grpc v1.27.1
@@ -77,15 +77,15 @@
golang.org/x/time 555d28b269f0569763d25dbe1a237ae74c6bcc82
gopkg.in/inf.v0 v0.9.1
gopkg.in/yaml.v2 v2.2.8
-k8s.io/api v0.19.4
-k8s.io/apiserver v0.19.4
-k8s.io/apimachinery v0.19.4
-k8s.io/client-go v0.19.4
-k8s.io/component-base v0.19.4
-k8s.io/cri-api v0.19.4
+k8s.io/api v0.19.10
+k8s.io/apiserver v0.19.10
+k8s.io/apimachinery v0.19.10
+k8s.io/client-go v0.19.10
+k8s.io/component-base v0.19.10
+k8s.io/cri-api v0.19.10
k8s.io/klog/v2 v2.2.0
k8s.io/utils d5654de09c73da55eb19ae4ab4f734f7a61747a6
-sigs.k8s.io/structured-merge-diff/v4 v4.0.1
+sigs.k8s.io/structured-merge-diff/v4 v4.0.3
sigs.k8s.io/yaml v1.2.0
# cni dependencies
diff -Nru containerd-1.4.5~ds1/vendor.conf containerd-1.4.12~ds1/vendor.conf
--- containerd-1.4.5~ds1/vendor.conf 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/vendor.conf 2021-11-18 03:52:12.000000000 +0800
@@ -27,11 +27,11 @@
github.com/imdario/mergo v0.3.7
github.com/konsorten/go-windows-terminal-sequences v1.0.3
github.com/matttproud/golang_protobuf_extensions v1.0.1
-github.com/Microsoft/go-winio v0.4.14
-github.com/Microsoft/hcsshim v0.8.10
+github.com/Microsoft/go-winio v0.4.19
+github.com/Microsoft/hcsshim v0.8.21
github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/image-spec v1.0.1
-github.com/opencontainers/runc v1.0.0-rc92
+github.com/opencontainers/runc v1.0.0-rc94
github.com/opencontainers/runtime-spec 4d89ac9fbff6c455f46a5bb59c6b1bb7184a5e43 # v1.0.3-0.20200728170252-4d89ac9fbff6
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.6.0
@@ -47,7 +47,7 @@
go.opencensus.io v0.22.0
golang.org/x/net 69a78807bb2bb6d1599c68698c6b009505012083
golang.org/x/sync 67f06af15bc961c363a7260195bcd53487529a21
-golang.org/x/sys 5cba982894dd4e8879e3ef0a0c308ceff39f6154
+golang.org/x/sys d19ff857e887eacb631721f188c7d365c2331456
golang.org/x/text v0.3.3
google.golang.org/genproto e50cd9704f63023d62cd06a1994b98227fc4d21a
google.golang.org/grpc v1.27.1
@@ -57,7 +57,7 @@
github.com/cilium/ebpf 1c8d4c9ef7759622653a1d319284a44652333b28
# cri dependencies
-github.com/containerd/cri 1360416eca4fef15c763444914e60fe1eaedbc3d # release/1.4
+github.com/containerd/cri 3b02bec1603179debe2cde54509b2bfc45fc27d3 # release/1.4
github.com/davecgh/go-spew v1.1.1
github.com/docker/docker 4634ce647cf2ce2c6031129ccd109e557244986f
github.com/docker/spdystream 449fdfce4d962303d702fec724ef0ad181c92528
diff -Nru containerd-1.4.5~ds1/version/version.go containerd-1.4.12~ds1/version/version.go
--- containerd-1.4.5~ds1/version/version.go 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/version/version.go 2021-11-18 03:52:12.000000000 +0800
@@ -23,7 +23,7 @@
Package = "github.com/containerd/containerd"
// Version holds the complete version number. Filled in at linking time.
- Version = "1.4.5+unknown"
+ Version = "1.4.12+unknown"
// Revision is filled with the VCS (e.g. git) revision being used to build
// the program at linking time.
diff -Nru containerd-1.4.5~ds1/.zuul/playbooks/containerd-build/run.yaml containerd-1.4.12~ds1/.zuul/playbooks/containerd-build/run.yaml
--- containerd-1.4.5~ds1/.zuul/playbooks/containerd-build/run.yaml 2021-05-12 12:30:30.000000000 +0800
+++ containerd-1.4.12~ds1/.zuul/playbooks/containerd-build/run.yaml 2021-11-18 03:52:12.000000000 +0800
@@ -2,7 +2,7 @@
become: yes
roles:
- role: config-golang
- go_version: '1.15.11'
+ go_version: '1.16.10'
arch: arm64
tasks:
- name: Build containerd
Reply to: