Skip to content

Fix use-after-free in CollisionEnvFCL when a moved world object is copy-on-write cloned - #3797

Open
ohrad-robotics wants to merge 1 commit into
moveit:mainfrom
ohrad-robotics:fix/collision-env-fcl-move-shape-uaf
Open

Fix use-after-free in CollisionEnvFCL when a moved world object is copy-on-write cloned#3797
ohrad-robotics wants to merge 1 commit into
moveit:mainfrom
ohrad-robotics:fix/collision-env-fcl-move-shape-uaf

Conversation

@ohrad-robotics

@ohrad-robotics ohrad-robotics commented Jul 22, 2026

Copy link
Copy Markdown

I was experiencing some rviz crashes while playing around with the moveit_resources_panda_moveit_config demo. I decided to throw Claude at it and uncovered a use-after-free bug in moveit_core. Rviz would crash if I introduced a simple box collision object, moved it so that it was in collision with the manipulator arm, and then tried to move the arm using the .

World::ensureUnique() copy-on-write clones a World::Object when it is mutated while an external shared_ptr to it is still alive (e.g. RViz's MotionPlanningDisplay briefly holding a reference while it live-checks collisions for the goal/start state). CollisionEnvFCL::notifyObjectChange()'s MOVE_SHAPE fast path (#3601) updated the cached FCL collision object's transform in place but never refreshed CollisionGeometryData::ptr.obj, a raw non-owning pointer into the World::Object. Once the pre-move object was destroyed, that pointer was left dangling, and the next collision check reading the object's id through it (CollisionGeometryData::getID()) was a use-after-free - reproducibly crashing RViz.

This PR:

  • Refreshes the cached pointer via the existing FCLGeometry::updateCollisionGeometryData() helper, the same mechanism createCollisionGeometry() already uses for this exact copy-on-write scenario, before applying the transform update.
  • Adds a regression test that forces the copy-on-write path and checks the cached World::Object pointer stays in sync via direct pointer comparison, so it fails deterministically without the fix rather than relying on the process actually crashing.

Description

Please explain the changes you made, including a reference to the related issue if applicable

Checklist

  • Required by CI: Code is auto formatted using clang-format
  • Extend the tutorials / documentation reference
  • Document API changes relevant to the user in the MIGRATION.md notes
  • Create tests, which fail without this PR reference
  • Include a screenshot if changing a GUI
  • While waiting for someone to review your request, please help review another open pull request to support the maintainers

…py-on-write cloned

World::ensureUnique() copy-on-write clones a World::Object when it is
mutated while an external shared_ptr to it is still alive (e.g. RViz's
MotionPlanningDisplay briefly holding a reference while it live-checks
collisions for the goal/start state). CollisionEnvFCL::notifyObjectChange()'s
MOVE_SHAPE fast path (moveit#3601) updated the cached FCL collision object's
transform in place but never refreshed CollisionGeometryData::ptr.obj, a
raw non-owning pointer into the World::Object. Once the pre-move object
was destroyed, that pointer was left dangling, and the next collision
check reading the object's id through it (CollisionGeometryData::getID())
was a use-after-free - reproducibly crashing RViz.

Refresh the cached pointer via the existing
FCLGeometry::updateCollisionGeometryData() helper, the same mechanism
createCollisionGeometry() already uses for this exact copy-on-write
scenario, before applying the transform update.

Adds a regression test that forces the copy-on-write path and checks
the cached World::Object pointer stays in sync via direct pointer
comparison, so it fails deterministically without the fix rather than
relying on the process actually crashing.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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