Package: release.debian.org Severity: normal User: release.debian....@packages.debian.org Usertags: unblock X-Debbugs-Cc: docker-regis...@packages.debian.org, z...@debian.org Control: affects -1 + src:docker-registry
Please unblock package docker-registry [ Reason ] Upstream micro release for CVE-2023-2253 (Catalog API endpoint can lead to OOM via malicious user input). [ Impact ] Fix security issue. [ Tests ] New unittest is added. The package has autopkgtest. [ Risks ] The debdiff contains some noise code style changes, otherwise they are trivial. [ Checklist ] [x] all changes are documented in the d/changelog [x] I reviewed all changes and I approve them [x] attach debdiff against the package in testing [ Other info ] I attached a filtered debdiff, with following command, filterdiff --exclude '*/releases/*' --exclude '*/script/*' --exclude '*/.github/*' \ --exclude '*.hcl' --exclude '*.yml' --exclude '*/Dockerfile' \ --exclude '*/Makefile' --exclude '*/.mailmap' --exclude '*_test.go' unblock docker-registry/2.8.2+ds1-1
diff -Nru -w docker-registry-2.8.1+ds1/configuration/configuration.go docker-registry-2.8.2+ds1/configuration/configuration.go --- docker-registry-2.8.1+ds1/configuration/configuration.go 2022-03-09 01:52:36.000000000 +0800 +++ docker-registry-2.8.2+ds1/configuration/configuration.go 2023-05-11 18:11:57.000000000 +0800 @@ -194,6 +194,7 @@ } `yaml:"redis,omitempty"` Health Health `yaml:"health,omitempty"` + Catalog Catalog `yaml:"catalog,omitempty"` Proxy Proxy `yaml:"proxy,omitempty"` @@ -244,6 +245,16 @@ } `yaml:"policy,omitempty"` } +// Catalog is composed of MaxEntries. +// Catalog endpoint (/v2/_catalog) configuration, it provides the configuration +// options to control the maximum number of entries returned by the catalog endpoint. +type Catalog struct { + // Max number of entries returned by the catalog endpoint. Requesting n entries + // to the catalog endpoint will return at most MaxEntries entries. + // An empty or a negative value will set a default of 1000 maximum entries by default. + MaxEntries int `yaml:"maxentries,omitempty"` +} + // LogHook is composed of hook Level and Type. // After hooks configuration, it can execute the next handling automatically, // when defined levels of log message emitted. @@ -670,6 +681,11 @@ if v0_1.Loglevel != Loglevel("") { v0_1.Loglevel = Loglevel("") } + + if v0_1.Catalog.MaxEntries <= 0 { + v0_1.Catalog.MaxEntries = 1000 + } + if v0_1.Storage.Type() == "" { return nil, errors.New("no storage configuration provided") } diff -Nru -w docker-registry-2.8.1+ds1/context/doc.go docker-registry-2.8.2+ds1/context/doc.go --- docker-registry-2.8.1+ds1/context/doc.go 2022-03-09 01:52:36.000000000 +0800 +++ docker-registry-2.8.2+ds1/context/doc.go 2023-05-11 18:11:57.000000000 +0800 @@ -15,7 +15,7 @@ // The above will store the version in the context and will be available to // the logger. // -// Logging +// # Logging // // The most useful aspect of this package is GetLogger. This function takes // any context.Context interface and returns the current logger from the @@ -65,7 +65,7 @@ // added to the request context, is unique to that context and can have // request scoped variables. // -// HTTP Requests +// # HTTP Requests // // This package also contains several methods for working with http requests. // The concepts are very similar to those described above. We simply place the diff -Nru -w docker-registry-2.8.1+ds1/context/http.go docker-registry-2.8.2+ds1/context/http.go --- docker-registry-2.8.1+ds1/context/http.go 2022-03-09 01:52:36.000000000 +0800 +++ docker-registry-2.8.2+ds1/context/http.go 2023-05-11 18:11:57.000000000 +0800 @@ -246,11 +246,7 @@ return ctx.vars } - if strings.HasPrefix(keyStr, "vars.") { - keyStr = strings.TrimPrefix(keyStr, "vars.") - } - - if v, ok := ctx.vars[keyStr]; ok { + if v, ok := ctx.vars[strings.TrimPrefix(keyStr, "vars.")]; ok { return v } } diff -Nru -w docker-registry-2.8.1+ds1/debian/changelog docker-registry-2.8.2+ds1/debian/changelog --- docker-registry-2.8.1+ds1/debian/changelog 2022-06-29 20:32:34.000000000 +0800 +++ docker-registry-2.8.2+ds1/debian/changelog 2023-05-13 23:21:12.000000000 +0800 @@ -1,3 +1,14 @@ +docker-registry (2.8.2+ds1-1) unstable; urgency=medium + + * Team upload + * New upstream version 2.8.2+ds1 + + CVE-2023-2253: Catalog API endpoint can lead to OOM via malicious user + input (Closes: #1035956) + * Drop patch merged by upstream + + 0009-Fix-panic-in-inmemory-driver.patch + + -- Shengjing Zhu <z...@debian.org> Sat, 13 May 2023 23:21:12 +0800 + docker-registry (2.8.1+ds1-2) unstable; urgency=medium [ Debian Janitor ] diff -Nru -w docker-registry-2.8.1+ds1/debian/patches/0007-Skip-TestRegistryAsCacheMutationAPIs.patch docker-registry-2.8.2+ds1/debian/patches/0007-Skip-TestRegistryAsCacheMutationAPIs.patch --- docker-registry-2.8.1+ds1/debian/patches/0007-Skip-TestRegistryAsCacheMutationAPIs.patch 2022-06-29 20:32:34.000000000 +0800 +++ docker-registry-2.8.2+ds1/debian/patches/0007-Skip-TestRegistryAsCacheMutationAPIs.patch 2023-05-13 23:21:12.000000000 +0800 @@ -12,10 +12,10 @@ 1 file changed, 1 insertion(+) diff --git a/registry/handlers/api_test.go b/registry/handlers/api_test.go -index 2d3edc7..a07184b 100644 +index bf037d4..207e167 100644 --- a/registry/handlers/api_test.go +++ b/registry/handlers/api_test.go -@@ -2468,6 +2468,7 @@ func createRepository(env *testEnv, t *testing.T, imageName string, tag string) +@@ -2728,6 +2728,7 @@ func createRepository(env *testEnv, t *testing.T, imageName string, tag string) // Test mutation operations on a registry configured as a cache. Ensure that they return // appropriate errors. func TestRegistryAsCacheMutationAPIs(t *testing.T) { diff -Nru -w docker-registry-2.8.1+ds1/debian/patches/0009-Fix-panic-in-inmemory-driver.patch docker-registry-2.8.2+ds1/debian/patches/0009-Fix-panic-in-inmemory-driver.patch --- docker-registry-2.8.1+ds1/debian/patches/0009-Fix-panic-in-inmemory-driver.patch 2022-06-29 20:32:34.000000000 +0800 +++ docker-registry-2.8.2+ds1/debian/patches/0009-Fix-panic-in-inmemory-driver.patch 1970-01-01 08:00:00.000000000 +0800 @@ -1,23 +0,0 @@ -From: Shengjing Zhu <z...@debian.org> -Date: Sun, 27 Mar 2022 19:38:07 +0800 -Subject: Fix panic in inmemory driver - -Forwarded: https://github.com/distribution/distribution/pull/3615 ---- - registry/storage/driver/inmemory/mfs.go | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/registry/storage/driver/inmemory/mfs.go b/registry/storage/driver/inmemory/mfs.go -index 9a2865f..24eeef9 100644 ---- a/registry/storage/driver/inmemory/mfs.go -+++ b/registry/storage/driver/inmemory/mfs.go -@@ -279,6 +279,9 @@ func (f *file) sectionReader(offset int64) io.Reader { - } - - func (f *file) ReadAt(p []byte, offset int64) (n int, err error) { -+ if offset >= int64(len(f.data)) { -+ return 0, io.EOF -+ } - return copy(p, f.data[offset:]), nil - } - diff -Nru -w docker-registry-2.8.1+ds1/debian/patches/series docker-registry-2.8.2+ds1/debian/patches/series --- docker-registry-2.8.1+ds1/debian/patches/series 2022-06-29 20:32:34.000000000 +0800 +++ docker-registry-2.8.2+ds1/debian/patches/series 2023-05-13 23:21:12.000000000 +0800 @@ -6,4 +6,3 @@ 0006-Skip-TestHTTPChecker.patch 0007-Skip-TestRegistryAsCacheMutationAPIs.patch 0008-Skip-flaky-TestGracefulShutdown-and-TestRegistrySupp.patch -0009-Fix-panic-in-inmemory-driver.patch diff -Nru -w docker-registry-2.8.1+ds1/.dockerignore docker-registry-2.8.2+ds1/.dockerignore --- docker-registry-2.8.1+ds1/.dockerignore 1970-01-01 08:00:00.000000000 +0800 +++ docker-registry-2.8.2+ds1/.dockerignore 2023-05-11 18:11:57.000000000 +0800 @@ -0,0 +1 @@ +bin/ diff -Nru -w docker-registry-2.8.1+ds1/health/doc.go docker-registry-2.8.2+ds1/health/doc.go --- docker-registry-2.8.1+ds1/health/doc.go 2022-03-09 01:52:36.000000000 +0800 +++ docker-registry-2.8.2+ds1/health/doc.go 2023-05-11 18:11:57.000000000 +0800 @@ -13,7 +13,7 @@ // particularly useful for checks that verify upstream connectivity or // database status, since they might take a long time to return/timeout. // -// Installing +// # Installing // // To install health, just import it in your application: // @@ -35,7 +35,7 @@ // After importing these packages to your main application, you can start // registering checks. // -// Registering Checks +// # Registering Checks // // The recommended way of registering checks is using a periodic Check. // PeriodicChecks run on a certain schedule and asynchronously update the @@ -84,7 +84,7 @@ // return Errors.new("This is an error!") // })) // -// Examples +// # Examples // // You could also use the health checker mechanism to ensure your application // only comes up if certain conditions are met, or to allow the developer to diff -Nru -w docker-registry-2.8.1+ds1/registry/api/v2/descriptors.go docker-registry-2.8.2+ds1/registry/api/v2/descriptors.go --- docker-registry-2.8.1+ds1/registry/api/v2/descriptors.go 2022-03-09 01:52:36.000000000 +0800 +++ docker-registry-2.8.2+ds1/registry/api/v2/descriptors.go 2023-05-11 18:11:57.000000000 +0800 @@ -134,6 +134,19 @@ }, } + invalidPaginationResponseDescriptor = ResponseDescriptor{ + Name: "Invalid pagination number", + Description: "The received parameter n was invalid in some way, as described by the error code. The client should resolve the issue and retry the request.", + StatusCode: http.StatusBadRequest, + Body: BodyDescriptor{ + ContentType: "application/json", + Format: errorsBody, + }, + ErrorCodes: []errcode.ErrorCode{ + ErrorCodePaginationNumberInvalid, + }, + } + repositoryNotFoundResponseDescriptor = ResponseDescriptor{ Name: "No Such Repository Error", StatusCode: http.StatusNotFound, @@ -490,6 +503,7 @@ }, }, Failures: []ResponseDescriptor{ + invalidPaginationResponseDescriptor, unauthorizedResponseDescriptor, repositoryNotFoundResponseDescriptor, deniedResponseDescriptor, @@ -1578,6 +1592,9 @@ }, }, }, + Failures: []ResponseDescriptor{ + invalidPaginationResponseDescriptor, + }, }, }, }, diff -Nru -w docker-registry-2.8.1+ds1/registry/api/v2/errors.go docker-registry-2.8.2+ds1/registry/api/v2/errors.go --- docker-registry-2.8.1+ds1/registry/api/v2/errors.go 2022-03-09 01:52:36.000000000 +0800 +++ docker-registry-2.8.2+ds1/registry/api/v2/errors.go 2023-05-11 18:11:57.000000000 +0800 @@ -133,4 +133,13 @@ longer proceed.`, HTTPStatusCode: http.StatusNotFound, }) + + ErrorCodePaginationNumberInvalid = errcode.Register(errGroup, errcode.ErrorDescriptor{ + Value: "PAGINATION_NUMBER_INVALID", + Message: "invalid number of results requested", + Description: `Returned when the "n" parameter (number of results + to return) is not an integer, "n" is negative or "n" is bigger than + the maximum allowed.`, + HTTPStatusCode: http.StatusBadRequest, + }) ) diff -Nru -w docker-registry-2.8.1+ds1/registry/auth/auth.go docker-registry-2.8.2+ds1/registry/auth/auth.go --- docker-registry-2.8.1+ds1/registry/auth/auth.go 2022-03-09 01:52:36.000000000 +0800 +++ docker-registry-2.8.2+ds1/registry/auth/auth.go 2023-05-11 18:11:57.000000000 +0800 @@ -29,7 +29,6 @@ // } // } // } -// package auth import ( diff -Nru -w docker-registry-2.8.1+ds1/registry/auth/token/token.go docker-registry-2.8.2+ds1/registry/auth/token/token.go --- docker-registry-2.8.1+ds1/registry/auth/token/token.go 2022-03-09 01:52:36.000000000 +0800 +++ docker-registry-2.8.2+ds1/registry/auth/token/token.go 2023-05-11 18:11:57.000000000 +0800 @@ -185,6 +185,7 @@ // VerifySigningKey attempts to get the key which was used to sign this token. // The token header should contain either of these 3 fields: +// // `x5c` - The x509 certificate chain for the signing key. Needs to be // verified. // `jwk` - The JSON Web Key representation of the signing key. @@ -192,6 +193,7 @@ // `kid` - The unique identifier for the key. This library interprets it // as a libtrust fingerprint. The key itself can be looked up in // the trustedKeys field of the given verify options. +// // Each of these methods are tried in that order of preference until the // signing key is found or an error is returned. func (t *Token) VerifySigningKey(verifyOpts VerifyOptions) (signingKey libtrust.PublicKey, err error) { diff -Nru -w docker-registry-2.8.1+ds1/registry/client/errors.go docker-registry-2.8.2+ds1/registry/client/errors.go --- docker-registry-2.8.1+ds1/registry/client/errors.go 2022-03-09 01:52:36.000000000 +0800 +++ docker-registry-2.8.2+ds1/registry/client/errors.go 2023-05-11 18:11:57.000000000 +0800 @@ -55,6 +55,8 @@ switch statusCode { case http.StatusUnauthorized: return errcode.ErrorCodeUnauthorized.WithMessage(detailsErr.Details) + case http.StatusForbidden: + return errcode.ErrorCodeDenied.WithMessage(detailsErr.Details) case http.StatusTooManyRequests: return errcode.ErrorCodeTooManyRequests.WithMessage(detailsErr.Details) default: diff -Nru -w docker-registry-2.8.1+ds1/registry/client/repository.go docker-registry-2.8.2+ds1/registry/client/repository.go --- docker-registry-2.8.1+ds1/registry/client/repository.go 2022-03-09 01:52:36.000000000 +0800 +++ docker-registry-2.8.2+ds1/registry/client/repository.go 2023-05-11 18:11:57.000000000 +0800 @@ -114,9 +114,7 @@ return 0, err } - for cnt := range ctlg.Repositories { - entries[cnt] = ctlg.Repositories[cnt] - } + copy(entries, ctlg.Repositories) numFilled = len(ctlg.Repositories) link := resp.Header.Get("Link") diff -Nru -w docker-registry-2.8.1+ds1/registry/client/transport/http_reader.go docker-registry-2.8.2+ds1/registry/client/transport/http_reader.go --- docker-registry-2.8.1+ds1/registry/client/transport/http_reader.go 2022-03-09 01:52:36.000000000 +0800 +++ docker-registry-2.8.2+ds1/registry/client/transport/http_reader.go 2023-05-11 18:11:57.000000000 +0800 @@ -180,7 +180,6 @@ // context.GetLogger(hrs.context).Infof("Range: %s", req.Header.Get("Range")) } - req.Header.Add("Accept-Encoding", "identity") resp, err := hrs.client.Do(req) if err != nil { return nil, err diff -Nru -w docker-registry-2.8.1+ds1/registry/handlers/basicauth.go docker-registry-2.8.2+ds1/registry/handlers/basicauth.go --- docker-registry-2.8.1+ds1/registry/handlers/basicauth.go 2022-03-09 01:52:36.000000000 +0800 +++ docker-registry-2.8.2+ds1/registry/handlers/basicauth.go 2023-05-11 18:11:57.000000000 +0800 @@ -1,3 +1,4 @@ +//go:build go1.4 // +build go1.4 package handlers diff -Nru -w docker-registry-2.8.1+ds1/registry/handlers/basicauth_prego14.go docker-registry-2.8.2+ds1/registry/handlers/basicauth_prego14.go --- docker-registry-2.8.1+ds1/registry/handlers/basicauth_prego14.go 2022-03-09 01:52:36.000000000 +0800 +++ docker-registry-2.8.2+ds1/registry/handlers/basicauth_prego14.go 2023-05-11 18:11:57.000000000 +0800 @@ -1,3 +1,4 @@ +//go:build !go1.4 // +build !go1.4 package handlers diff -Nru -w docker-registry-2.8.1+ds1/registry/handlers/catalog.go docker-registry-2.8.2+ds1/registry/handlers/catalog.go --- docker-registry-2.8.1+ds1/registry/handlers/catalog.go 2022-03-09 01:52:36.000000000 +0800 +++ docker-registry-2.8.2+ds1/registry/handlers/catalog.go 2023-05-11 18:11:57.000000000 +0800 @@ -9,11 +9,13 @@ "strconv" "github.com/docker/distribution/registry/api/errcode" + v2 "github.com/docker/distribution/registry/api/v2" "github.com/docker/distribution/registry/storage/driver" + "github.com/gorilla/handlers" ) -const maximumReturnedEntries = 100 +const defaultReturnedEntries = 100 func catalogDispatcher(ctx *Context, r *http.Request) http.Handler { catalogHandler := &catalogHandler{ @@ -38,29 +40,55 @@ q := r.URL.Query() lastEntry := q.Get("last") - maxEntries, err := strconv.Atoi(q.Get("n")) - if err != nil || maxEntries < 0 { - maxEntries = maximumReturnedEntries + + entries := defaultReturnedEntries + maximumConfiguredEntries := ch.App.Config.Catalog.MaxEntries + + // parse n, if n unparseable, or negative assign it to defaultReturnedEntries + if n := q.Get("n"); n != "" { + parsedMax, err := strconv.Atoi(n) + if err == nil { + if parsedMax > maximumConfiguredEntries { + ch.Errors = append(ch.Errors, v2.ErrorCodePaginationNumberInvalid.WithDetail(map[string]int{"n": parsedMax})) + return + } else if parsedMax >= 0 { + entries = parsedMax + } + } } - repos := make([]string, maxEntries) + // then enforce entries to be between 0 & maximumConfiguredEntries + // max(0, min(entries, maximumConfiguredEntries)) + if entries < 0 || entries > maximumConfiguredEntries { + entries = maximumConfiguredEntries + } - filled, err := ch.App.registry.Repositories(ch.Context, repos, lastEntry) - _, pathNotFound := err.(driver.PathNotFoundError) + repos := make([]string, entries) + filled := 0 - if err == io.EOF || pathNotFound { + // entries is guaranteed to be >= 0 and < maximumConfiguredEntries + if entries == 0 { moreEntries = false - } else if err != nil { + } else { + returnedRepositories, err := ch.App.registry.Repositories(ch.Context, repos, lastEntry) + if err != nil { + _, pathNotFound := err.(driver.PathNotFoundError) + if err != io.EOF && !pathNotFound { ch.Errors = append(ch.Errors, errcode.ErrorCodeUnknown.WithDetail(err)) return } + // err is either io.EOF or not PathNotFoundError + moreEntries = false + } + filled = returnedRepositories + } w.Header().Set("Content-Type", "application/json; charset=utf-8") // Add a link header if there are more entries to retrieve if moreEntries { - lastEntry = repos[len(repos)-1] - urlStr, err := createLinkEntry(r.URL.String(), maxEntries, lastEntry) + lastEntry = repos[filled-1] + urlStr, err := createLinkEntry(r.URL.String(), entries, lastEntry) if err != nil { ch.Errors = append(ch.Errors, errcode.ErrorCodeUnknown.WithDetail(err)) return diff -Nru -w docker-registry-2.8.1+ds1/registry/storage/blobwriter_nonresumable.go docker-registry-2.8.2+ds1/registry/storage/blobwriter_nonresumable.go --- docker-registry-2.8.1+ds1/registry/storage/blobwriter_nonresumable.go 2022-03-09 01:52:36.000000000 +0800 +++ docker-registry-2.8.2+ds1/registry/storage/blobwriter_nonresumable.go 2023-05-11 18:11:57.000000000 +0800 @@ -1,3 +1,4 @@ +//go:build noresumabledigest // +build noresumabledigest package storage diff -Nru -w docker-registry-2.8.1+ds1/registry/storage/blobwriter_resumable.go docker-registry-2.8.2+ds1/registry/storage/blobwriter_resumable.go --- docker-registry-2.8.1+ds1/registry/storage/blobwriter_resumable.go 2022-03-09 01:52:36.000000000 +0800 +++ docker-registry-2.8.2+ds1/registry/storage/blobwriter_resumable.go 2023-05-11 18:11:57.000000000 +0800 @@ -1,3 +1,4 @@ +//go:build !noresumabledigest // +build !noresumabledigest package storage diff -Nru -w docker-registry-2.8.1+ds1/registry/storage/driver/gcs/gcs.go docker-registry-2.8.2+ds1/registry/storage/driver/gcs/gcs.go --- docker-registry-2.8.1+ds1/registry/storage/driver/gcs/gcs.go 2022-03-09 01:52:36.000000000 +0800 +++ docker-registry-2.8.2+ds1/registry/storage/driver/gcs/gcs.go 2023-05-11 18:11:57.000000000 +0800 @@ -10,6 +10,7 @@ // Note that the contents of incomplete uploads are not accessible even though // Stat returns their length // +//go:build include_gcs // +build include_gcs package gcs diff -Nru -w docker-registry-2.8.1+ds1/registry/storage/driver/inmemory/mfs.go docker-registry-2.8.2+ds1/registry/storage/driver/inmemory/mfs.go --- docker-registry-2.8.1+ds1/registry/storage/driver/inmemory/mfs.go 2022-03-09 01:52:36.000000000 +0800 +++ docker-registry-2.8.2+ds1/registry/storage/driver/inmemory/mfs.go 2023-05-11 18:11:57.000000000 +0800 @@ -279,6 +279,9 @@ } func (f *file) ReadAt(p []byte, offset int64) (n int, err error) { + if offset >= int64(len(f.data)) { + return 0, io.EOF + } return copy(p, f.data[offset:]), nil } diff -Nru -w docker-registry-2.8.1+ds1/registry/storage/driver/middleware/cloudfront/middleware.go docker-registry-2.8.2+ds1/registry/storage/driver/middleware/cloudfront/middleware.go --- docker-registry-2.8.1+ds1/registry/storage/driver/middleware/cloudfront/middleware.go 2022-03-09 01:52:36.000000000 +0800 +++ docker-registry-2.8.2+ds1/registry/storage/driver/middleware/cloudfront/middleware.go 2023-05-11 18:11:57.000000000 +0800 @@ -1,6 +1,5 @@ // Package middleware - cloudfront wrapper for storage libs // N.B. currently only works with S3, not arbitrary sites -// package middleware import ( @@ -38,7 +37,9 @@ // Optional options: ipFilteredBy, awsregion // ipfilteredby: valid value "none|aws|awsregion". "none", do not filter any IP, default value. "aws", only aws IP goes +// // to S3 directly. "awsregion", only regions listed in awsregion options goes to S3 directly +// // awsregion: a comma separated string of AWS regions. func newCloudFrontStorageMiddleware(storageDriver storagedriver.StorageDriver, options map[string]interface{}) (storagedriver.StorageDriver, error) { // parse baseurl diff -Nru -w docker-registry-2.8.1+ds1/registry/storage/driver/oss/oss.go docker-registry-2.8.2+ds1/registry/storage/driver/oss/oss.go --- docker-registry-2.8.1+ds1/registry/storage/driver/oss/oss.go 2022-03-09 01:52:36.000000000 +0800 +++ docker-registry-2.8.2+ds1/registry/storage/driver/oss/oss.go 2023-05-11 18:11:57.000000000 +0800 @@ -7,6 +7,7 @@ // Because OSS is a key, value store the Stat call does not support last modification // time for directories (directories are an abstraction for key, value stores) // +//go:build include_oss // +build include_oss package oss diff -Nru -w docker-registry-2.8.1+ds1/registry/storage/driver/s3-aws/s3.go docker-registry-2.8.2+ds1/registry/storage/driver/s3-aws/s3.go --- docker-registry-2.8.1+ds1/registry/storage/driver/s3-aws/s3.go 2022-03-09 01:52:36.000000000 +0800 +++ docker-registry-2.8.2+ds1/registry/storage/driver/s3-aws/s3.go 2023-05-11 18:11:57.000000000 +0800 @@ -549,9 +549,9 @@ // Writer returns a FileWriter which will store the content written to it // at the location designated by "path" after the call to Commit. -func (d *driver) Writer(ctx context.Context, path string, append bool) (storagedriver.FileWriter, error) { +func (d *driver) Writer(ctx context.Context, path string, appendParam bool) (storagedriver.FileWriter, error) { key := d.s3Path(path) - if !append { + if !appendParam { // TODO (brianbland): cancel other uploads at this path resp, err := d.S3.CreateMultipartUpload(&s3.CreateMultipartUploadInput{ Bucket: aws.String(d.Bucket), @@ -574,7 +574,7 @@ if err != nil { return nil, parseError(path, err) } - + var allParts []*s3.Part for _, multi := range resp.Uploads { if key != *multi.Key { continue @@ -587,11 +587,20 @@ if err != nil { return nil, parseError(path, err) } - var multiSize int64 - for _, part := range resp.Parts { - multiSize += *part.Size + allParts = append(allParts, resp.Parts...) + for *resp.IsTruncated { + resp, err = d.S3.ListParts(&s3.ListPartsInput{ + Bucket: aws.String(d.Bucket), + Key: aws.String(key), + UploadId: multi.UploadId, + PartNumberMarker: resp.NextPartNumberMarker, + }) + if err != nil { + return nil, parseError(path, err) + } + allParts = append(allParts, resp.Parts...) } - return d.newWriter(key, *multi.UploadId, resp.Parts), nil + return d.newWriter(key, *multi.UploadId, allParts), nil } return nil, storagedriver.PathNotFoundError{Path: path} } diff -Nru -w docker-registry-2.8.1+ds1/registry/storage/paths.go docker-registry-2.8.2+ds1/registry/storage/paths.go --- docker-registry-2.8.1+ds1/registry/storage/paths.go 2022-03-09 01:52:36.000000000 +0800 +++ docker-registry-2.8.2+ds1/registry/storage/paths.go 2023-05-11 18:11:57.000000000 +0800 @@ -435,7 +435,6 @@ // groups of digest folder. It will be as follows: // // <algorithm>/<first two bytes of digest>/<full digest> -// func digestPathComponents(dgst digest.Digest, multilevel bool) ([]string, error) { if err := dgst.Validate(); err != nil { return nil, err diff -Nru -w docker-registry-2.8.1+ds1/version/print.go docker-registry-2.8.2+ds1/version/print.go --- docker-registry-2.8.1+ds1/version/print.go 2022-03-09 01:52:36.000000000 +0800 +++ docker-registry-2.8.2+ds1/version/print.go 2023-05-11 18:11:57.000000000 +0800 @@ -15,7 +15,6 @@ // with version "v2.0" would print the following: // // registry github.com/docker/distribution v2.0 -// func FprintVersion(w io.Writer) { fmt.Fprintln(w, os.Args[0], Package, Version) } diff -Nru -w docker-registry-2.8.1+ds1/version/version.go docker-registry-2.8.2+ds1/version/version.go --- docker-registry-2.8.1+ds1/version/version.go 2022-03-09 01:52:36.000000000 +0800 +++ docker-registry-2.8.2+ds1/version/version.go 2023-05-11 18:11:57.000000000 +0800 @@ -8,7 +8,7 @@ // the latest release tag by hand, always suffixed by "+unknown". During // build, it will be replaced by the actual version. The value here will be // used if the registry is run after a go get based install. -var Version = "v2.8.1+unknown" +var Version = "v2.8.2+unknown" // Revision is filled with the VCS (e.g. git) revision being used to build // the program at linking time. diff -Nru -w docker-registry-2.8.1+ds1/version/version.sh docker-registry-2.8.2+ds1/version/version.sh --- docker-registry-2.8.1+ds1/version/version.sh 2022-03-09 01:52:36.000000000 +0800 +++ docker-registry-2.8.2+ds1/version/version.sh 2023-05-11 18:11:57.000000000 +0800 @@ -17,7 +17,7 @@ // Version indicates which version of the binary is running. This is set to // the latest release tag by hand, always suffixed by "+unknown". During // build, it will be replaced by the actual version. The value here will be -// used if the registry is run after a go get based install. +// used if the registry is run after a go install based install. var Version = "$(git describe --match 'v[0-9]*' --dirty='.m' --always)+unknown" // Revision is filled with the VCS (e.g. git) revision being used to build