From b16222452c1a27a1b2c1ef42e1164037ccfb76cd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 May 2024 21:10:15 +0000 Subject: [PATCH] Bump github.com/containers/podman/v5 from 5.0.2 to 5.0.3 Bumps [github.com/containers/podman/v5](https://github.com/containers/podman) from 5.0.2 to 5.0.3. - [Release notes](https://github.com/containers/podman/releases) - [Changelog](https://github.com/containers/podman/blob/v5.0.3/RELEASE_NOTES.md) - [Commits](https://github.com/containers/podman/compare/v5.0.2...v5.0.3) --- updated-dependencies: - dependency-name: github.com/containers/podman/v5 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- go.mod | 10 +- go.sum | 20 ++-- .../containers/buildah/CHANGELOG.md | 7 ++ .../containers/buildah/changelog.txt | 6 ++ .../containers/buildah/define/types.go | 2 +- .../containers/common/version/version.go | 2 +- .../containers/image/v5/copy/progress_bars.go | 7 +- .../containers/image/v5/copy/single.go | 39 ++++++-- .../image/v5/directory/directory_dest.go | 22 ++++- .../image/v5/directory/directory_src.go | 17 +++- .../image/v5/directory/directory_transport.go | 25 +++-- .../image/v5/docker/docker_client.go | 20 +++- .../image/v5/docker/docker_image.go | 7 +- .../image/v5/docker/docker_image_dest.go | 22 ++++- .../image/v5/docker/docker_image_src.go | 18 +++- .../image/v5/docker/internal/tarfile/dest.go | 12 ++- .../v5/docker/internal/tarfile/writer.go | 34 +++++-- .../image/v5/docker/registries_d.go | 7 +- .../image/v5/openshift/openshift_src.go | 3 + .../containers/image/v5/ostree/ostree_dest.go | 10 ++ .../containers/image/v5/ostree/ostree_src.go | 4 +- .../image/v5/pkg/blobcache/blobcache.go | 12 ++- .../containers/image/v5/pkg/blobcache/dest.go | 93 +++++++++++-------- .../containers/image/v5/pkg/blobcache/src.go | 16 +++- .../image/v5/storage/storage_dest.go | 42 ++++++--- .../image/v5/storage/storage_image.go | 14 ++- .../image/v5/storage/storage_reference.go | 10 +- .../image/v5/storage/storage_src.go | 19 +++- .../containers/image/v5/version/version.go | 2 +- .../ocicrypt/keywrap/jwe/keywrapper_jwe.go | 17 +++- .../containers/ocicrypt/utils/testing.go | 13 ++- .../podman/v5/version/rawversion/version.go | 2 +- vendor/modules.txt | 10 +- 33 files changed, 399 insertions(+), 145 deletions(-) diff --git a/go.mod b/go.mod index 2064a27b4..32b4f982d 100644 --- a/go.mod +++ b/go.mod @@ -3,9 +3,9 @@ module github.com/containers/prometheus-podman-exporter go 1.20 require ( - github.com/containers/common v0.58.2 - github.com/containers/image/v5 v5.30.0 - github.com/containers/podman/v5 v5.0.2 + github.com/containers/common v0.58.3 + github.com/containers/image/v5 v5.30.1 + github.com/containers/podman/v5 v5.0.3 github.com/go-kit/log v0.2.1 github.com/onsi/ginkgo/v2 v2.17.2 github.com/onsi/gomega v1.33.1 @@ -41,11 +41,11 @@ require ( github.com/containerd/typeurl/v2 v2.1.1 // indirect github.com/containernetworking/cni v1.1.2 // indirect github.com/containernetworking/plugins v1.4.0 // indirect - github.com/containers/buildah v1.35.3 // indirect + github.com/containers/buildah v1.35.4 // indirect github.com/containers/conmon v2.0.20+incompatible // indirect github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 // indirect github.com/containers/luksy v0.0.0-20240212203526-ceb12d4fd50c // indirect - github.com/containers/ocicrypt v1.1.9 // indirect + github.com/containers/ocicrypt v1.1.10 // indirect github.com/containers/psgo v1.9.0 // indirect github.com/containers/storage v1.53.0 // indirect github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f // indirect diff --git a/go.sum b/go.sum index c9c8fe174..ec05b8317 100644 --- a/go.sum +++ b/go.sum @@ -62,22 +62,22 @@ github.com/containernetworking/cni v1.1.2 h1:wtRGZVv7olUHMOqouPpn3cXJWpJgM6+EUl3 github.com/containernetworking/cni v1.1.2/go.mod h1:sDpYKmGVENF3s6uvMvGgldDWeG8dMxakj/u+i9ht9vw= github.com/containernetworking/plugins v1.4.0 h1:+w22VPYgk7nQHw7KT92lsRmuToHvb7wwSv9iTbXzzic= github.com/containernetworking/plugins v1.4.0/go.mod h1:UYhcOyjefnrQvKvmmyEKsUA+M9Nfn7tqULPpH0Pkcj0= -github.com/containers/buildah v1.35.3 h1:Dn8Krwm2PemBNNOMwp7uiMK2e5cW2ZjTdLRzKM789pc= -github.com/containers/buildah v1.35.3/go.mod h1:kYi6vTHdbr1gnRo3B/RhTHsY2if/w398+/RvCxAXqkQ= -github.com/containers/common v0.58.2 h1:5nu9lQz4QNSgovNk7NRk33SkqkVNKYoXh7L6gXmACow= -github.com/containers/common v0.58.2/go.mod h1:l3vMqanJGj7tZ3W/i76gEJ128VXgFUO1tLaohJXPvdk= +github.com/containers/buildah v1.35.4 h1:M/M5RJW07ZIDsngmJDb6bnWxZA2RRFulp0MW7EwPATg= +github.com/containers/buildah v1.35.4/go.mod h1:gh6xe/VXW7TTIDWCRtAvx0/YaNuEJWYabDKrHKj17So= +github.com/containers/common v0.58.3 h1:Iy/CdYjluEK926QT+ejonz7YvoRHazeW7BAiLIkmUQ4= +github.com/containers/common v0.58.3/go.mod h1:p4V1SNk+WOISgp01m+axuqCUxaDP3WSZPPzvnJnS/cQ= 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/image/v5 v5.30.0 h1:CmHeSwI6W2kTRWnUsxATDFY5TEX4b58gPkaQcEyrLIA= -github.com/containers/image/v5 v5.30.0/go.mod h1:gSD8MVOyqBspc0ynLsuiMR9qmt8UQ4jpVImjmK0uXfk= +github.com/containers/image/v5 v5.30.1 h1:AKrQMgOKI1oKx5FW5eoU2xoNyzACajHGx1O3qxobvFM= +github.com/containers/image/v5 v5.30.1/go.mod h1:gSD8MVOyqBspc0ynLsuiMR9qmt8UQ4jpVImjmK0uXfk= github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 h1:Qzk5C6cYglewc+UyGf6lc8Mj2UaPTHy/iF2De0/77CA= github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY= github.com/containers/luksy v0.0.0-20240212203526-ceb12d4fd50c h1:6zalnZZODMOqNZBww9VAM1Mq5EZ3J+S8vYGCo2yg39M= github.com/containers/luksy v0.0.0-20240212203526-ceb12d4fd50c/go.mod h1:A/RMGaYhtzfW6L3whYRU+0GGEFocTYyQBqlWSb2UNEM= -github.com/containers/ocicrypt v1.1.9 h1:2Csfba4jse85Raxk5HIyEk8OwZNjRvfkhEGijOjIdEM= -github.com/containers/ocicrypt v1.1.9/go.mod h1:dTKx1918d8TDkxXvarscpNVY+lyPakPNFN4jwA9GBys= -github.com/containers/podman/v5 v5.0.2 h1:xutkGrVfLZupfqo1pERid1tZ3ivFjDXDRbUK9z4ms80= -github.com/containers/podman/v5 v5.0.2/go.mod h1:g4eTcOHzWWuANV5V6C5ovUxXjSrTxTz9ZWpKdfIYvto= +github.com/containers/ocicrypt v1.1.10 h1:r7UR6o8+lyhkEywetubUUgcKFjOWOaWz8cEBrCPX0ic= +github.com/containers/ocicrypt v1.1.10/go.mod h1:YfzSSr06PTHQwSTUKqDSjish9BeW1E4HUmreluQcMd8= +github.com/containers/podman/v5 v5.0.3 h1:SVJZButvmykHaCLS0+SjEM39J0oanXfWC4fW9LzXnQU= +github.com/containers/podman/v5 v5.0.3/go.mod h1:goPIZj29q+7Z5Teoe8w0QIz5sk+rKdWfEvH30FPPzBg= github.com/containers/psgo v1.9.0 h1:eJ74jzSaCHnWt26OlKZROSyUyRcGDf+gYBdXnxrMW4g= github.com/containers/psgo v1.9.0/go.mod h1:0YoluUm43Mz2UnBIh1P+6V6NWcbpTL5uRtXyOcH0B5A= github.com/containers/storage v1.53.0 h1:VSES3C/u1pxjTJIXvLrSmyP7OBtDky04oGu07UvdTEA= diff --git a/vendor/github.com/containers/buildah/CHANGELOG.md b/vendor/github.com/containers/buildah/CHANGELOG.md index dff879625..4d585b405 100644 --- a/vendor/github.com/containers/buildah/CHANGELOG.md +++ b/vendor/github.com/containers/buildah/CHANGELOG.md @@ -2,6 +2,13 @@ # Changelog +## v1.35.4 (2024-05-09) + + [release-1.35] CVE-2024-3727 updates + integration test: handle new labels in "bud and test --unsetlabel" + [release-1.35] Bump go-jose CVE-2024-28180 + [release-1.35] Bump ocicrypt and go-jose CVE-2024-28180 + ## v1.35.3 (2024-03-28) [release-1.35] Bump c/common to v0.58.1 diff --git a/vendor/github.com/containers/buildah/changelog.txt b/vendor/github.com/containers/buildah/changelog.txt index 0f1b9de3d..8849ac819 100644 --- a/vendor/github.com/containers/buildah/changelog.txt +++ b/vendor/github.com/containers/buildah/changelog.txt @@ -1,3 +1,9 @@ +- Changelog for v1.35.4 (2024-05-09) + * [release-1.35] CVE-2024-3727 updates + * integration test: handle new labels in "bud and test --unsetlabel" + * [release-1.35] Bump go-jose CVE-2024-28180 + * [release-1.35] Bump ocicrypt and go-jose CVE-2024-28180 + - Changelog for v1.35.3 (2024-03-28) * [release-1.35] Bump c/common to v0.58.1 diff --git a/vendor/github.com/containers/buildah/define/types.go b/vendor/github.com/containers/buildah/define/types.go index 017354060..61bd220f1 100644 --- a/vendor/github.com/containers/buildah/define/types.go +++ b/vendor/github.com/containers/buildah/define/types.go @@ -29,7 +29,7 @@ const ( // identify working containers. Package = "buildah" // Version for the Package. Also used by .packit.sh for Packit builds. - Version = "1.35.3" + Version = "1.35.4" // DefaultRuntime if containers.conf fails. DefaultRuntime = "runc" diff --git a/vendor/github.com/containers/common/version/version.go b/vendor/github.com/containers/common/version/version.go index 88a616078..ddf29b94b 100644 --- a/vendor/github.com/containers/common/version/version.go +++ b/vendor/github.com/containers/common/version/version.go @@ -1,4 +1,4 @@ package version // Version is the version of the build. -const Version = "0.58.2" +const Version = "0.58.3" diff --git a/vendor/github.com/containers/image/v5/copy/progress_bars.go b/vendor/github.com/containers/image/v5/copy/progress_bars.go index 3ac93a9d7..1d092dba6 100644 --- a/vendor/github.com/containers/image/v5/copy/progress_bars.go +++ b/vendor/github.com/containers/image/v5/copy/progress_bars.go @@ -49,10 +49,13 @@ type progressBar struct { // As a convention, most users of progress bars should call mark100PercentComplete on full success; // by convention, we don't leave progress bars in partial state when fully done // (even if we copied much less data than anticipated). -func (c *copier) createProgressBar(pool *mpb.Progress, partial bool, info types.BlobInfo, kind string, onComplete string) *progressBar { +func (c *copier) createProgressBar(pool *mpb.Progress, partial bool, info types.BlobInfo, kind string, onComplete string) (*progressBar, error) { // shortDigestLen is the length of the digest used for blobs. const shortDigestLen = 12 + if err := info.Digest.Validate(); err != nil { // digest.Digest.Encoded() panics on failure, so validate explicitly. + return nil, err + } prefix := fmt.Sprintf("Copying %s %s", kind, info.Digest.Encoded()) // Truncate the prefix (chopping of some part of the digest) to make all progress bars aligned in a column. maxPrefixLen := len("Copying blob ") + shortDigestLen @@ -105,7 +108,7 @@ func (c *copier) createProgressBar(pool *mpb.Progress, partial bool, info types. return &progressBar{ Bar: bar, originalSize: info.Size, - } + }, nil } // printCopyInfo prints a "Copying ..." message on the copier if the output is diff --git a/vendor/github.com/containers/image/v5/copy/single.go b/vendor/github.com/containers/image/v5/copy/single.go index e1a43f75e..3ecbe1ef7 100644 --- a/vendor/github.com/containers/image/v5/copy/single.go +++ b/vendor/github.com/containers/image/v5/copy/single.go @@ -606,7 +606,10 @@ func (ic *imageCopier) copyConfig(ctx context.Context, src types.Image) error { destInfo, err := func() (types.BlobInfo, error) { // A scope for defer progressPool := ic.c.newProgressPool() defer progressPool.Wait() - bar := ic.c.createProgressBar(progressPool, false, srcInfo, "config", "done") + bar, err := ic.c.createProgressBar(progressPool, false, srcInfo, "config", "done") + if err != nil { + return types.BlobInfo{}, err + } defer bar.Abort(false) ic.c.printCopyInfo("config", srcInfo) @@ -738,15 +741,21 @@ func (ic *imageCopier) copyLayer(ctx context.Context, srcInfo types.BlobInfo, to } if reused { logrus.Debugf("Skipping blob %s (already present):", srcInfo.Digest) - func() { // A scope for defer + if err := func() error { // A scope for defer label := "skipped: already exists" if reusedBlob.MatchedByTOCDigest { label = "skipped: already exists (found by TOC)" } - bar := ic.c.createProgressBar(pool, false, types.BlobInfo{Digest: reusedBlob.Digest, Size: 0}, "blob", label) + bar, err := ic.c.createProgressBar(pool, false, types.BlobInfo{Digest: reusedBlob.Digest, Size: 0}, "blob", label) + if err != nil { + return err + } defer bar.Abort(false) bar.mark100PercentComplete() - }() + return nil + }(); err != nil { + return types.BlobInfo{}, "", err + } // Throw an event that the layer has been skipped if ic.c.options.Progress != nil && ic.c.options.ProgressInterval > 0 { @@ -765,8 +774,11 @@ func (ic *imageCopier) copyLayer(ctx context.Context, srcInfo types.BlobInfo, to // Attempt a partial only when the source allows to retrieve a blob partially and // the destination has support for it. if canAvoidProcessingCompleteLayer && ic.c.rawSource.SupportsGetBlobAt() && ic.c.dest.SupportsPutBlobPartial() { - if reused, blobInfo := func() (bool, types.BlobInfo) { // A scope for defer - bar := ic.c.createProgressBar(pool, true, srcInfo, "blob", "done") + reused, blobInfo, err := func() (bool, types.BlobInfo, error) { // A scope for defer + bar, err := ic.c.createProgressBar(pool, true, srcInfo, "blob", "done") + if err != nil { + return false, types.BlobInfo{}, err + } hideProgressBar := true defer func() { // Note that this is not the same as defer bar.Abort(hideProgressBar); we need hideProgressBar to be evaluated lazily. bar.Abort(hideProgressBar) @@ -789,18 +801,25 @@ func (ic *imageCopier) copyLayer(ctx context.Context, srcInfo types.BlobInfo, to bar.mark100PercentComplete() hideProgressBar = false logrus.Debugf("Retrieved partial blob %v", srcInfo.Digest) - return true, updatedBlobInfoFromUpload(srcInfo, uploadedBlob) + return true, updatedBlobInfoFromUpload(srcInfo, uploadedBlob), nil } logrus.Debugf("Failed to retrieve partial blob: %v", err) - return false, types.BlobInfo{} - }(); reused { + return false, types.BlobInfo{}, nil + }() + if err != nil { + return types.BlobInfo{}, "", err + } + if reused { return blobInfo, cachedDiffID, nil } } // Fallback: copy the layer, computing the diffID if we need to do so return func() (types.BlobInfo, digest.Digest, error) { // A scope for defer - bar := ic.c.createProgressBar(pool, false, srcInfo, "blob", "done") + bar, err := ic.c.createProgressBar(pool, false, srcInfo, "blob", "done") + if err != nil { + return types.BlobInfo{}, "", err + } defer bar.Abort(false) srcStream, srcBlobSize, err := ic.c.rawSource.GetBlob(ctx, srcInfo, ic.c.blobInfoCache) diff --git a/vendor/github.com/containers/image/v5/directory/directory_dest.go b/vendor/github.com/containers/image/v5/directory/directory_dest.go index 9d9219241..3a8fdf0d8 100644 --- a/vendor/github.com/containers/image/v5/directory/directory_dest.go +++ b/vendor/github.com/containers/image/v5/directory/directory_dest.go @@ -173,7 +173,10 @@ func (d *dirImageDestination) PutBlobWithOptions(ctx context.Context, stream io. } } - blobPath := d.ref.layerPath(blobDigest) + blobPath, err := d.ref.layerPath(blobDigest) + if err != nil { + return private.UploadedBlob{}, err + } // need to explicitly close the file, since a rename won't otherwise not work on Windows blobFile.Close() explicitClosed = true @@ -196,7 +199,10 @@ func (d *dirImageDestination) TryReusingBlobWithOptions(ctx context.Context, inf if info.Digest == "" { return false, private.ReusedBlob{}, fmt.Errorf("Can not check for a blob with unknown digest") } - blobPath := d.ref.layerPath(info.Digest) + blobPath, err := d.ref.layerPath(info.Digest) + if err != nil { + return false, private.ReusedBlob{}, err + } finfo, err := os.Stat(blobPath) if err != nil && os.IsNotExist(err) { return false, private.ReusedBlob{}, nil @@ -216,7 +222,11 @@ func (d *dirImageDestination) TryReusingBlobWithOptions(ctx context.Context, inf // If the destination is in principle available, refuses this manifest type (e.g. it does not recognize the schema), // but may accept a different manifest type, the returned error must be an ManifestTypeRejectedError. func (d *dirImageDestination) PutManifest(ctx context.Context, manifest []byte, instanceDigest *digest.Digest) error { - return os.WriteFile(d.ref.manifestPath(instanceDigest), manifest, 0644) + path, err := d.ref.manifestPath(instanceDigest) + if err != nil { + return err + } + return os.WriteFile(path, manifest, 0644) } // PutSignaturesWithFormat writes a set of signatures to the destination. @@ -229,7 +239,11 @@ func (d *dirImageDestination) PutSignaturesWithFormat(ctx context.Context, signa if err != nil { return err } - if err := os.WriteFile(d.ref.signaturePath(i, instanceDigest), blob, 0644); err != nil { + path, err := d.ref.signaturePath(i, instanceDigest) + if err != nil { + return err + } + if err := os.WriteFile(path, blob, 0644); err != nil { return err } } diff --git a/vendor/github.com/containers/image/v5/directory/directory_src.go b/vendor/github.com/containers/image/v5/directory/directory_src.go index 5fc83bb6f..6d725bcfa 100644 --- a/vendor/github.com/containers/image/v5/directory/directory_src.go +++ b/vendor/github.com/containers/image/v5/directory/directory_src.go @@ -55,7 +55,11 @@ func (s *dirImageSource) Close() error { // If instanceDigest is not nil, it contains a digest of the specific manifest instance to retrieve (when the primary manifest is a manifest list); // this never happens if the primary manifest is not a manifest list (e.g. if the source never returns manifest lists). func (s *dirImageSource) GetManifest(ctx context.Context, instanceDigest *digest.Digest) ([]byte, string, error) { - m, err := os.ReadFile(s.ref.manifestPath(instanceDigest)) + path, err := s.ref.manifestPath(instanceDigest) + if err != nil { + return nil, "", err + } + m, err := os.ReadFile(path) if err != nil { return nil, "", err } @@ -66,7 +70,11 @@ func (s *dirImageSource) GetManifest(ctx context.Context, instanceDigest *digest // The Digest field in BlobInfo is guaranteed to be provided, Size may be -1 and MediaType may be optionally provided. // May update BlobInfoCache, preferably after it knows for certain that a blob truly exists at a specific location. func (s *dirImageSource) GetBlob(ctx context.Context, info types.BlobInfo, cache types.BlobInfoCache) (io.ReadCloser, int64, error) { - r, err := os.Open(s.ref.layerPath(info.Digest)) + path, err := s.ref.layerPath(info.Digest) + if err != nil { + return nil, -1, err + } + r, err := os.Open(path) if err != nil { return nil, -1, err } @@ -84,7 +92,10 @@ func (s *dirImageSource) GetBlob(ctx context.Context, info types.BlobInfo, cache func (s *dirImageSource) GetSignaturesWithFormat(ctx context.Context, instanceDigest *digest.Digest) ([]signature.Signature, error) { signatures := []signature.Signature{} for i := 0; ; i++ { - path := s.ref.signaturePath(i, instanceDigest) + path, err := s.ref.signaturePath(i, instanceDigest) + if err != nil { + return nil, err + } sigBlob, err := os.ReadFile(path) if err != nil { if os.IsNotExist(err) { diff --git a/vendor/github.com/containers/image/v5/directory/directory_transport.go b/vendor/github.com/containers/image/v5/directory/directory_transport.go index 7e3068693..4f7d596b4 100644 --- a/vendor/github.com/containers/image/v5/directory/directory_transport.go +++ b/vendor/github.com/containers/image/v5/directory/directory_transport.go @@ -161,25 +161,34 @@ func (ref dirReference) DeleteImage(ctx context.Context, sys *types.SystemContex } // manifestPath returns a path for the manifest within a directory using our conventions. -func (ref dirReference) manifestPath(instanceDigest *digest.Digest) string { +func (ref dirReference) manifestPath(instanceDigest *digest.Digest) (string, error) { if instanceDigest != nil { - return filepath.Join(ref.path, instanceDigest.Encoded()+".manifest.json") + if err := instanceDigest.Validate(); err != nil { // digest.Digest.Encoded() panics on failure, and could possibly result in a path with ../, so validate explicitly. + return "", err + } + return filepath.Join(ref.path, instanceDigest.Encoded()+".manifest.json"), nil } - return filepath.Join(ref.path, "manifest.json") + return filepath.Join(ref.path, "manifest.json"), nil } // layerPath returns a path for a layer tarball within a directory using our conventions. -func (ref dirReference) layerPath(digest digest.Digest) string { +func (ref dirReference) layerPath(digest digest.Digest) (string, error) { + if err := digest.Validate(); err != nil { // digest.Digest.Encoded() panics on failure, and could possibly result in a path with ../, so validate explicitly. + return "", err + } // FIXME: Should we keep the digest identification? - return filepath.Join(ref.path, digest.Encoded()) + return filepath.Join(ref.path, digest.Encoded()), nil } // signaturePath returns a path for a signature within a directory using our conventions. -func (ref dirReference) signaturePath(index int, instanceDigest *digest.Digest) string { +func (ref dirReference) signaturePath(index int, instanceDigest *digest.Digest) (string, error) { if instanceDigest != nil { - return filepath.Join(ref.path, fmt.Sprintf(instanceDigest.Encoded()+".signature-%d", index+1)) + if err := instanceDigest.Validate(); err != nil { // digest.Digest.Encoded() panics on failure, and could possibly result in a path with ../, so validate explicitly. + return "", err + } + return filepath.Join(ref.path, fmt.Sprintf(instanceDigest.Encoded()+".signature-%d", index+1)), nil } - return filepath.Join(ref.path, fmt.Sprintf("signature-%d", index+1)) + return filepath.Join(ref.path, fmt.Sprintf("signature-%d", index+1)), nil } // versionPath returns a path for the version file within a directory using our conventions. diff --git a/vendor/github.com/containers/image/v5/docker/docker_client.go b/vendor/github.com/containers/image/v5/docker/docker_client.go index a60ec563d..737c778a0 100644 --- a/vendor/github.com/containers/image/v5/docker/docker_client.go +++ b/vendor/github.com/containers/image/v5/docker/docker_client.go @@ -952,6 +952,8 @@ func (c *dockerClient) detectProperties(ctx context.Context) error { return c.detectPropertiesError } +// fetchManifest fetches a manifest for (the repo of ref) + tagOrDigest. +// The caller is responsible for ensuring tagOrDigest uses the expected format. func (c *dockerClient) fetchManifest(ctx context.Context, ref dockerReference, tagOrDigest string) ([]byte, string, error) { path := fmt.Sprintf(manifestPath, reference.Path(ref.ref), tagOrDigest) headers := map[string][]string{ @@ -1035,6 +1037,9 @@ func (c *dockerClient) getBlob(ctx context.Context, ref dockerReference, info ty } } + if err := info.Digest.Validate(); err != nil { // Make sure info.Digest.String() does not contain any unexpected characters + return nil, 0, err + } path := fmt.Sprintf(blobsPath, reference.Path(ref.ref), info.Digest.String()) logrus.Debugf("Downloading %s", path) res, err := c.makeRequest(ctx, http.MethodGet, path, nil, nil, v2Auth, nil) @@ -1098,7 +1103,10 @@ func isManifestUnknownError(err error) bool { // digest in ref. // It returns (nil, nil) if the manifest does not exist. func (c *dockerClient) getSigstoreAttachmentManifest(ctx context.Context, ref dockerReference, digest digest.Digest) (*manifest.OCI1, error) { - tag := sigstoreAttachmentTag(digest) + tag, err := sigstoreAttachmentTag(digest) + if err != nil { + return nil, err + } sigstoreRef, err := reference.WithTag(reference.TrimNamed(ref.ref), tag) if err != nil { return nil, err @@ -1131,6 +1139,9 @@ func (c *dockerClient) getSigstoreAttachmentManifest(ctx context.Context, ref do // getExtensionsSignatures returns signatures from the X-Registry-Supports-Signatures API extension, // using the original data structures. func (c *dockerClient) getExtensionsSignatures(ctx context.Context, ref dockerReference, manifestDigest digest.Digest) (*extensionSignatureList, error) { + if err := manifestDigest.Validate(); err != nil { // Make sure manifestDigest.String() does not contain any unexpected characters + return nil, err + } path := fmt.Sprintf(extensionsSignaturePath, reference.Path(ref.ref), manifestDigest) res, err := c.makeRequest(ctx, http.MethodGet, path, nil, nil, v2Auth, nil) if err != nil { @@ -1154,8 +1165,11 @@ func (c *dockerClient) getExtensionsSignatures(ctx context.Context, ref dockerRe } // sigstoreAttachmentTag returns a sigstore attachment tag for the specified digest. -func sigstoreAttachmentTag(d digest.Digest) string { - return strings.Replace(d.String(), ":", "-", 1) + ".sig" +func sigstoreAttachmentTag(d digest.Digest) (string, error) { + if err := d.Validate(); err != nil { // Make sure d.String() doesn’t contain any unexpected characters + return "", err + } + return strings.Replace(d.String(), ":", "-", 1) + ".sig", nil } // Close removes resources associated with an initialized dockerClient, if any. diff --git a/vendor/github.com/containers/image/v5/docker/docker_image.go b/vendor/github.com/containers/image/v5/docker/docker_image.go index 93160480e..4c80bb2b5 100644 --- a/vendor/github.com/containers/image/v5/docker/docker_image.go +++ b/vendor/github.com/containers/image/v5/docker/docker_image.go @@ -88,7 +88,12 @@ func GetRepositoryTags(ctx context.Context, sys *types.SystemContext, ref types. if err = json.NewDecoder(res.Body).Decode(&tagsHolder); err != nil { return nil, err } - tags = append(tags, tagsHolder.Tags...) + for _, tag := range tagsHolder.Tags { + if _, err := reference.WithTag(dr.ref, tag); err != nil { // Ensure the tag does not contain unexpected values + return nil, fmt.Errorf("registry returned invalid tag %q: %w", tag, err) + } + tags = append(tags, tag) + } link := res.Header.Get("Link") if link == "" { diff --git a/vendor/github.com/containers/image/v5/docker/docker_image_dest.go b/vendor/github.com/containers/image/v5/docker/docker_image_dest.go index 877d11b73..a29150eb7 100644 --- a/vendor/github.com/containers/image/v5/docker/docker_image_dest.go +++ b/vendor/github.com/containers/image/v5/docker/docker_image_dest.go @@ -230,6 +230,9 @@ func (d *dockerImageDestination) PutBlobWithOptions(ctx context.Context, stream // If the destination does not contain the blob, or it is unknown, blobExists ordinarily returns (false, -1, nil); // it returns a non-nil error only on an unexpected failure. func (d *dockerImageDestination) blobExists(ctx context.Context, repo reference.Named, digest digest.Digest, extraScope *authScope) (bool, int64, error) { + if err := digest.Validate(); err != nil { // Make sure digest.String() does not contain any unexpected characters + return false, -1, err + } checkPath := fmt.Sprintf(blobsPath, reference.Path(repo), digest.String()) logrus.Debugf("Checking %s", checkPath) res, err := d.c.makeRequest(ctx, http.MethodHead, checkPath, nil, nil, v2Auth, extraScope) @@ -469,6 +472,7 @@ func (d *dockerImageDestination) PutManifest(ctx context.Context, m []byte, inst // particular instance. refTail = instanceDigest.String() // Double-check that the manifest we've been given matches the digest we've been given. + // This also validates the format of instanceDigest. matches, err := manifest.MatchesDigest(m, *instanceDigest) if err != nil { return fmt.Errorf("digesting manifest in PutManifest: %w", err) @@ -635,11 +639,13 @@ func (d *dockerImageDestination) putSignaturesToLookaside(signatures []signature // NOTE: Keep this in sync with docs/signature-protocols.md! for i, signature := range signatures { - sigURL := lookasideStorageURL(d.c.signatureBase, manifestDigest, i) - err := d.putOneSignature(sigURL, signature) + sigURL, err := lookasideStorageURL(d.c.signatureBase, manifestDigest, i) if err != nil { return err } + if err := d.putOneSignature(sigURL, signature); err != nil { + return err + } } // Remove any other signatures, if present. // We stop at the first missing signature; if a previous deleting loop aborted @@ -647,7 +653,10 @@ func (d *dockerImageDestination) putSignaturesToLookaside(signatures []signature // is enough for dockerImageSource to stop looking for other signatures, so that // is sufficient. for i := len(signatures); ; i++ { - sigURL := lookasideStorageURL(d.c.signatureBase, manifestDigest, i) + sigURL, err := lookasideStorageURL(d.c.signatureBase, manifestDigest, i) + if err != nil { + return err + } missing, err := d.c.deleteOneSignature(sigURL) if err != nil { return err @@ -778,8 +787,12 @@ func (d *dockerImageDestination) putSignaturesToSigstoreAttachments(ctx context. if err != nil { return err } + attachmentTag, err := sigstoreAttachmentTag(manifestDigest) + if err != nil { + return err + } logrus.Debugf("Uploading sigstore attachment manifest") - return d.uploadManifest(ctx, manifestBlob, sigstoreAttachmentTag(manifestDigest)) + return d.uploadManifest(ctx, manifestBlob, attachmentTag) } func layerMatchesSigstoreSignature(layer imgspecv1.Descriptor, mimeType string, @@ -895,6 +908,7 @@ func (d *dockerImageDestination) putSignaturesToAPIExtension(ctx context.Context return err } + // manifestDigest is known to be valid because it was not rejected by getExtensionsSignatures above. path := fmt.Sprintf(extensionsSignaturePath, reference.Path(d.ref.ref), manifestDigest.String()) res, err := d.c.makeRequest(ctx, http.MethodPut, path, nil, bytes.NewReader(body), v2Auth, nil) if err != nil { diff --git a/vendor/github.com/containers/image/v5/docker/docker_image_src.go b/vendor/github.com/containers/image/v5/docker/docker_image_src.go index f9d4d6030..274cd6dd2 100644 --- a/vendor/github.com/containers/image/v5/docker/docker_image_src.go +++ b/vendor/github.com/containers/image/v5/docker/docker_image_src.go @@ -194,6 +194,9 @@ func simplifyContentType(contentType string) string { // this never happens if the primary manifest is not a manifest list (e.g. if the source never returns manifest lists). func (s *dockerImageSource) GetManifest(ctx context.Context, instanceDigest *digest.Digest) ([]byte, string, error) { if instanceDigest != nil { + if err := instanceDigest.Validate(); err != nil { // Make sure instanceDigest.String() does not contain any unexpected characters + return nil, "", err + } return s.fetchManifest(ctx, instanceDigest.String()) } err := s.ensureManifestIsLoaded(ctx) @@ -203,6 +206,8 @@ func (s *dockerImageSource) GetManifest(ctx context.Context, instanceDigest *dig return s.cachedManifest, s.cachedManifestMIMEType, nil } +// fetchManifest fetches a manifest for tagOrDigest. +// The caller is responsible for ensuring tagOrDigest uses the expected format. func (s *dockerImageSource) fetchManifest(ctx context.Context, tagOrDigest string) ([]byte, string, error) { return s.c.fetchManifest(ctx, s.physicalRef, tagOrDigest) } @@ -352,6 +357,9 @@ func (s *dockerImageSource) GetBlobAt(ctx context.Context, info types.BlobInfo, return nil, nil, fmt.Errorf("external URLs not supported with GetBlobAt") } + if err := info.Digest.Validate(); err != nil { // Make sure info.Digest.String() does not contain any unexpected characters + return nil, nil, err + } path := fmt.Sprintf(blobsPath, reference.Path(s.physicalRef.ref), info.Digest.String()) logrus.Debugf("Downloading %s", path) res, err := s.c.makeRequest(ctx, http.MethodGet, path, headers, nil, v2Auth, nil) @@ -462,7 +470,10 @@ func (s *dockerImageSource) getSignaturesFromLookaside(ctx context.Context, inst return nil, fmt.Errorf("server provided %d signatures, assuming that's unreasonable and a server error", maxLookasideSignatures) } - sigURL := lookasideStorageURL(s.c.signatureBase, manifestDigest, i) + sigURL, err := lookasideStorageURL(s.c.signatureBase, manifestDigest, i) + if err != nil { + return nil, err + } signature, missing, err := s.getOneSignature(ctx, sigURL) if err != nil { return nil, err @@ -660,7 +671,10 @@ func deleteImage(ctx context.Context, sys *types.SystemContext, ref dockerRefere } for i := 0; ; i++ { - sigURL := lookasideStorageURL(c.signatureBase, manifestDigest, i) + sigURL, err := lookasideStorageURL(c.signatureBase, manifestDigest, i) + if err != nil { + return err + } missing, err := c.deleteOneSignature(sigURL) if err != nil { return err diff --git a/vendor/github.com/containers/image/v5/docker/internal/tarfile/dest.go b/vendor/github.com/containers/image/v5/docker/internal/tarfile/dest.go index b44f4ca1f..d5446840b 100644 --- a/vendor/github.com/containers/image/v5/docker/internal/tarfile/dest.go +++ b/vendor/github.com/containers/image/v5/docker/internal/tarfile/dest.go @@ -111,11 +111,19 @@ func (d *Destination) PutBlobWithOptions(ctx context.Context, stream io.Reader, return private.UploadedBlob{}, fmt.Errorf("reading Config file stream: %w", err) } d.config = buf - if err := d.archive.sendFileLocked(d.archive.configPath(inputInfo.Digest), inputInfo.Size, bytes.NewReader(buf)); err != nil { + configPath, err := d.archive.configPath(inputInfo.Digest) + if err != nil { + return private.UploadedBlob{}, err + } + if err := d.archive.sendFileLocked(configPath, inputInfo.Size, bytes.NewReader(buf)); err != nil { return private.UploadedBlob{}, fmt.Errorf("writing Config file: %w", err) } } else { - if err := d.archive.sendFileLocked(d.archive.physicalLayerPath(inputInfo.Digest), inputInfo.Size, stream); err != nil { + layerPath, err := d.archive.physicalLayerPath(inputInfo.Digest) + if err != nil { + return private.UploadedBlob{}, err + } + if err := d.archive.sendFileLocked(layerPath, inputInfo.Size, stream); err != nil { return private.UploadedBlob{}, err } } diff --git a/vendor/github.com/containers/image/v5/docker/internal/tarfile/writer.go b/vendor/github.com/containers/image/v5/docker/internal/tarfile/writer.go index df7b2c090..7f6bd0e6b 100644 --- a/vendor/github.com/containers/image/v5/docker/internal/tarfile/writer.go +++ b/vendor/github.com/containers/image/v5/docker/internal/tarfile/writer.go @@ -95,7 +95,10 @@ func (w *Writer) ensureSingleLegacyLayerLocked(layerID string, layerDigest diges if !w.legacyLayers.Contains(layerID) { // Create a symlink for the legacy format, where there is one subdirectory per layer ("image"). // See also the comment in physicalLayerPath. - physicalLayerPath := w.physicalLayerPath(layerDigest) + physicalLayerPath, err := w.physicalLayerPath(layerDigest) + if err != nil { + return err + } if err := w.sendSymlinkLocked(filepath.Join(layerID, legacyLayerFileName), filepath.Join("..", physicalLayerPath)); err != nil { return fmt.Errorf("creating layer symbolic link: %w", err) } @@ -139,6 +142,9 @@ func (w *Writer) writeLegacyMetadataLocked(layerDescriptors []manifest.Schema2De } // This chainID value matches the computation in docker/docker/layer.CreateChainID … + if err := l.Digest.Validate(); err != nil { // This should never fail on this code path, still: make sure the chainID computation is unambiguous. + return err + } if chainID == "" { chainID = l.Digest } else { @@ -204,12 +210,20 @@ func checkManifestItemsMatch(a, b *ManifestItem) error { func (w *Writer) ensureManifestItemLocked(layerDescriptors []manifest.Schema2Descriptor, configDigest digest.Digest, repoTags []reference.NamedTagged) error { layerPaths := []string{} for _, l := range layerDescriptors { - layerPaths = append(layerPaths, w.physicalLayerPath(l.Digest)) + p, err := w.physicalLayerPath(l.Digest) + if err != nil { + return err + } + layerPaths = append(layerPaths, p) } var item *ManifestItem + configPath, err := w.configPath(configDigest) + if err != nil { + return err + } newItem := ManifestItem{ - Config: w.configPath(configDigest), + Config: configPath, RepoTags: []string{}, Layers: layerPaths, Parent: "", // We don’t have this information @@ -294,21 +308,27 @@ func (w *Writer) Close() error { // configPath returns a path we choose for storing a config with the specified digest. // NOTE: This is an internal implementation detail, not a format property, and can change // any time. -func (w *Writer) configPath(configDigest digest.Digest) string { - return configDigest.Hex() + ".json" +func (w *Writer) configPath(configDigest digest.Digest) (string, error) { + if err := configDigest.Validate(); err != nil { // digest.Digest.Hex() panics on failure, and could possibly result in unexpected paths, so validate explicitly. + return "", err + } + return configDigest.Hex() + ".json", nil } // physicalLayerPath returns a path we choose for storing a layer with the specified digest // (the actual path, i.e. a regular file, not a symlink that may be used in the legacy format). // NOTE: This is an internal implementation detail, not a format property, and can change // any time. -func (w *Writer) physicalLayerPath(layerDigest digest.Digest) string { +func (w *Writer) physicalLayerPath(layerDigest digest.Digest) (string, error) { + if err := layerDigest.Validate(); err != nil { // digest.Digest.Hex() panics on failure, and could possibly result in unexpected paths, so validate explicitly. + return "", err + } // Note that this can't be e.g. filepath.Join(l.Digest.Hex(), legacyLayerFileName); due to the way // writeLegacyMetadata constructs layer IDs differently from inputinfo.Digest values (as described // inside it), most of the layers would end up in subdirectories alone without any metadata; (docker load) // tries to load every subdirectory as an image and fails if the config is missing. So, keep the layers // in the root of the tarball. - return layerDigest.Hex() + ".tar" + return layerDigest.Hex() + ".tar", nil } type tarFI struct { diff --git a/vendor/github.com/containers/image/v5/docker/registries_d.go b/vendor/github.com/containers/image/v5/docker/registries_d.go index c7b884ab3..9d651d9bd 100644 --- a/vendor/github.com/containers/image/v5/docker/registries_d.go +++ b/vendor/github.com/containers/image/v5/docker/registries_d.go @@ -286,8 +286,11 @@ func (ns registryNamespace) signatureTopLevel(write bool) string { // lookasideStorageURL returns an URL usable for accessing signature index in base with known manifestDigest. // base is not nil from the caller // NOTE: Keep this in sync with docs/signature-protocols.md! -func lookasideStorageURL(base lookasideStorageBase, manifestDigest digest.Digest, index int) *url.URL { +func lookasideStorageURL(base lookasideStorageBase, manifestDigest digest.Digest, index int) (*url.URL, error) { + if err := manifestDigest.Validate(); err != nil { // digest.Digest.Hex() panics on failure, and could possibly result in a path with ../, so validate explicitly. + return nil, err + } sigURL := *base sigURL.Path = fmt.Sprintf("%s@%s=%s/signature-%d", sigURL.Path, manifestDigest.Algorithm(), manifestDigest.Hex(), index+1) - return &sigURL + return &sigURL, nil } diff --git a/vendor/github.com/containers/image/v5/openshift/openshift_src.go b/vendor/github.com/containers/image/v5/openshift/openshift_src.go index 0ac0127ee..62774afbb 100644 --- a/vendor/github.com/containers/image/v5/openshift/openshift_src.go +++ b/vendor/github.com/containers/image/v5/openshift/openshift_src.go @@ -109,6 +109,9 @@ func (s *openshiftImageSource) GetSignaturesWithFormat(ctx context.Context, inst } imageStreamImageName = s.imageStreamImageName } else { + if err := instanceDigest.Validate(); err != nil { // Make sure instanceDigest.String() does not contain any unexpected characters + return nil, err + } imageStreamImageName = instanceDigest.String() } image, err := s.client.getImage(ctx, imageStreamImageName) diff --git a/vendor/github.com/containers/image/v5/ostree/ostree_dest.go b/vendor/github.com/containers/image/v5/ostree/ostree_dest.go index 228af90ca..37387bfdc 100644 --- a/vendor/github.com/containers/image/v5/ostree/ostree_dest.go +++ b/vendor/github.com/containers/image/v5/ostree/ostree_dest.go @@ -345,6 +345,10 @@ func (d *ostreeImageDestination) TryReusingBlobWithOptions(ctx context.Context, } d.repo = repo } + + if err := info.Digest.Validate(); err != nil { // digest.Digest.Hex() panics on failure, so validate explicitly. + return false, private.ReusedBlob{}, err + } branch := fmt.Sprintf("ociimage/%s", info.Digest.Hex()) found, data, err := readMetadata(d.repo, branch, "docker.uncompressed_digest") @@ -470,12 +474,18 @@ func (d *ostreeImageDestination) Commit(context.Context, types.UnparsedImage) er return nil } for _, layer := range d.schema.LayersDescriptors { + if err := layer.Digest.Validate(); err != nil { // digest.Digest.Encoded() panics on failure, so validate explicitly. + return err + } hash := layer.Digest.Hex() if err = checkLayer(hash); err != nil { return err } } for _, layer := range d.schema.FSLayers { + if err := layer.BlobSum.Validate(); err != nil { // digest.Digest.Encoded() panics on failure, so validate explicitly. + return err + } hash := layer.BlobSum.Hex() if err = checkLayer(hash); err != nil { return err diff --git a/vendor/github.com/containers/image/v5/ostree/ostree_src.go b/vendor/github.com/containers/image/v5/ostree/ostree_src.go index 9983acc0a..a9568c2d3 100644 --- a/vendor/github.com/containers/image/v5/ostree/ostree_src.go +++ b/vendor/github.com/containers/image/v5/ostree/ostree_src.go @@ -286,7 +286,9 @@ func (s *ostreeImageSource) readSingleFile(commit, path string) (io.ReadCloser, // The Digest field in BlobInfo is guaranteed to be provided, Size may be -1 and MediaType may be optionally provided. // May update BlobInfoCache, preferably after it knows for certain that a blob truly exists at a specific location. func (s *ostreeImageSource) GetBlob(ctx context.Context, info types.BlobInfo, cache types.BlobInfoCache) (io.ReadCloser, int64, error) { - + if err := info.Digest.Validate(); err != nil { // digest.Digest.Encoded() panics on failure, so validate explicitly. + return nil, -1, err + } blob := info.Digest.Hex() // Ensure s.compressed is initialized. It is build by LayerInfosForCopy. diff --git a/vendor/github.com/containers/image/v5/pkg/blobcache/blobcache.go b/vendor/github.com/containers/image/v5/pkg/blobcache/blobcache.go index 2bbf48848..f4de6cebf 100644 --- a/vendor/github.com/containers/image/v5/pkg/blobcache/blobcache.go +++ b/vendor/github.com/containers/image/v5/pkg/blobcache/blobcache.go @@ -78,12 +78,15 @@ func (b *BlobCache) DeleteImage(ctx context.Context, sys *types.SystemContext) e } // blobPath returns the path appropriate for storing a blob with digest. -func (b *BlobCache) blobPath(digest digest.Digest, isConfig bool) string { +func (b *BlobCache) blobPath(digest digest.Digest, isConfig bool) (string, error) { + if err := digest.Validate(); err != nil { // Make sure digest.String() does not contain any unexpected characters + return "", err + } baseName := digest.String() if isConfig { baseName += ".config" } - return filepath.Join(b.directory, baseName) + return filepath.Join(b.directory, baseName), nil } // findBlob checks if we have a blob for info in cache (whether a config or not) @@ -95,7 +98,10 @@ func (b *BlobCache) findBlob(info types.BlobInfo) (string, int64, bool, error) { } for _, isConfig := range []bool{false, true} { - path := b.blobPath(info.Digest, isConfig) + path, err := b.blobPath(info.Digest, isConfig) + if err != nil { + return "", -1, false, err + } fileInfo, err := os.Stat(path) if err == nil && (info.Size == -1 || info.Size == fileInfo.Size()) { return path, fileInfo.Size(), isConfig, nil diff --git a/vendor/github.com/containers/image/v5/pkg/blobcache/dest.go b/vendor/github.com/containers/image/v5/pkg/blobcache/dest.go index 663df11dd..d8899f2ed 100644 --- a/vendor/github.com/containers/image/v5/pkg/blobcache/dest.go +++ b/vendor/github.com/containers/image/v5/pkg/blobcache/dest.go @@ -79,47 +79,58 @@ func (d *blobCacheDestination) IgnoresEmbeddedDockerReference() bool { // and this new file. func (d *blobCacheDestination) saveStream(wg *sync.WaitGroup, decompressReader io.ReadCloser, tempFile *os.File, compressedFilename string, compressedDigest digest.Digest, isConfig bool, alternateDigest *digest.Digest) { defer wg.Done() - // Decompress from and digest the reading end of that pipe. - decompressed, err3 := archive.DecompressStream(decompressReader) + defer decompressReader.Close() + + succeeded := false + defer func() { + if !succeeded { + // Remove the temporary file. + if err := os.Remove(tempFile.Name()); err != nil { + logrus.Debugf("error cleaning up temporary file %q for decompressed copy of blob %q: %v", tempFile.Name(), compressedDigest.String(), err) + } + } + }() + digester := digest.Canonical.Digester() - if err3 == nil { + if err := func() error { // A scope for defer + defer tempFile.Close() + + // Decompress from and digest the reading end of that pipe. + decompressed, err := archive.DecompressStream(decompressReader) + if err != nil { + // Drain the pipe to keep from stalling the PutBlob() thread. + if _, err2 := io.Copy(io.Discard, decompressReader); err2 != nil { + logrus.Debugf("error draining the pipe: %v", err2) + } + return err + } + defer decompressed.Close() // Read the decompressed data through the filter over the pipe, blocking until the // writing end is closed. - _, err3 = io.Copy(io.MultiWriter(tempFile, digester.Hash()), decompressed) - } else { - // Drain the pipe to keep from stalling the PutBlob() thread. - if _, err := io.Copy(io.Discard, decompressReader); err != nil { - logrus.Debugf("error draining the pipe: %v", err) - } + _, err = io.Copy(io.MultiWriter(tempFile, digester.Hash()), decompressed) + return err + }(); err != nil { + return } - decompressReader.Close() - decompressed.Close() - tempFile.Close() + // Determine the name that we should give to the uncompressed copy of the blob. - decompressedFilename := d.reference.blobPath(digester.Digest(), isConfig) - if err3 == nil { - // Rename the temporary file. - if err3 = os.Rename(tempFile.Name(), decompressedFilename); err3 != nil { - logrus.Debugf("error renaming new decompressed copy of blob %q into place at %q: %v", digester.Digest().String(), decompressedFilename, err3) - // Remove the temporary file. - if err3 = os.Remove(tempFile.Name()); err3 != nil { - logrus.Debugf("error cleaning up temporary file %q for decompressed copy of blob %q: %v", tempFile.Name(), compressedDigest.String(), err3) - } - } else { - *alternateDigest = digester.Digest() - // Note the relationship between the two files. - if err3 = ioutils.AtomicWriteFile(decompressedFilename+compressedNote, []byte(compressedDigest.String()), 0600); err3 != nil { - logrus.Debugf("error noting that the compressed version of %q is %q: %v", digester.Digest().String(), compressedDigest.String(), err3) - } - if err3 = ioutils.AtomicWriteFile(compressedFilename+decompressedNote, []byte(digester.Digest().String()), 0600); err3 != nil { - logrus.Debugf("error noting that the decompressed version of %q is %q: %v", compressedDigest.String(), digester.Digest().String(), err3) - } - } - } else { - // Remove the temporary file. - if err3 = os.Remove(tempFile.Name()); err3 != nil { - logrus.Debugf("error cleaning up temporary file %q for decompressed copy of blob %q: %v", tempFile.Name(), compressedDigest.String(), err3) - } + decompressedFilename, err := d.reference.blobPath(digester.Digest(), isConfig) + if err != nil { + return + } + // Rename the temporary file. + if err := os.Rename(tempFile.Name(), decompressedFilename); err != nil { + logrus.Debugf("error renaming new decompressed copy of blob %q into place at %q: %v", digester.Digest().String(), decompressedFilename, err) + return + } + succeeded = true + *alternateDigest = digester.Digest() + // Note the relationship between the two files. + if err := ioutils.AtomicWriteFile(decompressedFilename+compressedNote, []byte(compressedDigest.String()), 0600); err != nil { + logrus.Debugf("error noting that the compressed version of %q is %q: %v", digester.Digest().String(), compressedDigest.String(), err) + } + if err := ioutils.AtomicWriteFile(compressedFilename+decompressedNote, []byte(digester.Digest().String()), 0600); err != nil { + logrus.Debugf("error noting that the decompressed version of %q is %q: %v", compressedDigest.String(), digester.Digest().String(), err) } } @@ -144,7 +155,10 @@ func (d *blobCacheDestination) PutBlobWithOptions(ctx context.Context, stream io needToWait := false compression := archive.Uncompressed if inputInfo.Digest != "" { - filename := d.reference.blobPath(inputInfo.Digest, options.IsConfig) + filename, err2 := d.reference.blobPath(inputInfo.Digest, options.IsConfig) + if err2 != nil { + return private.UploadedBlob{}, err2 + } tempfile, err = os.CreateTemp(filepath.Dir(filename), filepath.Base(filename)) if err == nil { stream = io.TeeReader(stream, tempfile) @@ -273,7 +287,10 @@ func (d *blobCacheDestination) PutManifest(ctx context.Context, manifestBytes [] if err != nil { logrus.Warnf("error digesting manifest %q: %v", string(manifestBytes), err) } else { - filename := d.reference.blobPath(manifestDigest, false) + filename, err := d.reference.blobPath(manifestDigest, false) + if err != nil { + return err + } if err = ioutils.AtomicWriteFile(filename, manifestBytes, 0600); err != nil { logrus.Warnf("error saving manifest as %q: %v", filename, err) } diff --git a/vendor/github.com/containers/image/v5/pkg/blobcache/src.go b/vendor/github.com/containers/image/v5/pkg/blobcache/src.go index 2fe108cda..600d2fa7a 100644 --- a/vendor/github.com/containers/image/v5/pkg/blobcache/src.go +++ b/vendor/github.com/containers/image/v5/pkg/blobcache/src.go @@ -56,7 +56,10 @@ func (s *blobCacheSource) Close() error { func (s *blobCacheSource) GetManifest(ctx context.Context, instanceDigest *digest.Digest) ([]byte, string, error) { if instanceDigest != nil { - filename := s.reference.blobPath(*instanceDigest, false) + filename, err := s.reference.blobPath(*instanceDigest, false) + if err != nil { + return nil, "", err + } manifestBytes, err := os.ReadFile(filename) if err == nil { s.cacheHits++ @@ -136,8 +139,10 @@ func (s *blobCacheSource) LayerInfosForCopy(ctx context.Context, instanceDigest replacedInfos := make([]types.BlobInfo, 0, len(infos)) for _, info := range infos { var replaceDigest []byte - var err error - blobFile := s.reference.blobPath(info.Digest, false) + blobFile, err := s.reference.blobPath(info.Digest, false) + if err != nil { + return nil, err + } var alternate string switch s.reference.compress { case types.Compress: @@ -148,7 +153,10 @@ func (s *blobCacheSource) LayerInfosForCopy(ctx context.Context, instanceDigest replaceDigest, err = os.ReadFile(alternate) } if err == nil && digest.Digest(replaceDigest).Validate() == nil { - alternate = s.reference.blobPath(digest.Digest(replaceDigest), false) + alternate, err = s.reference.blobPath(digest.Digest(replaceDigest), false) + if err != nil { + return nil, err + } fileInfo, err := os.Stat(alternate) if err == nil { switch info.MediaType { diff --git a/vendor/github.com/containers/image/v5/storage/storage_dest.go b/vendor/github.com/containers/image/v5/storage/storage_dest.go index c06d6c09f..bc9790ca3 100644 --- a/vendor/github.com/containers/image/v5/storage/storage_dest.go +++ b/vendor/github.com/containers/image/v5/storage/storage_dest.go @@ -361,6 +361,18 @@ func (s *storageImageDestination) TryReusingBlobWithOptions(ctx context.Context, // tryReusingBlobAsPending implements TryReusingBlobWithOptions for (blobDigest, size or -1), filling s.blobDiffIDs and other metadata. // The caller must arrange the blob to be eventually committed using s.commitLayer(). func (s *storageImageDestination) tryReusingBlobAsPending(blobDigest digest.Digest, size int64, options *private.TryReusingBlobOptions) (bool, private.ReusedBlob, error) { + if blobDigest == "" { + return false, private.ReusedBlob{}, errors.New(`Can not check for a blob with unknown digest`) + } + if err := blobDigest.Validate(); err != nil { + return false, private.ReusedBlob{}, fmt.Errorf("Can not check for a blob with invalid digest: %w", err) + } + if options.TOCDigest != "" { + if err := options.TOCDigest.Validate(); err != nil { + return false, private.ReusedBlob{}, fmt.Errorf("Can not check for a blob with invalid digest: %w", err) + } + } + // lock the entire method as it executes fairly quickly s.lock.Lock() defer s.lock.Unlock() @@ -380,18 +392,6 @@ func (s *storageImageDestination) tryReusingBlobAsPending(blobDigest digest.Dige } } - if blobDigest == "" { - return false, private.ReusedBlob{}, errors.New(`Can not check for a blob with unknown digest`) - } - if err := blobDigest.Validate(); err != nil { - return false, private.ReusedBlob{}, fmt.Errorf("Can not check for a blob with invalid digest: %w", err) - } - if options.TOCDigest != "" { - if err := options.TOCDigest.Validate(); err != nil { - return false, private.ReusedBlob{}, fmt.Errorf("Can not check for a blob with invalid digest: %w", err) - } - } - // Check if we have a wasn't-compressed layer in storage that's based on that blob. // Check if we've already cached it in a file. @@ -1070,8 +1070,12 @@ func (s *storageImageDestination) Commit(ctx context.Context, unparsedToplevel t if err != nil { return fmt.Errorf("digesting top-level manifest: %w", err) } + key, err := manifestBigDataKey(manifestDigest) + if err != nil { + return err + } options.BigData = append(options.BigData, storage.ImageBigDataOption{ - Key: manifestBigDataKey(manifestDigest), + Key: key, Data: toplevelManifest, Digest: manifestDigest, }) @@ -1079,8 +1083,12 @@ func (s *storageImageDestination) Commit(ctx context.Context, unparsedToplevel t // Set up to save the image's manifest. Allow looking it up by digest by using the key convention defined by the Store. // Record the manifest twice: using a digest-specific key to allow references to that specific digest instance, // and using storage.ImageDigestBigDataKey for future users that don’t specify any digest and for compatibility with older readers. + key, err := manifestBigDataKey(s.manifestDigest) + if err != nil { + return err + } options.BigData = append(options.BigData, storage.ImageBigDataOption{ - Key: manifestBigDataKey(s.manifestDigest), + Key: key, Data: s.manifest, Digest: s.manifestDigest, }) @@ -1098,8 +1106,12 @@ func (s *storageImageDestination) Commit(ctx context.Context, unparsedToplevel t }) } for instanceDigest, signatures := range s.signatureses { + key, err := signatureBigDataKey(instanceDigest) + if err != nil { + return err + } options.BigData = append(options.BigData, storage.ImageBigDataOption{ - Key: signatureBigDataKey(instanceDigest), + Key: key, Data: signatures, Digest: digest.Canonical.FromBytes(signatures), }) diff --git a/vendor/github.com/containers/image/v5/storage/storage_image.go b/vendor/github.com/containers/image/v5/storage/storage_image.go index eed846eb9..7e368857e 100644 --- a/vendor/github.com/containers/image/v5/storage/storage_image.go +++ b/vendor/github.com/containers/image/v5/storage/storage_image.go @@ -21,14 +21,20 @@ var ( // manifestBigDataKey returns a key suitable for recording a manifest with the specified digest using storage.Store.ImageBigData and related functions. // If a specific manifest digest is explicitly requested by the user, the key returned by this function should be used preferably; // for compatibility, if a manifest is not available under this key, check also storage.ImageDigestBigDataKey -func manifestBigDataKey(digest digest.Digest) string { - return storage.ImageDigestManifestBigDataNamePrefix + "-" + digest.String() +func manifestBigDataKey(digest digest.Digest) (string, error) { + if err := digest.Validate(); err != nil { // Make sure info.Digest.String() uses the expected format and does not collide with other BigData keys. + return "", err + } + return storage.ImageDigestManifestBigDataNamePrefix + "-" + digest.String(), nil } // signatureBigDataKey returns a key suitable for recording the signatures associated with the manifest with the specified digest using storage.Store.ImageBigData and related functions. // If a specific manifest digest is explicitly requested by the user, the key returned by this function should be used preferably; -func signatureBigDataKey(digest digest.Digest) string { - return "signature-" + digest.Encoded() +func signatureBigDataKey(digest digest.Digest) (string, error) { + if err := digest.Validate(); err != nil { // digest.Digest.Encoded() panics on failure, so validate explicitly. + return "", err + } + return "signature-" + digest.Encoded(), nil } // storageImageMetadata is stored, as JSON, in storage.Image.Metadata diff --git a/vendor/github.com/containers/image/v5/storage/storage_reference.go b/vendor/github.com/containers/image/v5/storage/storage_reference.go index a55e34054..6b7565fd8 100644 --- a/vendor/github.com/containers/image/v5/storage/storage_reference.go +++ b/vendor/github.com/containers/image/v5/storage/storage_reference.go @@ -73,7 +73,10 @@ func multiArchImageMatchesSystemContext(store storage.Store, img *storage.Image, // We don't need to care about storage.ImageDigestBigDataKey because // manifests lists are only stored into storage by c/image versions // that know about manifestBigDataKey, and only using that key. - key := manifestBigDataKey(manifestDigest) + key, err := manifestBigDataKey(manifestDigest) + if err != nil { + return false // This should never happen, manifestDigest comes from a reference.Digested, and that validates the format. + } manifestBytes, err := store.ImageBigData(img.ID, key) if err != nil { return false @@ -95,7 +98,10 @@ func multiArchImageMatchesSystemContext(store storage.Store, img *storage.Image, if err != nil { return false } - key = manifestBigDataKey(chosenInstance) + key, err = manifestBigDataKey(chosenInstance) + if err != nil { + return false + } _, err = store.ImageBigData(img.ID, key) return err == nil // true if img.ID is based on chosenInstance. } diff --git a/vendor/github.com/containers/image/v5/storage/storage_src.go b/vendor/github.com/containers/image/v5/storage/storage_src.go index ead3300f3..27febe1d3 100644 --- a/vendor/github.com/containers/image/v5/storage/storage_src.go +++ b/vendor/github.com/containers/image/v5/storage/storage_src.go @@ -237,7 +237,10 @@ func (s *storageImageSource) getBlobAndLayerID(digest digest.Digest, layers []st // GetManifest() reads the image's manifest. func (s *storageImageSource) GetManifest(ctx context.Context, instanceDigest *digest.Digest) (manifestBlob []byte, mimeType string, err error) { if instanceDigest != nil { - key := manifestBigDataKey(*instanceDigest) + key, err := manifestBigDataKey(*instanceDigest) + if err != nil { + return nil, "", err + } blob, err := s.imageRef.transport.store.ImageBigData(s.image.ID, key) if err != nil { return nil, "", fmt.Errorf("reading manifest for image instance %q: %w", *instanceDigest, err) @@ -249,7 +252,10 @@ func (s *storageImageSource) GetManifest(ctx context.Context, instanceDigest *di // Prefer the manifest corresponding to the user-specified digest, if available. if s.imageRef.named != nil { if digested, ok := s.imageRef.named.(reference.Digested); ok { - key := manifestBigDataKey(digested.Digest()) + key, err := manifestBigDataKey(digested.Digest()) + if err != nil { + return nil, "", err + } blob, err := s.imageRef.transport.store.ImageBigData(s.image.ID, key) if err != nil && !os.IsNotExist(err) { // os.IsNotExist is true if the image exists but there is no data corresponding to key return nil, "", err @@ -385,7 +391,14 @@ func (s *storageImageSource) GetSignaturesWithFormat(ctx context.Context, instan instance := "default instance" if instanceDigest != nil { signatureSizes = s.metadata.SignaturesSizes[*instanceDigest] - key = signatureBigDataKey(*instanceDigest) + k, err := signatureBigDataKey(*instanceDigest) + if err != nil { + return nil, err + } + key = k + if err := instanceDigest.Validate(); err != nil { // digest.Digest.Encoded() panics on failure, so validate explicitly. + return nil, err + } instance = instanceDigest.Encoded() } if len(signatureSizes) > 0 { diff --git a/vendor/github.com/containers/image/v5/version/version.go b/vendor/github.com/containers/image/v5/version/version.go index a14c8e2ff..2be054158 100644 --- a/vendor/github.com/containers/image/v5/version/version.go +++ b/vendor/github.com/containers/image/v5/version/version.go @@ -8,7 +8,7 @@ const ( // VersionMinor is for functionality in a backwards-compatible manner VersionMinor = 30 // VersionPatch is for backwards-compatible bug fixes - VersionPatch = 0 + VersionPatch = 1 // VersionDev indicates development branch. Releases will be empty string. VersionDev = "" diff --git a/vendor/github.com/containers/ocicrypt/keywrap/jwe/keywrapper_jwe.go b/vendor/github.com/containers/ocicrypt/keywrap/jwe/keywrapper_jwe.go index cd2241cbc..24e1d619d 100644 --- a/vendor/github.com/containers/ocicrypt/keywrap/jwe/keywrapper_jwe.go +++ b/vendor/github.com/containers/ocicrypt/keywrap/jwe/keywrapper_jwe.go @@ -123,9 +123,24 @@ func addPubKeys(joseRecipients *[]jose.Recipient, pubKeys [][]byte) error { } alg := jose.RSA_OAEP - switch key.(type) { + switch key := key.(type) { case *ecdsa.PublicKey: alg = jose.ECDH_ES_A256KW + case *jose.JSONWebKey: + if key.Algorithm != "" { + alg = jose.KeyAlgorithm(key.Algorithm) + switch alg { + /* accepted algorithms */ + case jose.RSA_OAEP: + case jose.RSA_OAEP_256: + case jose.ECDH_ES_A128KW: + case jose.ECDH_ES_A192KW: + case jose.ECDH_ES_A256KW: + /* all others are rejected */ + default: + return fmt.Errorf("%s is an unsupported JWE key algorithm", alg) + } + } } *joseRecipients = append(*joseRecipients, jose.Recipient{ diff --git a/vendor/github.com/containers/ocicrypt/utils/testing.go b/vendor/github.com/containers/ocicrypt/utils/testing.go index 69bb9d12f..050aa885e 100644 --- a/vendor/github.com/containers/ocicrypt/utils/testing.go +++ b/vendor/github.com/containers/ocicrypt/utils/testing.go @@ -38,6 +38,15 @@ func CreateRSAKey(bits int) (*rsa.PrivateKey, error) { return key, nil } +// CreateECDSAKey creates an elliptic curve key for the given curve +func CreateECDSAKey(curve elliptic.Curve) (*ecdsa.PrivateKey, error) { + key, err := ecdsa.GenerateKey(curve, rand.Reader) + if err != nil { + return nil, fmt.Errorf("ecdsa.GenerateKey failed: %w", err) + } + return key, nil +} + // CreateRSATestKey creates an RSA key of the given size and returns // the public and private key in PEM or DER format func CreateRSATestKey(bits int, password []byte, pemencode bool) ([]byte, []byte, error) { @@ -85,9 +94,9 @@ func CreateRSATestKey(bits int, password []byte, pemencode bool) ([]byte, []byte // CreateECDSATestKey creates and elliptic curve key for the given curve and returns // the public and private key in DER format func CreateECDSATestKey(curve elliptic.Curve) ([]byte, []byte, error) { - key, err := ecdsa.GenerateKey(curve, rand.Reader) + key, err := CreateECDSAKey(curve) if err != nil { - return nil, nil, fmt.Errorf("ecdsa.GenerateKey failed: %w", err) + return nil, nil, err } pubData, err := x509.MarshalPKIXPublicKey(&key.PublicKey) diff --git a/vendor/github.com/containers/podman/v5/version/rawversion/version.go b/vendor/github.com/containers/podman/v5/version/rawversion/version.go index 126606e03..7abaacbb3 100644 --- a/vendor/github.com/containers/podman/v5/version/rawversion/version.go +++ b/vendor/github.com/containers/podman/v5/version/rawversion/version.go @@ -7,4 +7,4 @@ package rawversion // // NOTE: remember to bump the version at the top of the top-level README.md // file when this is bumped. -const RawVersion = "5.0.2" +const RawVersion = "5.0.3" diff --git a/vendor/modules.txt b/vendor/modules.txt index 06c785519..b2b696644 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -114,7 +114,7 @@ github.com/containernetworking/cni/pkg/version # github.com/containernetworking/plugins v1.4.0 ## explicit; go 1.20 github.com/containernetworking/plugins/pkg/ns -# github.com/containers/buildah v1.35.3 +# github.com/containers/buildah v1.35.4 ## explicit; go 1.20 github.com/containers/buildah github.com/containers/buildah/bind @@ -141,7 +141,7 @@ github.com/containers/buildah/pkg/rusage github.com/containers/buildah/pkg/sshagent github.com/containers/buildah/pkg/util github.com/containers/buildah/util -# github.com/containers/common v0.58.2 +# github.com/containers/common v0.58.3 ## explicit; go 1.20 github.com/containers/common/internal github.com/containers/common/internal/attributedstring @@ -207,7 +207,7 @@ github.com/containers/common/version # github.com/containers/conmon v2.0.20+incompatible ## explicit github.com/containers/conmon/runner/config -# github.com/containers/image/v5 v5.30.0 +# github.com/containers/image/v5 v5.30.1 ## explicit; go 1.19 github.com/containers/image/v5/copy github.com/containers/image/v5/directory @@ -280,7 +280,7 @@ github.com/containers/libtrust # github.com/containers/luksy v0.0.0-20240212203526-ceb12d4fd50c ## explicit; go 1.20 github.com/containers/luksy -# github.com/containers/ocicrypt v1.1.9 +# github.com/containers/ocicrypt v1.1.10 ## explicit; go 1.20 github.com/containers/ocicrypt github.com/containers/ocicrypt/blockcipher @@ -296,7 +296,7 @@ github.com/containers/ocicrypt/keywrap/pkcs7 github.com/containers/ocicrypt/spec github.com/containers/ocicrypt/utils github.com/containers/ocicrypt/utils/keyprovider -# github.com/containers/podman/v5 v5.0.2 +# github.com/containers/podman/v5 v5.0.3 ## explicit; go 1.20 github.com/containers/podman/v5/cmd/podman/parse github.com/containers/podman/v5/cmd/podman/registry