Skip to content

Prevent buffer builder length overflow in MutableBuffer::extend_zeros#9820

Merged
alamb merged 4 commits intoapache:mainfrom
alamb:codex/buffer-builder-reserve-overflow
Apr 28, 2026
Merged

Prevent buffer builder length overflow in MutableBuffer::extend_zeros#9820
alamb merged 4 commits intoapache:mainfrom
alamb:codex/buffer-builder-reserve-overflow

Conversation

@alamb
Copy link
Copy Markdown
Contributor

@alamb alamb commented Apr 25, 2026

Which issue does this PR close?

  • None.

Rationale for this change

BufferBuilder reserve paths relied on unchecked usize arithmetic when calculating the required byte length. In optimized builds, very large requested lengths could wrap before capacity growth.

What changes are included in this PR?

This adds checked arithmetic for MutableBuffer byte length calculations used by reserve and zero-extension paths.

Are these changes tested?

Yes. This adds regression coverage for overflowing BufferBuilder length calculations through reserve, append_n_zeroed, and advance.

Are there any user-facing changes?

Invalid requested lengths whose byte size cannot be represented without overflow now panic consistently. There are no API changes.

@github-actions github-actions Bot added the arrow Changes to the arrow crate label Apr 25, 2026
@alamb alamb marked this pull request as ready for review April 25, 2026 04:02
let new_len = self
.len
.checked_add(additional)
.expect("buffer length overflow");
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.

Introducing internal panics is not ideal, tho clearly better than UB. How should library users code defensively to avoid panic, and how can we make their life easier?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree panics are not good and should be avoided when possible

We had a bit of a philosophical debate about this earlier (when to panic vs Error) and the conclusion we came to got codified in this doc, which I think is relevant here: https://github.com/apache/arrow-rs#guidelines-for-panic-vs-result

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically, do we force all downstream consumers to check for what is very likely an error that will never happen? I think the answer depends on opinion

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.

Yeah... arguably the guidelines say we should be returning an error here (because asking for too many entries is a form of invalid input), but it certainly complicates the API. I don't know if there's a way to provide a fallible version of this API, for paranoid consumers to use?

I do agree it should be a very rare error, but I've also been unpleasantly surprised at how often 32-bit StringArray offsets blow up in practice.

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.

These are 64-bit values right? Probably ok to leave it as a panic because last I knew most hardware cannot physically index more than 48 bits of virtual memory and most operating systems cap the size of any one memory mapping to a few TB of contiguous virtual address space (even one not backed by memory).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think usize is 64 bits on 64-bit architectures and 32 bits on 32-bit architectures

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do agree it should be a very rare error, but I've also been unpleasantly surprised at how often 32-bit StringArray offsets blow up in practice.

Yeah, i32 (2GB strings) is shockingly common

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if there's a way to provide a fallible version of this API, for paranoid consumers to use?

I mean we could add a try_extend_zeros or something 🤔

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.

Yeah, I agree it might be nice to add some try_ functions and then document that the current versions might panic.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I filed a ticket to consider adding new try_ variants

I also pushed a bunch of documentation updates to this PR to document that the APIs panic in certain cases

@alamb alamb changed the title Prevent buffer builder length overflow Prevent buffer builder length overflow in MutableBuffer::extend_zeros Apr 28, 2026
@alamb
Copy link
Copy Markdown
Contributor Author

alamb commented Apr 28, 2026

@scovich or @etseidl I would like to get this into the 58.2.0 release if possible -- I realize we can continue to improve the PR, but I think this is better than what is on main. As @scovich says:

Introducing internal panics is not ideal, tho clearly better than UB.

If you agree can I ask one of you to approve this PR so I can merge it?

Copy link
Copy Markdown
Contributor

@etseidl etseidl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. This is better, and we can worry about further improvements later.

@alamb
Copy link
Copy Markdown
Contributor Author

alamb commented Apr 28, 2026

Awesome - with that I think I have all the content we need for the release. I'll move to making a RC

@alamb alamb merged commit 3c4311c into apache:main Apr 28, 2026
27 checks passed
@alamb alamb deleted the codex/buffer-builder-reserve-overflow branch April 28, 2026 20:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

arrow Changes to the arrow crate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants