Skip to content

CopyObject server-side checksum can cover transformed data when compression is enabled #63

Description

@Vonng

Problem

Reviewing #46 exposed a separate checksum-placement problem in CopyObject.

When CopyObject needs a server-computed destination checksum and destination compression is enabled, the current handler starts newS2CompressReader and later attaches AddServerSideChecksumHasher to srcInfo.Reader. That reader represents the storage stream, not necessarily the logical S3 plaintext stream. The compression goroutine can also begin consuming input as soon as it is created.

Static data-flow therefore indicates that the stored checksum can cover compressed bytes, or miss bytes consumed before the hasher is attached, instead of covering the logical destination object. This needs an API-level reproduction before the final patch is accepted.

Relevant code:

  • cmd/object-handlers.go: destination compression and AddServerSideChecksumHasher
  • cmd/object-api-utils.go: newS2CompressReader and PutObjReader
  • cmd/erasure-object.go: RawServerSideChecksumResult persistence

Relationship to #46

#46 will intentionally fix only UploadPart and UploadPartCopy. It will establish one shared internal invariant for later fixes:

  1. PutObjReader retains a dedicated logical plaintext checksum reader, distinct from the storage reader.
  2. A fallback server-side hasher is installed in the handler before compression or encryption can consume data.
  3. The object layer validates the effective algorithm and persists the result.

The CopyObject fix should reuse that exact mechanism in a separate PR. It must not add a second checksum-reader abstraction or attach the hasher later in the object layer.

Proposed direction

  • Reuse the unexported checksum reader introduced by UploadPart requires a per-part checksum header that AWS S3 computes server-side #46.
  • Preserve the pre-compression CopyObject reader as the logical checksum source.
  • Install the server-side hasher before newS2CompressReader starts.
  • Keep supplied client checksum validation unchanged.
  • Verify that the checksum returned by HEAD/GET covers logical object bytes for compressed and encrypted destinations.

Acceptance criteria

  • API-level reproduction of the current compressed CopyObject behavior.
  • Correct server-computed CRC32, CRC32C, CRC64NVME, SHA1, and SHA256 where supported.
  • Tests for default, compressed, encrypted, and compressed plus encrypted modes.
  • Explicit SSE-C and SSE-S3 coverage where applicable.
  • Targeted race test proving no hasher installation occurs after reader consumption begins.
  • No public API or on-disk format change beyond the existing checksum metadata representation.

This issue is deliberately separate from #46 so the multipart P0 can be reviewed, released, and rolled back independently.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status
    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions