This is an automated email from the ASF dual-hosted git repository.
mgrigorov pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/avro.git
The following commit(s) were added to refs/heads/main by this push:
new f7dfbc0d37 [C] Fix negative block size validation in datafile reader
(#3623)
f7dfbc0d37 is described below
commit f7dfbc0d37608a896ffcc8734a8d64376c463039
Author: Ze Sheng <[email protected]>
AuthorDate: Mon Jan 19 00:21:59 2026 -0600
[C] Fix negative block size validation in datafile reader (#3623)
* [C] Fix negative block size validation in datafile reader
The file_read_block_count() function in datafile.c reads block size
using zigzag encoding, which can produce negative numbers from
malicious Avro container files. These negative values were passed
directly to avro_malloc(), causing allocation failures.
This patch adds validation to reject negative block size values with
a clear error message before attempting memory allocation.
Bug: Negative block size from varint decoding causes
allocation-size-too-big when cast to size_t
Impact: DoS via crafted .avro file
Co-Authored-By: Claude <[email protected]>
* Add NULL checks after malloc/realloc in file_read_block_count
This addresses reviewer feedback about handling allocation failures.
When block_size is a very large positive number, malloc/realloc
will fail and return NULL. Without NULL checks, this would lead
to a null pointer dereference.
Co-Authored-By: Claude Opus 4.5 <[email protected]>
---------
Co-authored-by: Claude <[email protected]>
---
lang/c/src/datafile.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/lang/c/src/datafile.c b/lang/c/src/datafile.c
index c9d4dfeb68..bbcf69493b 100644
--- a/lang/c/src/datafile.c
+++ b/lang/c/src/datafile.c
@@ -451,12 +451,24 @@ static int file_read_block_count(avro_file_reader_t r)
"Cannot read file block count: ");
check_prefix(rval, enc->read_long(r->reader, &len),
"Cannot read file block size: ");
+ if (len < 0) {
+ avro_set_error("Invalid block size: %" PRId64, len);
+ return EINVAL;
+ }
if (r->current_blockdata && len > r->current_blocklen) {
r->current_blockdata = (char *)
avro_realloc(r->current_blockdata, r->current_blocklen, len);
+ if (!r->current_blockdata) {
+ avro_set_error("Cannot allocate block buffer");
+ return ENOMEM;
+ }
r->current_blocklen = len;
} else if (!r->current_blockdata) {
r->current_blockdata = (char *) avro_malloc(len);
+ if (!r->current_blockdata && len > 0) {
+ avro_set_error("Cannot allocate block buffer");
+ return ENOMEM;
+ }
r->current_blocklen = len;
}