Skip to content

Validate CRC32C checksum values before decoding - #3658

Open
wasphin wants to merge 1 commit into
apache:masterfrom
wasphin:fix-crc32c-value-validation
Open

wasphin wants to merge 1 commit into
apache:masterfrom
wasphin:fix-crc32c-value-validation

Conversation

@wasphin

@wasphin wasphin commented Oct 25, 2026

Copy link
Copy Markdown
Member

What problem does this PR solve?

Problem Summary:

CRC32C verification assumes a four-byte checksum and reads it through a uint32_t pointer. Invalid lengths reach a CHECK, and the byte buffer need not provide uint32_t alignment.

What is changed and the side effects?

Changed:

  • Return false for checksum values whose length is not four bytes.
  • Decode the checksum with memcpy before verification.
  • Cover short and long checksum values, restoration of a valid value, and absence of CHECK failures.

Side effects:

  • Performance effects: Skips checksum computation for invalid value lengths.
  • Breaking backward compatibility: None for valid inputs.

Check List:

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

The new test uses logging APIs unavailable with glog enabled, causing compilation failure in that configuration.

1 open issue
What changed in this PR

This PR hardens bRPC’s CRC32C verification against malformed checksum lengths and unaligned byte buffers while preserving valid-input behavior.

Changes:

  • Reject checksum values that are not four bytes before computing the checksum.
  • Decode checksum bytes with memcpy instead of a pointer cast.
  • Add regression coverage for invalid lengths, valid-value restoration, and absence of CHECK failures.
File Description
test/​brpc_checksum_unittest.cpp Adds malformed-length regression coverage and scoped log capture.
src/​brpc/​policy/​crc32c_checksum.cpp Validates checksum length and safely decodes checksum bytes.

Review effort: Balanced

Comment on lines +64 to +79
logging::StringSink logs;
{
logging::LogSink* previous = logging::SetLogSink(&logs);
BUTIL_SCOPE_EXIT { logging::SetLogSink(previous); };
for (size_t size = 0; size <= 8; ++size) {
if (size == valid.size()) {
continue;
}
const std::string invalid(size, '\0');
accessor.set_checksum_value(invalid.data(), invalid.size());
EXPECT_FALSE(brpc::policy::Crc32cVerify(in)) << "size=" << size;
}
accessor.set_checksum_value(valid.data(), valid.size());
EXPECT_TRUE(brpc::policy::Crc32cVerify(in));
}
EXPECT_EQ(std::string::npos, logs.find("Check failed: val.size()"));
@chenBright
chenBright requested a balanced review from Copilot October 26, 2026 03:10

This comment was marked as low quality.

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.

2 participants