Skip to content

CRC64NVME + COMPOSITE is silently canonicalised to FULL_OBJECT instead of rejected #50

Description

@Vonng

Expected Behavior

CreateMultipartUpload with x-amz-checksum-algorithm: CRC64NVME and
x-amz-checksum-type: COMPOSITE should be rejected. AWS's
algorithm/type matrix
lists CRC-64/NVME as supporting the full object type only, and the API reference states that
CRC64NVME "is always a full object checksum".

Current Behavior

The combination is accepted and silently canonicalised to a full object checksum.

internal/hash/checksum.go

func NewChecksumType(alg, objType string) ChecksumType {
	full := ChecksumFullObject
	switch objType {
	case xhttp.AmzChecksumTypeFullObject:
	case xhttp.AmzChecksumTypeComposite, "":
		full = 0
	...
	case "CRC64NVME":
		// AWS seems to ignore full value, and just assume it.
		return ChecksumCRC64NVME
	}

and

func (c ChecksumType) FullObjectRequested() bool {
	return c&(ChecksumFullObject) == ChecksumFullObject || c.Is(ChecksumCRC64NVME)
}

so the requested COMPOSITE mode is discarded and the upload behaves as full object
everywhere downstream.

This became externally visible after the #31 fix: an upload declaring CRC64NVME +
COMPOSITE and completing without part checksums in the body now returns 200 where it
previously returned 400 InvalidPart. The patch follows MinIO's own canonical internal
state consistently - the underlying inconsistency is that the invalid combination is
accepted at initiation in the first place.

Impact

No integrity impact: the resulting object gets a correct full object CRC64NVME checksum, and
ListParts / HeadObject report FULL_OBJECT. The problem is that a client asking for a
combination AWS rejects gets a silent substitution instead of an error, so it cannot tell
that it did not get what it asked for.

Possible Solution

Reject CRC64NVME + COMPOSITE at CreateMultipartUpload (and on PutObject), matching
AWS. This is a behaviour change for requests clients can send today, so it needs a
deliberate decision rather than a silent tightening - hence a separate issue rather than
folding it into the #31 fix.

Context

Found during adversarial review of the #31 fix.

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