Closed Nemo157 closed 1 year ago
Could you please re-check the issue? I committed the potential fix for it.
The DerefMut<Target = Vec<u8>>
still makes me a bit wary, if any reallocating function is called on that there will be similar UB when it realloc's the storage. Skimming through I think this is reachable via push_vertex
.
EDIT: Yeah, reproducer depending on the git repo:
use fyrox::{
core::algebra::Vector3,
scene::mesh::{buffer::VertexBuffer, vertex::SimpleVertex},
};
fn main() {
let vertex = SimpleVertex {
position: Vector3::new(0.0, 0.0, 0.0),
};
let mut buf = VertexBuffer::new(1, vec![vertex]).unwrap();
buf.modify().push_vertex(&vertex).unwrap();
}
error: Undefined Behavior: incorrect layout on deallocation: alloc1459 has size 12 and alignment 4, but gave size 12 and alignment 1
--> /home/nemo157/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/alloc.rs:140:14
|
140 | unsafe { __rust_realloc(ptr, layout.size(), layout.align(), new_size) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect layout on deallocation: alloc1459 has size 12 and alignment 4, but gave size 12 and alignment 1
|
...
= note: inside `std::vec::Vec::<u8>::extend_from_slice` at /home/nemo157/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/vec/mod.rs:2386:9: 2386:39
= note: inside `fyrox::scene::mesh::buffer::VertexBufferRefMut::<'_>::push_vertex::<fyrox::scene::mesh::vertex::SimpleVertex>` at cargo/git/checkouts/fyrox-3b28ccbadb9683b5/a85ad50/src/scene/mesh/buffer.rs:347:13: 349:62
note: inside `main`
--> src/main.rs:11:5
|
11 | buf.modify().push_vertex(&vertex).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Yeah, you absolutely right, I did a potential fix, could you please re-check it?
It is a requirement of
Vec
that it is dropped with a type that has the same alignment as it was allocated with, insideVertexBuffer::new
the passedVec<T>
is type-erased into aVec<u8>
, with most of theT
types being passed having alignment 4 rather thanu8
's alignment 1, resulting in undefined behavior when the value is deallocated.This can be observed by running a minimal testcase under Miri: