From dd5809939058008a526cca484aa65d07c3846a8e Mon Sep 17 00:00:00 2001 From: Eugene Blikh Date: Tue, 26 May 2026 00:10:45 +0300 Subject: [PATCH] =?UTF-8?q?patches:=20core-go-checksum=20=E2=80=94=20fix?= =?UTF-8?q?=20the=20actual=20sigv4=20bug,=20not=20flexible-checksums?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous version of the patch set RequestChecksumCalculation=WhenRequired, which targeted the flexible-checksum middleware. That layer never causes the seek; the bug is in the sigv4 dynamic-payload middleware, which only uses UnsignedPayload over HTTPS. With s3-insecure=true to internal Garage the SDK takes the ComputePayloadSHA256 branch and seeks the non-seekable body. Updated patch: - Swaps ComputePayloadHash middleware for v4.UnsignedPayload{} via opts.APIOptions in objects.NewClient — forces unsigned payload regardless of TLS. - Adds s3.WithSigV4SigningRegion(region) to NewFromConfig so the V1 endpoint resolver can't override the signing region back to "default". Mirrors phoebe-lab/srht/patches/core-go-checksum.patch (d8feacd). --- patches/core-go-checksum.patch | 37 ++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/patches/core-go-checksum.patch b/patches/core-go-checksum.patch index aca2ed7e359b8a2ed2b7813eaaf6dd88aecb410a..41e8c96622b972e9fef4c0ed46fef3bcde27bf33 100644 --- a/patches/core-go-checksum.patch +++ b/patches/core-go-checksum.patch @@ -1,16 +1,37 @@ diff --git a/objects/middleware.go b/objects/middleware.go -index efdb4b5..520781b 100644 +index efdb4b5..b14330e 100644 --- a/objects/middleware.go +++ b/objects/middleware.go -@@ -88,6 +88,11 @@ func NewClient(conf ini.File) (*s3.Client, error) { +@@ -7,9 +7,11 @@ import ( + "net/http" + + "github.com/aws/aws-sdk-go-v2/aws" ++ v4 "github.com/aws/aws-sdk-go-v2/aws/signer/v4" + "github.com/aws/aws-sdk-go-v2/credentials" + "github.com/aws/aws-sdk-go-v2/service/s3" + "github.com/aws/smithy-go/endpoints" ++ smithymw "github.com/aws/smithy-go/middleware" + "github.com/vaughan0/go-ini" + + "git.sr.ht/~sircmpwn/core-go/config" +@@ -87,7 +89,19 @@ func NewClient(conf ini.File) (*s3.Client, error) { + return s3.NewFromConfig(aws.Config{ Region: region, Credentials: creds, - }, func(opts *s3.Options) { -+ // Patched (phoebe-lab): AWS SDK v2 defaults to WhenSupported, which seeks -+ // non-seekable PutObject bodies (pages Publish, builds artifact upload) -+ // for checksum computation. Use WhenRequired to skip pre-flight hashing. -+ opts.RequestChecksumCalculation = aws.RequestChecksumCalculationWhenRequired -+ opts.ResponseChecksumValidation = aws.ResponseChecksumValidationWhenRequired +- }, func(opts *s3.Options) { ++ }, s3.WithSigV4SigningRegion(region), func(opts *s3.Options) { ++ // Patched (phoebe-lab): pages Publish + builds artifact upload pass ++ // non-seekable bodies (tar.Reader, io.LimitReader) to PutObject. The ++ // SDK's default dynamic-payload middleware only uses UnsignedPayload ++ // over HTTPS; over HTTP (s3-insecure=true to internal Garage) it ++ // falls through to ComputePayloadSHA256, which seeks the body and ++ // fails. Force UnsignedPayload unconditionally. The above ++ // WithSigV4SigningRegion pins the sigv4 region so the V1 endpoint ++ // resolver doesn't override it back to "default". ++ opts.APIOptions = append(opts.APIOptions, func(stack *smithymw.Stack) error { ++ _, err := stack.Finalize.Swap("ComputePayloadHash", &v4.UnsignedPayload{}) ++ return err ++ }) opts.BaseEndpoint = aws.String(scheme + upstream) opts.EndpointResolverV2 = &S3Resolver{ conf,