Skip to content

[MEDIUM] Bound binary array allocation by payload length - #743

Open
OskarEichler wants to merge 1 commit into
ged:masterfrom
OskarEichler:codex/security-bound-binary-array-preallocation
Open

[MEDIUM] Bound binary array allocation by payload length#743
OskarEichler wants to merge 1 commit into
ged:masterfrom
OskarEichler:codex/security-bound-binary-array-preallocation

Conversation

@OskarEichler

Copy link
Copy Markdown
Contributor

Summary

PG::BinaryDecoder::Array trusts declared dimensions when preallocating its first Ruby array. A tiny malformed binary value can therefore request a very large allocation before the decoder discovers that the element data is missing.

This change verifies that the remaining payload contains at least the four-byte length word required for every declared element before allocating the result arrays. Valid payloads are unchanged, and malformed payloads keep the existing premature end error.

Reproduction

The following 20-byte value declares 10,000,000 elements but contains none:

decoder = PG::BinaryDecoder::Array.new(
  elements_type: PG::BinaryDecoder::Integer.new
)
payload = [1, 0, 23, 10_000_000, 1].pack("N5")
decoder.decode(payload)

With current master, Ruby's GC.stat(:malloc_increase_bytes) rose by approximately 80 MiB before ArgumentError was raised. With this patch it rose by about 11 KiB and raised the same error at the same position.

Verification

  • Built the native extension on Ruby 4.0.6 / PostgreSQL libpq 15.
  • Repeated the malformed-header reproduction before and after the patch.
  • Existing composite coder coverage: 89 examples, 0 failures.
  • Full suite baseline on the adjacent COPY fix branch: 1,111 examples, 8 existing local pg_service/libpq 15 failures, 9 pending.
  • git diff --check passes.

Limitations

The focused allocation measurement used Ruby's allocator counters on macOS. No new automated spec is included.

Breaking changes

None. Payloads that cannot contain their declared element count already raise ArgumentError; they now do so before disproportionate allocation.

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.

1 participant