Skip to content

Prevent TOCTOU bugs in ComponentsQueuedRegistrator #20016

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

SkiFire13
Copy link
Contributor

Objective

Solution

  • Don't make the force_register_ family of functions always enqueue of the component/resource; instead have them check again whether it was already queued or not.

Testing

  • I added a small regression test but it's non-deterministic: if the bug is fixed it will always pass, but if the bug is presen then it has a (hopefully small) chance of passing. On my PC it failed after ~100 iterations, so hopefully 1000 is enough in CI (assuming it doesn't have single core runners...)

@alice-i-cecile alice-i-cecile added this to the 0.17 milestone Jul 7, 2025
@alice-i-cecile alice-i-cecile added C-Bug An unexpected or incorrect behavior A-ECS Entities, components, systems, and events S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Jul 7, 2025
Copy link
Contributor

@chescock chescock left a comment

Choose a reason for hiding this comment

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

Good catch!

/// The [`TypeId`] must not already be registered or queued as a component.
unsafe fn force_register_arbitrary_component(
/// The [`TypeId`] must not already be registered as a component.
unsafe fn register_arbitrary_component(
Copy link
Contributor

Choose a reason for hiding this comment

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

Why remove force from the names? They're still queuing without first checking that the components are registered, which is a kind of "forcing".

The names queue_register_component and register_arbitrary_component don't do a great job of communicating the difference, although I suppose force_register_arbitrary_component wasn't much better.

Hmm, I wonder if it would make sense to make a future PR to inline these into their callers so that we don't need two names.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I see your point, but at the same time they are no longer really forcing the registration. They are more like register_if_not_enqueued or something like that, but it doesn't sound so good as a name.

}

/// Queues this function to run as a resource registrator.
/// Queues this function to run as a resource registratorif the given
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
/// Queues this function to run as a resource registratorif the given
/// Queues this function to run as a resource registrator if the given

@JaySpruce JaySpruce 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 Jul 8, 2025
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 C-Bug An unexpected or incorrect behavior S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ComponentsQueuedRegistrator::queue_register_component does not ensure components are registered only once
4 participants