Skip to content

[Bug]: File-per-key path mapping can collide and return another object's data #2980

Description

@feichai0017

Bug Report

On current main (f20b7061), ResolvePathFromKey() is not collision-safe for file-per-key storage.

The path uses only the low 8 bits of std::hash<std::string> for its two directory levels, while SanitizeKey() maps each of /\\:*?"<>| to _. For a fixed tenant, the 10,000 four-character keys built from those characters plus _ all sanitize to the same filename but have only 256 possible directory pairs, so at least two distinct keys must map to the same path.

This is a correctness problem because:

  • writes open the destination with O_TRUNC, so the later key overwrites the earlier file;
  • StorageBackendAdaptor::BatchLoad() deserializes the stored KVEntry without checking that its key matches the requested key;
  • when the colliding keys and values have equal lengths, a read can silently return the other key's value.

The same path helper is used by file-per-key LOCAL_DISK storage and the legacy DISK replica path.

Expected behavior

Distinct object identities must never resolve to the same on-disk object path in normal operation, and reads must reject records whose stored key does not match the requested key.

Proposed direction

Use a stable full-key digest for the filename, retain a legacy-path read fallback for existing files, and validate the deserialized key before copying data to the caller.

Before submitting...

  • Searched existing issues and open PRs for path/key collision reports.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions