Skip to content

Commit 98cf626

Browse files
TheRawMeatballcart
authored andcommitted
Backport soundness fix (#3685)
#3001 discovered a soundness bug in World::resource_scope, this PR backports the fix with a smaller PR to patch out the bug sooner. Fixes #3147
1 parent ec88fca commit 98cf626

File tree

1 file changed

+12
-6
lines changed
  • crates/bevy_ecs/src/world

1 file changed

+12
-6
lines changed

crates/bevy_ecs/src/world/mod.rs

+12-6
Original file line numberDiff line numberDiff line change
@@ -925,24 +925,30 @@ impl World {
925925
// the ptr value / drop is called when T is dropped
926926
unsafe { column.swap_remove_and_forget_unchecked(0) }
927927
};
928-
// SAFE: pointer is of type T
929-
let value = Mut {
930-
value: unsafe { &mut *ptr.cast::<T>() },
928+
// SAFE: pointer is of type T and valid to move out of
929+
// Read the value onto the stack to avoid potential mut aliasing.
930+
let mut value = unsafe { std::ptr::read(ptr.cast::<T>()) };
931+
let value_mut = Mut {
932+
value: &mut value,
931933
ticks: Ticks {
932934
component_ticks: &mut ticks,
933935
last_change_tick: self.last_change_tick(),
934936
change_tick: self.change_tick(),
935937
},
936938
};
937-
let result = f(self, value);
939+
let result = f(self, value_mut);
940+
assert!(!self.contains_resource::<T>());
938941
let resource_archetype = self.archetypes.resource_mut();
939942
let unique_components = resource_archetype.unique_components_mut();
940943
let column = unique_components
941944
.get_mut(component_id)
942945
.unwrap_or_else(|| panic!("resource does not exist: {}", std::any::type_name::<T>()));
946+
947+
// Wrap the value in MaybeUninit to prepare for passing the value back into the ECS
948+
let mut nodrop_wrapped_value = std::mem::MaybeUninit::new(value);
943949
unsafe {
944-
// SAFE: pointer is of type T
945-
column.push(ptr, ticks);
950+
// SAFE: pointer is of type T, and valid to move out of
951+
column.push(nodrop_wrapped_value.as_mut_ptr() as *mut _, ticks);
946952
}
947953
result
948954
}

0 commit comments

Comments
 (0)