Harden RESTORE validation and block malformed HLL payload misuse in PF operations#1599
Merged
Harden RESTORE validation and block malformed HLL payload misuse in PF operations#1599
Conversation
09cb009 to
0c6a10d
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
This PR strengthens Garnet’s handling of RESTORE payloads and HyperLogLog (PF*) operations to prevent malformed/tampered serialized values from being accepted and later misused during PF processing.
Changes:
- Enables RESTORE checksum validation by default (unless explicitly skipped via server option).
- Hardens HyperLogLog blob validation, including strict sparse-stream semantic checks.
- Adds/extends test utilities and regression tests to cover corrupted dumps and checksum-skip scenarios.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| libs/server/Resp/KeyAdminCommands.cs | Flips RESTORE checksum-validation gate to validate by default. |
| libs/server/Resp/HyperLogLog/HyperLogLog.cs | Tightens HLL length checks and validates sparse opcode stream semantics/coverage. |
| libs/server/Storage/Session/MainStore/HyperLogLogOps.cs | Adds PFCOUNT/PFMERGE defense-in-depth validation before processing blobs. |
| test/Garnet.test/TestUtils.cs | Extends test server factory to optionally skip RESTORE checksum validation. |
| test/Garnet.test/HyperLogLogTests.cs | Adds regression tests for corrupted dumps, sparse-stream validator cases, and checksum-skip behavior. |
Comments suppressed due to low confidence (1)
libs/server/Resp/KeyAdminCommands.cs:81
- RESTORE CRC computation appears to hash the value-type byte as well (valueSpan.Slice(0, valueSpan.Length - 8)), but DUMP computes CRC starting after the value-type byte (payloadToHash slice starts after writing the type byte). With checksum validation now enabled by default, this mismatch would cause RESTORE to reject dumps produced by DUMP. Adjust the RESTORE hash input to skip the leading type byte so both commands use the same CRC coverage.
if (!storeWrapper.serverOptions.SkipRDBRestoreChecksumValidation)
{
// crc is calculated over the encoded payload length, payload and the rdb version bytes
// skip's the value type byte and crc64 bytes
var calculatedCrc = new ReadOnlySpan<byte>(Crc64.Hash(valueSpan.Slice(0, valueSpan.Length - 8)));
// skip's rdb version bytes
var payloadCrc = footer[2..];
if (calculatedCrc.SequenceCompareTo(payloadCrc) != 0)
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
d9b3f60 to
21cc936
Compare
* Bump the nuget-deps group with 14 updates Bumps diskann-garnet from 1.0.23 to 1.0.25 Bumps Microsoft.Extensions.Configuration.Binder from 10.0.2 to 10.0.3 Bumps Microsoft.Extensions.Configuration.Json from 10.0.2 to 10.0.3 Bumps Microsoft.Extensions.Logging from 10.0.2 to 10.0.3 Bumps Microsoft.Extensions.Logging.Configuration from 9.0.8 to 10.0.3 Bumps Microsoft.Extensions.Logging.Console from 9.0.8 to 10.0.3 Bumps Microsoft.IdentityModel.Protocols.OpenIdConnect from 8.6.1 to 8.16.0 Bumps Microsoft.IdentityModel.Validators from 8.6.1 to 8.16.0 Bumps Microsoft.NET.Test.Sdk from 18.0.1 to 18.3.0 Bumps NUnit from 4.1.0 to 4.5.0 Bumps NUnit3TestAdapter from 4.6.0 to 6.1.0 Bumps StackExchange.Redis from 2.9.25 to 2.11.8 Bumps System.IdentityModel.Tokens.Jwt from 8.6.1 to 8.16.0 Bumps System.Numerics.Tensors from 9.0.9 to 10.0.3 --- updated-dependencies: - dependency-name: diskann-garnet dependency-version: 1.0.25 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: nuget-deps - dependency-name: Microsoft.Extensions.Configuration.Binder dependency-version: 10.0.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: nuget-deps - dependency-name: Microsoft.Extensions.Configuration.Json dependency-version: 10.0.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: nuget-deps - dependency-name: Microsoft.Extensions.Logging dependency-version: 10.0.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: nuget-deps - dependency-name: Microsoft.Extensions.Logging.Configuration dependency-version: 10.0.3 dependency-type: direct:production update-type: version-update:semver-major dependency-group: nuget-deps - dependency-name: Microsoft.Extensions.Logging.Console dependency-version: 10.0.3 dependency-type: direct:production update-type: version-update:semver-major dependency-group: nuget-deps - dependency-name: Microsoft.IdentityModel.Protocols.OpenIdConnect dependency-version: 8.16.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: nuget-deps - dependency-name: System.IdentityModel.Tokens.Jwt dependency-version: 8.16.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: nuget-deps - dependency-name: Microsoft.IdentityModel.Validators dependency-version: 8.16.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: nuget-deps - dependency-name: Microsoft.NET.Test.Sdk dependency-version: 18.3.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: nuget-deps - dependency-name: NUnit dependency-version: 4.5.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: nuget-deps - dependency-name: NUnit3TestAdapter dependency-version: 6.1.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: nuget-deps - dependency-name: StackExchange.Redis dependency-version: 2.11.8 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: nuget-deps - dependency-name: System.Numerics.Tensors dependency-version: 10.0.3 dependency-type: direct:production update-type: version-update:semver-major dependency-group: nuget-deps ... Signed-off-by: dependabot[bot] <support@github.com> * fix changes in API * revert unit test upgrade * Add ConfigureAwait(false) to all test await expressions to fix NUnit 4.5 deadlock (#1593) * Initial plan * Add .ConfigureAwait(false) to all await expressions in test files Add .ConfigureAwait(false) to every await expression across 38 test files under test/ to follow best practices for library/test code and avoid potential deadlocks in synchronization contexts. - Handles single-line and multi-line await expressions - Handles ternary await expressions (both branches) - Skips await foreach and await using (already correct) - Excludes Task.Yield() which returns YieldAwaitable (no ConfigureAwait support) - No changes outside test/ directory Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Vasileios Zois <96085550+vazois@users.noreply.github.com> * upgrade nunit * Fix MigrateVector cluster tests for StackExchange.Redis 2.11.8 (#1595) * Initial plan * Fix MigrateVector tests to handle transient errors from StackExchange.Redis 2.11.8 Co-authored-by: vazois <96085550+vazois@users.noreply.github.com> * Fix MigrateVector tests: use Exception catch + specific MOVED message patterns for SE.Redis 2.11.8 Co-authored-by: vazois <96085550+vazois@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: vazois <96085550+vazois@users.noreply.github.com> * revert diskann version --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Vasileios Zois <vazois@microsoft.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Vasileios Zois <96085550+vazois@users.noreply.github.com> Co-authored-by: Tal Zaccai <talzacc@microsoft.com>
21cc936 to
e4bf81c
Compare
badrishc
approved these changes
Mar 4, 2026
badrishc
approved these changes
Mar 4, 2026
badrishc
approved these changes
Mar 4, 2026
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
This PR fixes RESTORE misuse paths that allowed tampered dump payloads to be accepted and later used by HyperLogLog operations, including when checksum validation is explicitly skipped.
Changes
!SkipRDBRestoreChecksumValidation).SparseRLESize <= allocated sparse payload).IsValidSparseStream) to verify:PFCOUNT/PFMERGEprocessing.skipRDBRestoreChecksumValidationto exercise checksum-skip scenarios.RESTORE,RESTORE,RESTORE,WRONGTYPEforPFCOUNT/PFADD/PFMERGE,