Skip to content

Conversation

james7132
Copy link
Member

@james7132 james7132 commented Aug 12, 2025

Objective

When working with realloc, it's a safety invariant to pass in the existing layout of the allocation that is being reallocated. This may not be the case with newly created Tables. Vec::with_capacity's documentation states that it will return an allocation with enough space for at least capacity elements, not exactly capacity. This means that entities.capacity() may be greater than the provided capacity. As the ThinColumns use this as their capacity, the new Layout fed to realloc will not match the allocation originally provided to alloc. This is unsound.

While investigating this, I also found that we were not validating that the total capacity of BlobArray's layout upon reallocation were less than isize::MAX via array_layout_unchecked.

Solution

Begin Table construction by allocating the entities Vec, and use it's capacity to allocate the columns instead of directly feeding the provided capacity into ThinColumn::with_capacity.

Replace the array_layout_unchecked call with a safe call to array_layout, and panic if it fails.

Testing

Tested this locally against existing unit tests and miri.

@james7132 james7132 added this to the 0.17 milestone Aug 12, 2025
@james7132 james7132 added D-Trivial Nice and easy! A great choice to get started with Bevy A-ECS Entities, components, systems, and events P-Unsound A bug that results in undefined compiler behavior D-Unsafe Touches with unsafe code in some way labels Aug 12, 2025
@alice-i-cecile alice-i-cecile added the S-Needs-Review Needs reviewer attention (from anyone!) to move forward label Aug 14, 2025
Copy link
Contributor

@SkiFire13 SkiFire13 left a comment

Choose a reason for hiding this comment

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

Nit: could this invariant be better documented on Table's definition, each Table creation and Table's realloc?

@hymm
Copy link
Contributor

hymm commented Aug 14, 2025

Am I understanding this comment correctly that currently Vec::with_capacity would always match the capacity requested, but if the allocator changed then it could potentially allocate more space than requested? https://stdrs.dev/nightly/x86_64-unknown-linux-gnu/src/alloc/raw_vec.rs.html#192. Then would this potentially be a problem with how we're allocating the ThinColumn too?

@james7132
Copy link
Member Author

Then would this potentially be a problem with how we're allocating the ThinColumn too?

Unless they change the safety invariants of already established stable APIs, I don't think so. The safety invariant states it just needs to be called with the same Layout that was used to allocate it, and that's what we're already doing / fixing with this PR.

@alice-i-cecile alice-i-cecile added S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it and removed S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Aug 14, 2025
@james7132
Copy link
Member Author

Upon further inspection, it seems like we weren't actually validating one of the safety invariants of array_layout_unchecked in BlobArray::realloc.

Added the comments @SkiFire13 mentioned.

@james7132 james7132 added S-Needs-Review Needs reviewer attention (from anyone!) to move forward and removed S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it labels Aug 15, 2025
@james7132 james7132 requested a review from SkiFire13 August 15, 2025 02:05
Copy link
Contributor

@SkiFire13 SkiFire13 left a comment

Choose a reason for hiding this comment

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

Look good, just left a couple of comments for some typos.

Co-authored-by: Giacomo Stevanato <[email protected]>
@james7132 james7132 removed the S-Needs-Review Needs reviewer attention (from anyone!) to move forward label Aug 15, 2025
@james7132 james7132 enabled auto-merge August 15, 2025 23:33
@james7132 james7132 added this pull request to the merge queue Aug 16, 2025
Merged via the queue into bevyengine:main with commit e9e6299 Aug 16, 2025
50 of 51 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-ECS Entities, components, systems, and events D-Trivial Nice and easy! A great choice to get started with Bevy D-Unsafe Touches with unsafe code in some way P-Unsound A bug that results in undefined compiler behavior
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants