-
-
Notifications
You must be signed in to change notification settings - Fork 97
Open
Description
The source of unsoundness
Lines 16 to 20 in 8e3054a
pub fn cast_slice<T>(slice: &[T]) -> &[u8] { | |
let len = std::mem::size_of::<T>() * slice.len(); | |
let ptr = slice.as_ptr(); | |
unsafe { std::slice::from_raw_parts(ptr as _, len) } | |
} |
cast_slice
would cast any type to byte slice which is unsound. e.g., If type T
contains padding bytes, read the returned byte slice would lead to uninitialized memory read. Similar issue could happen in cast_vec
.
To reproduce the bug
use rendy_core::cast_slice;
#[derive(Copy, Clone, Debug)]
pub struct A {
a: i8,
b: i32,
c: i8,
}
fn main() {
let int_array: [i32; 10] = [2; 10];
let int_byte = cast_slice(&int_array);
println!("{:?}", int_byte); // it's ok to read it because i32 won't contain padding bytes
let sa = A { a: 10, b: 11, c: 12 };
let xsa = [sa; 10];
let xsa_byte = cast_slice(&xsa);
println!("{:?}", xsa_byte); // it is dangerous to read it because struct A here contains padding bytes
}
run it with Miri
error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory
It is unsound to have UB happen in safe code.
Ideas about fixing the bug
Here I suggest to apply a trait bound such as Pod which could limit the type to be casted to byte slice.
Metadata
Metadata
Assignees
Labels
No labels