[ 
https://issues.apache.org/jira/browse/AVRO-4295?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18102857#comment-18102857
 ] 

ASF subversion and git services commented on AVRO-4295:
-------------------------------------------------------

Commit ed310ad6b5bea861e715ea8898733d55af9bca0c in avro's branch 
refs/heads/AVRO-4295-csharp-available-bytes from Ismaël Mejía
[ https://gitbox.apache.org/repos/asf?p=avro.git;h=ed310ad6b5 ]

AVRO-4295: [csharp] Bound zero-byte collection elements per datum, not per 
collection

The zero-byte-element item cap (array<null>-style elements that consume no 
input,
which the bytes-remaining check cannot bound) was enforced per collection:
ReadArray/ReadMap and Skip each started their running total from zero. Because a
container file carries its own schema, an attacker can declare a record with 
many
such collection fields, each block individually under the limit but jointly
unbounded, so a tiny payload still drives a huge aggregate allocation.

Track the cumulative zero-byte element count on the DefaultReader instance
(zeroByteItemsRead), reset at the start of each top-level Read<T>, and check it 
in
EnsureCollectionAvailable (now an instance method). The structural and
bytes-remaining checks stay per collection. Adds regression tests for a
multi-field record rejected cumulatively and a within-limit record that still
decodes (resetting between datums).


> [csharp] Bound allocation when decoding length-prefixed values and collections
> ------------------------------------------------------------------------------
>
>                 Key: AVRO-4295
>                 URL: https://issues.apache.org/jira/browse/AVRO-4295
>             Project: Apache Avro
>          Issue Type: Sub-task
>          Components: csharp
>    Affects Versions: 1.11.5, 1.12.1
>            Reporter: Ismaël Mejía
>            Assignee: Ismaël Mejía
>            Priority: Major
>              Labels: pull-request-available
>          Time Spent: 6h
>  Remaining Estimate: 0h
>
> A bytes or string value is encoded as a length prefix followed by that many 
> bytes of data, and an array or map block is encoded as an element count 
> followed by that many items. A malicious or truncated input can declare a 
> very large length or count while carrying little or no actual data, causing a 
> large allocation before the shortfall is noticed. When the source can report 
> how many bytes remain, reject a declared length (or a collection block count) 
> that exceeds the bytes actually available before allocating for it. Companion 
> to AVRO-4241 (Java).
> BinaryDecoder.RemainingBytes() reports the bytes still readable for a 
> seekable stream; ReadBytes/ReadString consult it directly 
> (EnsureAvailableBytes), while DefaultReader.ReadArray/ReadMap consult it via 
> MinBytesPerElement(). EnsureCollectionAvailable tracks the cumulative count 
> and enforces the limits, and the schema-resolution Skip path for arrays and 
> maps is bounded the same way. Negative and out-of-range counts are rejected 
> before the int cast.
> Zero-byte elements (null, or a record with only zero-byte fields) consume no 
> input, so the available-bytes check cannot bound their count: a tiny payload 
> such as {"type":"array","items":"null"} declaring a block count of 
> 200,000,000 would otherwise drive an unbounded allocation. In addition to the 
> available-bytes check this therefore caps the cumulative count of zero-byte 
> elements (default 10,000,000), applies a structural cap (int.MaxValue - 8, 
> further clamped to the runtime's maximum array length) to every 
> non-zero-byte-element collection (which also covers collections read from a 
> source that cannot report the bytes remaining), and bounds the array/map skip 
> paths. When set, the AVRO_MAX_COLLECTION_ITEMS environment variable caps both 
> limits.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to