From c1eea91a01ac16cfc6ba96024fea08f8606882ce Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 30 Nov 2023 14:48:27 +0000 Subject: [PATCH] fix(deps): update common, image, and storage deps Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 10 +-- go.sum | 20 ++--- .../containers/image/v5/copy/manifest.go | 82 +++++++++++++------ .../containers/image/v5/copy/single.go | 1 + .../image/v5/internal/manifest/manifest.go | 26 +++++- .../image/v5/manifest/docker_schema1.go | 15 ++++ .../containers/image/v5/manifest/manifest.go | 2 +- .../image/v5/oci/archive/oci_dest.go | 8 +- .../containers/storage/pkg/archive/archive.go | 4 + .../storage/pkg/chunked/cache_linux.go | 16 +++- vendor/github.com/containers/storage/store.go | 5 ++ vendor/modules.txt | 10 +-- 12 files changed, 151 insertions(+), 48 deletions(-) diff --git a/go.mod b/go.mod index c9b1d5f2ec..9a65b76177 100644 --- a/go.mod +++ b/go.mod @@ -12,14 +12,14 @@ require ( github.com/containernetworking/cni v1.1.2 github.com/containernetworking/plugins v1.3.0 github.com/containers/buildah v1.33.2-0.20231121195905-d1a1c53c8e1c - github.com/containers/common v0.57.1-0.20231129142626-3b9abaa8806f + github.com/containers/common v0.57.1-0.20231130092720-630c929caef9 github.com/containers/conmon v2.0.20+incompatible github.com/containers/gvisor-tap-vsock v0.7.1 - github.com/containers/image/v5 v5.29.1-0.20231120202631-293b00ba7166 + github.com/containers/image/v5 v5.29.1-0.20231130112833-c43036d4fc96 github.com/containers/libhvee v0.5.0 github.com/containers/ocicrypt v1.1.9 github.com/containers/psgo v1.8.0 - github.com/containers/storage v1.51.1-0.20231120144510-2cf61989a5bc + github.com/containers/storage v1.51.1-0.20231129190156-7d0a0a320f8a github.com/coreos/go-systemd/v22 v22.5.1-0.20231103132048-7d375ecc2b09 github.com/coreos/stream-metadata-go v0.4.3 github.com/crc-org/vfkit v0.5.0 @@ -93,7 +93,7 @@ require ( github.com/chenzhuoyu/iasm v0.9.0 // indirect github.com/chzyer/readline v1.5.1 // indirect github.com/containerd/cgroups/v3 v3.0.2 // indirect - github.com/containerd/containerd v1.7.9 // indirect + github.com/containerd/containerd v1.7.10 // indirect github.com/containerd/log v0.1.0 // indirect github.com/containerd/stargz-snapshotter/estargz v0.15.1 // indirect github.com/containerd/typeurl/v2 v2.1.1 // indirect @@ -206,7 +206,7 @@ require ( golang.org/x/arch v0.5.0 // indirect golang.org/x/crypto v0.16.0 // indirect golang.org/x/mod v0.13.0 // indirect - golang.org/x/oauth2 v0.14.0 // indirect + golang.org/x/oauth2 v0.15.0 // indirect golang.org/x/tools v0.14.0 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 // indirect diff --git a/go.sum b/go.sum index 41a1439360..95df02f6df 100644 --- a/go.sum +++ b/go.sum @@ -193,8 +193,8 @@ github.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09Zvgq github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s= github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g= github.com/containerd/containerd v1.5.7/go.mod h1:gyvv6+ugqY25TiXxcZC3L5yOeYgEw0QMhscqVp1AR9c= -github.com/containerd/containerd v1.7.9 h1:KOhK01szQbM80YfW1H6RZKh85PHGqY/9OcEZ35Je8sc= -github.com/containerd/containerd v1.7.9/go.mod h1:0/W44LWEYfSHoxBtsHIiNU/duEkgpMokemafHVCpq9Y= +github.com/containerd/containerd v1.7.10 h1:2nfZyT8BV0C3iKu/SsGxKVAf9dp5W7l9nA8JmWmDGuo= +github.com/containerd/containerd v1.7.10/go.mod h1:0/W44LWEYfSHoxBtsHIiNU/duEkgpMokemafHVCpq9Y= github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= @@ -256,14 +256,14 @@ github.com/containernetworking/plugins v1.3.0 h1:QVNXMT6XloyMUoO2wUOqWTC1hWFV62Q github.com/containernetworking/plugins v1.3.0/go.mod h1:Pc2wcedTQQCVuROOOaLBPPxrEXqqXBFt3cZ+/yVg6l0= github.com/containers/buildah v1.33.2-0.20231121195905-d1a1c53c8e1c h1:E7nxvH3N3kpyson0waJv1X+eY9hAs+x2zQswsK+//yY= github.com/containers/buildah v1.33.2-0.20231121195905-d1a1c53c8e1c/go.mod h1:oMNfVrZGEfWVOxXTNOYPMdZzDfSo2umURK/TO0d8TRk= -github.com/containers/common v0.57.1-0.20231129142626-3b9abaa8806f h1:palKvEWcNCW+mhh4hmOI/IpFthhnVwoRGOTlbTDpqE0= -github.com/containers/common v0.57.1-0.20231129142626-3b9abaa8806f/go.mod h1:FlJBjxfbI9s1o7VROe/2fiN8kvgO29/qa3dPDCaX3og= +github.com/containers/common v0.57.1-0.20231130092720-630c929caef9 h1:56pMgYcYyhTlmPPhRmG34NBmT5S/IwMMmOq0o4LJAMo= +github.com/containers/common v0.57.1-0.20231130092720-630c929caef9/go.mod h1:1TyelTjZvU4ZVSq6tGl0ImFlMKIbE8QkzpACQCdcs4U= github.com/containers/conmon v2.0.20+incompatible h1:YbCVSFSCqFjjVwHTPINGdMX1F6JXHGTUje2ZYobNrkg= github.com/containers/conmon v2.0.20+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I= github.com/containers/gvisor-tap-vsock v0.7.1 h1:+Rc+sOPplrkQb/BUXeN0ug8TxjgyrIqo/9P/eNS2A4c= github.com/containers/gvisor-tap-vsock v0.7.1/go.mod h1:WSSsjcuYZkvP8i0J+Ht3LF8yvysn3krD5zxQ74wz7y0= -github.com/containers/image/v5 v5.29.1-0.20231120202631-293b00ba7166 h1:Dz4ryT8VDKn6U+oWPtsihAV2eG7uFc+LYS7UjHjLcwk= -github.com/containers/image/v5 v5.29.1-0.20231120202631-293b00ba7166/go.mod h1:0uOgAiVgmF8+VCXltRYmncWjkDYc+jFma49NKNz0cS4= +github.com/containers/image/v5 v5.29.1-0.20231130112833-c43036d4fc96 h1:NeakBfEUoMzlCK1t1xkigEu/p4luDhfPtVLdrlhVhkA= +github.com/containers/image/v5 v5.29.1-0.20231130112833-c43036d4fc96/go.mod h1:viinaAODpZKsuvRIecjkmgV890VxszevaGiH+m8Qcug= github.com/containers/libhvee v0.5.0 h1:rDhfG2NI8Q+VgeXht2dXezanxEdpj9pHqYX3vWfOGUw= github.com/containers/libhvee v0.5.0/go.mod h1:yvU3Em2u1ZLl2VLd2glMIBWriBwfhWsDaRJsvixUIB0= github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 h1:Qzk5C6cYglewc+UyGf6lc8Mj2UaPTHy/iF2De0/77CA= @@ -278,8 +278,8 @@ github.com/containers/ocicrypt v1.1.9/go.mod h1:dTKx1918d8TDkxXvarscpNVY+lyPakPN github.com/containers/psgo v1.8.0 h1:2loGekmGAxM9ir5OsXWEfGwFxorMPYnc6gEDsGFQvhY= github.com/containers/psgo v1.8.0/go.mod h1:T8ZxnX3Ur4RvnhxFJ7t8xJ1F48RhiZB4rSrOaR/qGHc= github.com/containers/storage v1.43.0/go.mod h1:uZ147thiIFGdVTjMmIw19knttQnUCl3y9zjreHrg11s= -github.com/containers/storage v1.51.1-0.20231120144510-2cf61989a5bc h1:K+fKkKkqwwY3YYM+RejJ6OcbCRZfDRZLoKsMMBAT2Bw= -github.com/containers/storage v1.51.1-0.20231120144510-2cf61989a5bc/go.mod h1:oz9n9uia9xtxDQhw7nnlpMID5YKbHmMZsVFy4rR+5+s= +github.com/containers/storage v1.51.1-0.20231129190156-7d0a0a320f8a h1:YuHrRNrIAZ+b1yTzoTdNiAEBNqhBmnakrVxfXcH8SC8= +github.com/containers/storage v1.51.1-0.20231129190156-7d0a0a320f8a/go.mod h1:FHXkEBvKRmsTeB1JQIFfXnSyXCp+wVrt172O2ZlSzM4= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= @@ -1271,8 +1271,8 @@ golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.14.0 h1:P0Vrf/2538nmC0H+pEQ3MNFRRnVR7RlqyVw+bvm26z0= -golang.org/x/oauth2 v0.14.0/go.mod h1:lAtNWgaWfL4cm7j2OV8TxGi9Qb7ECORx8DktCY74OwM= +golang.org/x/oauth2 v0.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ= +golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= diff --git a/vendor/github.com/containers/image/v5/copy/manifest.go b/vendor/github.com/containers/image/v5/copy/manifest.go index 6f01cf5cc3..8844ac8e7e 100644 --- a/vendor/github.com/containers/image/v5/copy/manifest.go +++ b/vendor/github.com/containers/image/v5/copy/manifest.go @@ -6,8 +6,10 @@ import ( "fmt" "strings" + internalManifest "github.com/containers/image/v5/internal/manifest" "github.com/containers/image/v5/internal/set" "github.com/containers/image/v5/manifest" + compressiontypes "github.com/containers/image/v5/pkg/compression/types" "github.com/containers/image/v5/types" v1 "github.com/opencontainers/image-spec/specs-go/v1" "github.com/sirupsen/logrus" @@ -19,8 +21,8 @@ import ( // Include v2s1 signed but not v2s1 unsigned, because docker/distribution requires a signature even if the unsigned MIME type is used. var preferredManifestMIMETypes = []string{manifest.DockerV2Schema2MediaType, manifest.DockerV2Schema1SignedMediaType} -// ociEncryptionMIMETypes lists manifest MIME types that are known to support OCI encryption. -var ociEncryptionMIMETypes = []string{v1.MediaTypeImageManifest} +// allManifestMIMETypes lists all possible manifest MIME types. +var allManifestMIMETypes = []string{v1.MediaTypeImageManifest, manifest.DockerV2Schema2MediaType, manifest.DockerV2Schema1SignedMediaType, manifest.DockerV2Schema1MediaType} // orderedSet is a list of strings (MIME types or platform descriptors in our case), with each string appearing at most once. type orderedSet struct { @@ -51,9 +53,10 @@ type determineManifestConversionInputs struct { destSupportedManifestMIMETypes []string // MIME types supported by the destination, per types.ImageDestination.SupportedManifestMIMETypes() - forceManifestMIMEType string // User’s choice of forced manifest MIME type - requiresOCIEncryption bool // Restrict to manifest formats that can support OCI encryption - cannotModifyManifestReason string // The reason the manifest cannot be modified, or an empty string if it can + forceManifestMIMEType string // User’s choice of forced manifest MIME type + requestedCompressionFormat *compressiontypes.Algorithm // Compression algorithm to use, if the user _explictily_ requested one. + requiresOCIEncryption bool // Restrict to manifest formats that can support OCI encryption + cannotModifyManifestReason string // The reason the manifest cannot be modified, or an empty string if it can } // manifestConversionPlan contains the decisions made by determineManifestConversion. @@ -80,41 +83,74 @@ func determineManifestConversion(in determineManifestConversionInputs) (manifest destSupportedManifestMIMETypes = []string{in.forceManifestMIMEType} } + restrictiveCompressionRequired := in.requestedCompressionFormat != nil && !internalManifest.CompressionAlgorithmIsUniversallySupported(*in.requestedCompressionFormat) if len(destSupportedManifestMIMETypes) == 0 { - if !in.requiresOCIEncryption || manifest.MIMETypeSupportsEncryption(srcType) { + if (!in.requiresOCIEncryption || manifest.MIMETypeSupportsEncryption(srcType)) && + (!restrictiveCompressionRequired || internalManifest.MIMETypeSupportsCompressionAlgorithm(srcType, *in.requestedCompressionFormat)) { return manifestConversionPlan{ // Anything goes; just use the original as is, do not try any conversions. preferredMIMEType: srcType, otherMIMETypeCandidates: []string{}, }, nil } - destSupportedManifestMIMETypes = ociEncryptionMIMETypes + destSupportedManifestMIMETypes = allManifestMIMETypes } supportedByDest := set.New[string]() for _, t := range destSupportedManifestMIMETypes { - if !in.requiresOCIEncryption || manifest.MIMETypeSupportsEncryption(t) { - supportedByDest.Add(t) + if in.requiresOCIEncryption && !manifest.MIMETypeSupportsEncryption(t) { + continue } + if restrictiveCompressionRequired && !internalManifest.MIMETypeSupportsCompressionAlgorithm(t, *in.requestedCompressionFormat) { + continue + } + supportedByDest.Add(t) } if supportedByDest.Empty() { - if len(destSupportedManifestMIMETypes) == 0 { // Coverage: This should never happen, empty values were replaced by ociEncryptionMIMETypes + if len(destSupportedManifestMIMETypes) == 0 { // Coverage: This should never happen, empty values were replaced by allManifestMIMETypes return manifestConversionPlan{}, errors.New("internal error: destSupportedManifestMIMETypes is empty") } - // We know, and have verified, that destSupportedManifestMIMETypes is not empty, so encryption must have been involved. - if !in.requiresOCIEncryption { // Coverage: This should never happen, destSupportedManifestMIMETypes was not empty, so we should have filtered for encryption. - return manifestConversionPlan{}, errors.New("internal error: supportedByDest is empty but destSupportedManifestMIMETypes is not, and not encrypting") - } + // We know, and have verified, that destSupportedManifestMIMETypes is not empty, so some filtering of supported MIME types must have been involved. + // destSupportedManifestMIMETypes has three possible origins: if in.forceManifestMIMEType != "" { // 1. forceManifestType specified - return manifestConversionPlan{}, fmt.Errorf("encryption required together with format %s, which does not support encryption", - in.forceManifestMIMEType) + switch { + case in.requiresOCIEncryption && restrictiveCompressionRequired: + return manifestConversionPlan{}, fmt.Errorf("compression using %s, and encryption, required together with format %s, which does not support both", + in.requestedCompressionFormat.Name(), in.forceManifestMIMEType) + case in.requiresOCIEncryption: + return manifestConversionPlan{}, fmt.Errorf("encryption required together with format %s, which does not support encryption", + in.forceManifestMIMEType) + case restrictiveCompressionRequired: + return manifestConversionPlan{}, fmt.Errorf("compression using %s required together with format %s, which does not support it", + in.requestedCompressionFormat.Name(), in.forceManifestMIMEType) + default: + return manifestConversionPlan{}, errors.New("internal error: forceManifestMIMEType was rejected for an unknown reason") + } + } + if len(in.destSupportedManifestMIMETypes) == 0 { // 2. destination accepts anything and we have chosen allManifestTypes + if !restrictiveCompressionRequired { + // Coverage: This should never happen. + // If we have not rejected for encryption reasons, we must have rejected due to encryption, but + // allManifestTypes includes OCI, which supports encryption. + return manifestConversionPlan{}, errors.New("internal error: in.destSupportedManifestMIMETypes is empty but supportedByDest is empty as well") + } + // This can legitimately happen when the user asks for completely unsupported formats like Bzip2 or Xz. + return manifestConversionPlan{}, fmt.Errorf("compression using %s required, but none of the known manifest formats support it", in.requestedCompressionFormat.Name()) } - if len(in.destSupportedManifestMIMETypes) == 0 { // 2. destination accepts anything and we have chosen ociEncryptionMIMETypes - // Coverage: This should never happen, ociEncryptionMIMETypes all support encryption - return manifestConversionPlan{}, errors.New("internal error: in.destSupportedManifestMIMETypes is empty but supportedByDest is empty as well") + // 3. destination accepts a restricted list of mime types + destMIMEList := strings.Join(destSupportedManifestMIMETypes, ", ") + switch { + case in.requiresOCIEncryption && restrictiveCompressionRequired: + return manifestConversionPlan{}, fmt.Errorf("compression using %s, and encryption, required but the destination only supports MIME types [%s], none of which support both", + in.requestedCompressionFormat.Name(), destMIMEList) + case in.requiresOCIEncryption: + return manifestConversionPlan{}, fmt.Errorf("encryption required but the destination only supports MIME types [%s], none of which support encryption", + destMIMEList) + case restrictiveCompressionRequired: + return manifestConversionPlan{}, fmt.Errorf("compression using %s required but the destination only supports MIME types [%s], none of which support it", + in.requestedCompressionFormat.Name(), destMIMEList) + default: // Coverage: This should never happen, we only filter for in.requiresOCIEncryption || restrictiveCompressionRequired + return manifestConversionPlan{}, errors.New("internal error: supportedByDest is empty but destSupportedManifestMIMETypes is not, and we are neither encrypting nor requiring a restrictive compression algorithm") } - // 3. destination does not support encryption. - return manifestConversionPlan{}, fmt.Errorf("encryption required but the destination only supports MIME types [%s], none of which support encryption", - strings.Join(destSupportedManifestMIMETypes, ", ")) } // destSupportedManifestMIMETypes is a static guess; a particular registry may still only support a subset of the types. @@ -156,7 +192,7 @@ func determineManifestConversion(in determineManifestConversionInputs) (manifest } logrus.Debugf("Manifest has MIME type %s, ordered candidate list [%s]", srcType, strings.Join(prioritizedTypes.list, ", ")) - if len(prioritizedTypes.list) == 0 { // Coverage: destSupportedManifestMIMETypes and supportedByDest, which is a subset, is not empty (or we would have exited above), so this should never happen. + if len(prioritizedTypes.list) == 0 { // Coverage: destSupportedManifestMIMETypes and supportedByDest, which is a subset, is not empty (or we would have exited above), so this should never happen. return manifestConversionPlan{}, errors.New("Internal error: no candidate MIME types") } res := manifestConversionPlan{ diff --git a/vendor/github.com/containers/image/v5/copy/single.go b/vendor/github.com/containers/image/v5/copy/single.go index 67ca43f7bc..b9ea05970c 100644 --- a/vendor/github.com/containers/image/v5/copy/single.go +++ b/vendor/github.com/containers/image/v5/copy/single.go @@ -167,6 +167,7 @@ func (c *copier) copySingleImage(ctx context.Context, unparsedImage *image.Unpar srcMIMEType: ic.src.ManifestMIMEType, destSupportedManifestMIMETypes: ic.c.dest.SupportedManifestMIMETypes(), forceManifestMIMEType: c.options.ForceManifestMIMEType, + requestedCompressionFormat: ic.compressionFormat, requiresOCIEncryption: destRequiresOciEncryption, cannotModifyManifestReason: ic.cannotModifyManifestReason, }) diff --git a/vendor/github.com/containers/image/v5/internal/manifest/manifest.go b/vendor/github.com/containers/image/v5/internal/manifest/manifest.go index 1dbcc14182..6f7bc8bbe6 100644 --- a/vendor/github.com/containers/image/v5/internal/manifest/manifest.go +++ b/vendor/github.com/containers/image/v5/internal/manifest/manifest.go @@ -3,6 +3,7 @@ package manifest import ( "encoding/json" + compressiontypes "github.com/containers/image/v5/pkg/compression/types" "github.com/containers/libtrust" digest "github.com/opencontainers/go-digest" imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1" @@ -14,7 +15,7 @@ import ( const ( // DockerV2Schema1MediaType MIME type represents Docker manifest schema 1 DockerV2Schema1MediaType = "application/vnd.docker.distribution.manifest.v1+json" - // DockerV2Schema1MediaType MIME type represents Docker manifest schema 1 with a JWS signature + // DockerV2Schema1SignedMediaType MIME type represents Docker manifest schema 1 with a JWS signature DockerV2Schema1SignedMediaType = "application/vnd.docker.distribution.manifest.v1+prettyjws" // DockerV2Schema2MediaType MIME type represents Docker manifest schema 2 DockerV2Schema2MediaType = "application/vnd.docker.distribution.manifest.v2+json" @@ -165,3 +166,26 @@ func NormalizedMIMEType(input string) string { return DockerV2Schema1SignedMediaType } } + +// CompressionAlgorithmIsUniversallySupported returns true if MIMETypeSupportsCompressionAlgorithm(mimeType, algo) returns true for all mimeType values. +func CompressionAlgorithmIsUniversallySupported(algo compressiontypes.Algorithm) bool { + switch algo.Name() { // Should this use InternalUnstableUndocumentedMIMEQuestionMark() ? + case compressiontypes.GzipAlgorithmName: + return true + default: + return false + } +} + +// MIMETypeSupportsCompressionAlgorithm returns true if mimeType can represent algo. +func MIMETypeSupportsCompressionAlgorithm(mimeType string, algo compressiontypes.Algorithm) bool { + if CompressionAlgorithmIsUniversallySupported(algo) { + return true + } + switch algo.Name() { // Should this use InternalUnstableUndocumentedMIMEQuestionMark() ? + case compressiontypes.ZstdAlgorithmName, compressiontypes.ZstdChunkedAlgorithmName: + return mimeType == imgspecv1.MediaTypeImageManifest + default: // Includes Bzip2AlgorithmName and XzAlgorithmName, which are defined names but are not supported anywhere + return false + } +} diff --git a/vendor/github.com/containers/image/v5/manifest/docker_schema1.go b/vendor/github.com/containers/image/v5/manifest/docker_schema1.go index a80af701af..762815570c 100644 --- a/vendor/github.com/containers/image/v5/manifest/docker_schema1.go +++ b/vendor/github.com/containers/image/v5/manifest/docker_schema1.go @@ -10,6 +10,7 @@ import ( "github.com/containers/image/v5/docker/reference" "github.com/containers/image/v5/internal/manifest" "github.com/containers/image/v5/internal/set" + compressiontypes "github.com/containers/image/v5/pkg/compression/types" "github.com/containers/image/v5/types" "github.com/containers/storage/pkg/regexp" "github.com/docker/docker/api/types/versions" @@ -142,6 +143,15 @@ func (m *Schema1) LayerInfos() []LayerInfo { return layers } +const fakeSchema1MIMEType = DockerV2Schema2LayerMediaType // Used only in schema1CompressionMIMETypeSets +var schema1CompressionMIMETypeSets = []compressionMIMETypeSet{ + { + mtsUncompressed: fakeSchema1MIMEType, + compressiontypes.GzipAlgorithmName: fakeSchema1MIMEType, + compressiontypes.ZstdAlgorithmName: mtsUnsupportedMIMEType, + }, +} + // UpdateLayerInfos replaces the original layers with the specified BlobInfos (size+digest+urls), in order (the root layer first, and then successive layered layers) func (m *Schema1) UpdateLayerInfos(layerInfos []types.BlobInfo) error { // Our LayerInfos includes empty layers (where m.ExtractedV1Compatibility[].ThrowAway), so expect them to be included here as well. @@ -150,6 +160,11 @@ func (m *Schema1) UpdateLayerInfos(layerInfos []types.BlobInfo) error { } m.FSLayers = make([]Schema1FSLayers, len(layerInfos)) for i, info := range layerInfos { + // There are no MIME types in schema1, but we do a “conversion” here to reject unsupported compression algorithms, + // in a way that is consistent with the other schema implementations. + if _, err := updatedMIMEType(schema1CompressionMIMETypeSets, fakeSchema1MIMEType, info); err != nil { + return fmt.Errorf("preparing updated manifest, layer %q: %w", info.Digest, err) + } // (docker push) sets up m.ExtractedV1Compatibility[].{Id,Parent} based on values of info.Digest, // but (docker pull) ignores them in favor of computing DiffIDs from uncompressed data, except verifying the child->parent links and uniqueness. // So, we don't bother recomputing the IDs in m.History.V1Compatibility. diff --git a/vendor/github.com/containers/image/v5/manifest/manifest.go b/vendor/github.com/containers/image/v5/manifest/manifest.go index 959aac935e..828b8da0b7 100644 --- a/vendor/github.com/containers/image/v5/manifest/manifest.go +++ b/vendor/github.com/containers/image/v5/manifest/manifest.go @@ -16,7 +16,7 @@ import ( const ( // DockerV2Schema1MediaType MIME type represents Docker manifest schema 1 DockerV2Schema1MediaType = manifest.DockerV2Schema1MediaType - // DockerV2Schema1MediaType MIME type represents Docker manifest schema 1 with a JWS signature + // DockerV2Schema1SignedMediaType MIME type represents Docker manifest schema 1 with a JWS signature DockerV2Schema1SignedMediaType = manifest.DockerV2Schema1SignedMediaType // DockerV2Schema2MediaType MIME type represents Docker manifest schema 2 DockerV2Schema2MediaType = manifest.DockerV2Schema2MediaType diff --git a/vendor/github.com/containers/image/v5/oci/archive/oci_dest.go b/vendor/github.com/containers/image/v5/oci/archive/oci_dest.go index 8386c47a3f..6ca618e351 100644 --- a/vendor/github.com/containers/image/v5/oci/archive/oci_dest.go +++ b/vendor/github.com/containers/image/v5/oci/archive/oci_dest.go @@ -13,6 +13,7 @@ import ( "github.com/containers/image/v5/internal/signature" "github.com/containers/image/v5/types" "github.com/containers/storage/pkg/archive" + "github.com/containers/storage/pkg/idtools" digest "github.com/opencontainers/go-digest" "github.com/sirupsen/logrus" ) @@ -169,10 +170,15 @@ func (d *ociArchiveImageDestination) Commit(ctx context.Context, unparsedTopleve // tar converts the directory at src and saves it to dst func tarDirectory(src, dst string) error { // input is a stream of bytes from the archive of the directory at path - input, err := archive.Tar(src, archive.Uncompressed) + input, err := archive.TarWithOptions(src, &archive.TarOptions{ + Compression: archive.Uncompressed, + // Don’t include the data about the user account this code is running under. + ChownOpts: &idtools.IDPair{UID: 0, GID: 0}, + }) if err != nil { return fmt.Errorf("retrieving stream of bytes from %q: %w", src, err) } + defer input.Close() // creates the tar file outFile, err := os.Create(dst) diff --git a/vendor/github.com/containers/storage/pkg/archive/archive.go b/vendor/github.com/containers/storage/pkg/archive/archive.go index 05d2571182..85c91690d0 100644 --- a/vendor/github.com/containers/storage/pkg/archive/archive.go +++ b/vendor/github.com/containers/storage/pkg/archive/archive.go @@ -534,6 +534,10 @@ func (ta *tarAppender) addTarFile(path, name string) error { if ta.ChownOpts != nil { hdr.Uid = ta.ChownOpts.UID hdr.Gid = ta.ChownOpts.GID + // Don’t expose the user names from the local system; they probably don’t match the ta.ChownOpts value anyway, + // and they unnecessarily give recipients of the tar file potentially private data. + hdr.Uname = "" + hdr.Gname = "" } maybeTruncateHeaderModTime(hdr) diff --git a/vendor/github.com/containers/storage/pkg/chunked/cache_linux.go b/vendor/github.com/containers/storage/pkg/chunked/cache_linux.go index 5d4befc234..aa4f57e6fb 100644 --- a/vendor/github.com/containers/storage/pkg/chunked/cache_linux.go +++ b/vendor/github.com/containers/storage/pkg/chunked/cache_linux.go @@ -578,7 +578,10 @@ func unmarshalToc(manifest []byte) (*internal.TOC, error) { return byteSliceAsString(buf.Bytes()[from:to]) } - iter = jsoniter.ParseBytes(jsoniter.ConfigFastest, manifest) + pool := iter.Pool() + pool.ReturnIterator(iter) + iter = pool.BorrowIterator(manifest) + for field := iter.ReadObject(); field != ""; field = iter.ReadObject() { if strings.ToLower(field) == "version" { toc.Version = iter.ReadInt() @@ -657,8 +660,17 @@ func unmarshalToc(manifest []byte) (*internal.TOC, error) { } toc.Entries = append(toc.Entries, m) } - break } + + // validate there is no extra data in the provided input. This is a security measure to avoid + // that the digest we calculate for the TOC refers to the entire document. + if iter.Error != nil && iter.Error != io.EOF { + return nil, iter.Error + } + if iter.WhatIsNext() != jsoniter.InvalidValue || !errors.Is(iter.Error, io.EOF) { + return nil, fmt.Errorf("unexpected data after manifest") + } + toc.StringsBuf = buf return &toc, nil } diff --git a/vendor/github.com/containers/storage/store.go b/vendor/github.com/containers/storage/store.go index 41f3a9e9b2..62a9c9ea1b 100644 --- a/vendor/github.com/containers/storage/store.go +++ b/vendor/github.com/containers/storage/store.go @@ -11,6 +11,7 @@ import ( "reflect" "strings" "sync" + "syscall" "time" // register all of the built-in drivers @@ -961,6 +962,10 @@ func (s *store) load() error { } else { ris, err = newROImageStore(gipath) if err != nil { + if errors.Is(err, syscall.EROFS) { + logrus.Debugf("Ignoring creation of lockfiles on read-only file systems %q, %v", gipath, err) + continue + } return err } } diff --git a/vendor/modules.txt b/vendor/modules.txt index 652b100c64..e4bb48dcde 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -107,7 +107,7 @@ github.com/chzyer/readline # github.com/containerd/cgroups/v3 v3.0.2 ## explicit; go 1.18 github.com/containerd/cgroups/v3/cgroup1/stats -# github.com/containerd/containerd v1.7.9 +# github.com/containerd/containerd v1.7.10 ## explicit; go 1.19 github.com/containerd/containerd/errdefs github.com/containerd/containerd/log @@ -167,7 +167,7 @@ github.com/containers/buildah/pkg/sshagent github.com/containers/buildah/pkg/util github.com/containers/buildah/pkg/volumes github.com/containers/buildah/util -# github.com/containers/common v0.57.1-0.20231129142626-3b9abaa8806f +# github.com/containers/common v0.57.1-0.20231130092720-630c929caef9 ## explicit; go 1.18 github.com/containers/common/internal/attributedstring github.com/containers/common/libimage @@ -234,7 +234,7 @@ github.com/containers/conmon/runner/config # github.com/containers/gvisor-tap-vsock v0.7.1 ## explicit; go 1.20 github.com/containers/gvisor-tap-vsock/pkg/types -# github.com/containers/image/v5 v5.29.1-0.20231120202631-293b00ba7166 +# github.com/containers/image/v5 v5.29.1-0.20231130112833-c43036d4fc96 ## explicit; go 1.19 github.com/containers/image/v5/copy github.com/containers/image/v5/directory @@ -344,7 +344,7 @@ github.com/containers/psgo/internal/dev github.com/containers/psgo/internal/host github.com/containers/psgo/internal/proc github.com/containers/psgo/internal/process -# github.com/containers/storage v1.51.1-0.20231120144510-2cf61989a5bc +# github.com/containers/storage v1.51.1-0.20231129190156-7d0a0a320f8a ## explicit; go 1.19 github.com/containers/storage github.com/containers/storage/drivers @@ -1172,7 +1172,7 @@ golang.org/x/net/internal/socks golang.org/x/net/internal/timeseries golang.org/x/net/proxy golang.org/x/net/trace -# golang.org/x/oauth2 v0.14.0 +# golang.org/x/oauth2 v0.15.0 ## explicit; go 1.18 golang.org/x/oauth2 golang.org/x/oauth2/internal