[
https://issues.apache.org/jira/browse/AVRO-4276?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Ismaël Mejía updated AVRO-4276:
-------------------------------
Description:
BinaryDecoder::doDecodeItemCount() in lang/c++/impl/BinaryDecoder.cc does not
reject INT64_MIN as a block count. While the -(result + 1) + 1 idiom (added in
AVRO-4228) correctly avoids undefined behavior during negation, it converts
INT64_MIN to 2^63 as the item count. Callers such as Generic.cc then attempt
vector::resize(2^63), which will throw std::bad_alloc since no system can
allocate that much memory.
The zigzag encoding of INT64_MIN is a valid 10-byte varint (FF FF FF FF FF FF
FF FF FF 01), so the decoder can encounter this value when reading malformed or
corrupted data. Rather than propagating an impossibly large count that
inevitably fails downstream, the decoder should reject it early with a clear
error.
The C binding already rejects INT64_MIN explicitly (AVRO-4275). The C++ binding
should do the same for consistency and robustness.
Fix: Guard against INT64_MIN before negation in doDecodeItemCount(), and
simplify the negation to -result (safe once INT64_MIN is excluded).
was:
BinaryDecoder::doDecodeItemCount() in lang/c++/impl/BinaryDecoder.cc does not
reject INT64_MIN as a block count. While the -(result + 1) + 1 idiom (added in
AVRO-4228) avoids undefined behavior, it silently converts INT64_MIN to 2^63 as
the item count. Callers such as Generic.cc then attempt vector::resize(2^63),
triggering std::bad_alloc and crashing the process.
An attacker can craft a 10-byte varint (FF FF FF FF FF FF FF FF FF 01, zigzag
encoding of INT64_MIN) as an array or map block count to trigger this denial of
service.
The C binding already rejects INT64_MIN explicitly (AVRO-4275). The C++ binding
should do the same.
Fix: Guard against INT64_MIN before negation in doDecodeItemCount(), and
simplify the negation to -result (safe once INT64_MIN is excluded).
Summary: [C++] BinaryDecoder::doDecodeItemCount() should reject
INT64_MIN block count (was: [C++] BinaryDecoder::doDecodeItemCount() missing
INT64_MIN rejection allows DoS via crafted block count)
> [C++] BinaryDecoder::doDecodeItemCount() should reject INT64_MIN block count
> ----------------------------------------------------------------------------
>
> Key: AVRO-4276
> URL: https://issues.apache.org/jira/browse/AVRO-4276
> Project: Apache Avro
> Issue Type: Bug
> Components: c++
> Reporter: Ismaël Mejía
> Priority: Major
>
> BinaryDecoder::doDecodeItemCount() in lang/c++/impl/BinaryDecoder.cc does not
> reject INT64_MIN as a block count. While the -(result + 1) + 1 idiom (added
> in AVRO-4228) correctly avoids undefined behavior during negation, it
> converts INT64_MIN to 2^63 as the item count. Callers such as Generic.cc then
> attempt vector::resize(2^63), which will throw std::bad_alloc since no system
> can allocate that much memory.
> The zigzag encoding of INT64_MIN is a valid 10-byte varint (FF FF FF FF FF FF
> FF FF FF 01), so the decoder can encounter this value when reading malformed
> or corrupted data. Rather than propagating an impossibly large count that
> inevitably fails downstream, the decoder should reject it early with a clear
> error.
> The C binding already rejects INT64_MIN explicitly (AVRO-4275). The C++
> binding should do the same for consistency and robustness.
> Fix: Guard against INT64_MIN before negation in doDecodeItemCount(), and
> simplify the negation to -result (safe once INT64_MIN is excluded).
--
This message was sent by Atlassian Jira
(v8.20.10#820010)