Skip to content

fix(avro): key projection cache on Avro node to avoid OOB read - #1022

Merged
wgtmac merged 2 commits into
apache:mainfrom
gty404:fix/avro-projection-cache-key
Oct 22, 2026
Merged

wgtmac merged 2 commits into
apache:mainfrom
gty404:fix/avro-projection-cache-key

Conversation

@gty404

@gty404 gty404 commented Oct 15, 2026

Copy link
Copy Markdown
Contributor

Summary

  • DecodeStructToBuilder cached the Avro-field-index to projection-index mapping keyed on projections.data() only. All empty-struct projections share the same (null) data(), so a second empty struct with more Avro fields reused a cached vector sized for the first one and read out of bounds, which could end in a wild-pointer dispatch via StructBuilder::field_builder.
  • The cache key is now {projections.data(), avro_node}. The mapping is built and validated before being cached, and a projected field index outside the Avro record's field count returns InvalidArgument.

Test plan

  • New AvroReaderTest.ProjectEmptyStructsOfDifferentWidths: file with two struct columns of 1 and 6 fields, both read back as empty structs through the direct decoder
  • Test crashes (SIGSEGV) without the fix and passes with it
  • Full avro_test suite passes (196 tests)

The avro-to-projection cache was keyed on projections.data() only. All
empty-struct projections share the same (null) data(), so a second empty
struct with more Avro fields reused a cached vector sized for the first
and read out of bounds. Include the Avro node in the key and reject
out-of-range projected field indexes.
@gty404
gty404 force-pushed the fix/avro-projection-cache-key branch from fc62829 to 9fa7751 Compare October 15, 2026 09:13
Comment thread src/iceberg/avro/avro_direct_decoder.cc

@shangxinli shangxinli 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.

The new DirectDecoderTest asserts the cache mapping sizes directly, so it no longer depends on the sanitizer leg to catch a regression.

@wgtmac

wgtmac commented Oct 22, 2026

Copy link
Copy Markdown
Member

Thanks @gty404 for fixing this and @shangxinli for the quick review!

@wgtmac
wgtmac merged commit 1b1232b into apache:main Oct 22, 2026
15 checks passed
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