harden: collection count validation in persistence deserialization - #124
Merged
Conversation
adds MAX_COLLECTION_COUNT (100M) and validate_collection_count() to reject corrupt count fields before entering iteration loops. previously capped_capacity only limited pre-allocation but the loop itself would iterate up to u32::MAX times from a crafted file. covers aof record deserialization, aof rewriter, and snapshot reader for all collection types (list, set, hash, sorted set).
kacy
added a commit
that referenced
this pull request
Feb 19, 2026
adds MAX_COLLECTION_COUNT (100M) and validate_collection_count() to reject corrupt count fields before entering iteration loops. previously capped_capacity only limited pre-allocation but the loop itself would iterate up to u32::MAX times from a crafted file. covers aof record deserialization, aof rewriter, and snapshot reader for all collection types (list, set, hash, sorted set).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
summary
adds
MAX_COLLECTION_COUNT(100M) andvalidate_collection_count()to thepersistence format module. all deserialization loops that iterate
0..countnow validate the count before entering the loop.
previously,
capped_capacityonly limitedVec::with_capacitypre-allocation— the loop itself would still iterate up to
u32::MAX(~4.3 billion) timesfrom a crafted or corrupt file. a corrupt count field could cause the server to
spin for hours during AOF replay or snapshot loading.
the validation covers:
read_string_list()(used by SADD, SREM, HDEL, ZREM)from_bytes()inline loops (LPUSH/RPUSH, ZADD, HSET)read_payload_for_tag()(all collection tags)the 100M cap is generous enough that no realistic workload would hit it, while
catching obviously corrupt values that would otherwise cause unbounded iteration.
what was tested
all 95 existing persistence tests pass (
cargo test -p ember-persistence --features encryption,vector).design considerations
follows the same pattern established for vectors (
MAX_PERSISTED_VECTOR_COUNT).the constant lives in
format.rsalongsidecapped_capacitysince both aredeserialization safety guards.