Skip to content

Harden RESTORE validation and block malformed HLL payload misuse in PF operations#1599

Merged
vazois merged 16 commits intomainfrom
vazois/hll-store-corrupt-fix
Mar 4, 2026
Merged

Harden RESTORE validation and block malformed HLL payload misuse in PF operations#1599
vazois merged 16 commits intomainfrom
vazois/hll-store-corrupt-fix

Conversation

@vazois
Copy link
Contributor

@vazois vazois commented Mar 4, 2026

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

  • Fixed RESTORE checksum gate in libs/server/Resp/KeyAdminCommands.cs to validate CRC by default (!SkipRDBRestoreChecksumValidation).
  • Hardened HLL value validation in libs/server/Resp/HyperLogLog/HyperLogLog.cs:
    • Corrected dense/sparse length validation logic.
    • Enforced sparse payload bound (SparseRLESize <= allocated sparse payload).
    • Added full sparse stream semantic validation (IsValidSparseStream) to verify:
      • opcode validity,
      • non-zero register value bounds,
      • exact register-space coverage (no over/under-run).
  • Added defense-in-depth PF-path checks in libs/server/Storage/Session/MainStore/HyperLogLogOps.cs to reject malformed HLL blobs before PFCOUNT/PFMERGE processing.
  • Extended test server factory in test/Garnet.test/TestUtils.cs with skipRDBRestoreChecksumValidation to exercise checksum-skip scenarios.
  • Added/updated security regressions in test/Garnet.test/HyperLogLogTests.cs:
    • corrupted dump payload rejection on RESTORE,
    • zero-CRC payload rejection on RESTORE,
    • corrupted sparse-RLE payload rejection on RESTORE,
    • sparse stream validator rejection cases,
    • checksum-skip mode test asserting malformed restored HLL returns WRONGTYPE for PFCOUNT/PFADD/PFMERGE,
    • representation/length parsing coverage for sparse/dense and 6/14/32-bit parser branches.

Copilot AI review requested due to automatic review settings March 4, 2026 00:07
@vazois vazois force-pushed the vazois/hll-store-corrupt-fix branch from 09cb009 to 0c6a10d Compare March 4, 2026 00:11
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@vazois vazois force-pushed the vazois/hll-store-corrupt-fix branch from d9b3f60 to 21cc936 Compare March 4, 2026 18:49
vazois and others added 2 commits March 4, 2026 11:03
* 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>
@vazois vazois force-pushed the vazois/hll-store-corrupt-fix branch from 21cc936 to e4bf81c Compare March 4, 2026 19:03
@vazois vazois merged commit b5b1030 into main Mar 4, 2026
68 of 71 checks passed
@vazois vazois deleted the vazois/hll-store-corrupt-fix branch March 4, 2026 22:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants