Hello,
We are working on a static analysis tool designed to detect unsoundness and safety violations in Rust projects. We identified a soundness issue in tensorbase/crates/base/src/mem.rs.
|
pub fn shape_slice<T>(slice: &[u8]) -> &[T] { |
|
pub fn shape_vec<T>(v: Vec<u8>) -> Vec<T> { |
|
pub fn shape_vec_u8<T>(v: Vec<T>) -> Vec<u8> { |
Location:
The vulnerability is located in the public function shape_slice:
pub fn shape_slice<T>(slice: &[u8]) -> &[T] {
unsafe {
std::slice::from_raw_parts(
slice.as_ptr() as *const T,
slice.len() / mem::size_of::<T>(),
)
}
}
This function is pub and located in a pub mod, making it accessible to external users.
Description:
The function casts a byte slice &[u8] (which has an alignment of 1) to a slice of generic type &[T]. However, it does not check if the input slice.as_ptr() satisfies the alignment requirements of T.
According to the safety contract of std::slice::from_raw_parts:
The pointer must be properly aligned.
If a user passes a byte slice that is not aligned to std::mem::align_of::(), creating the returned slice &[T] is immediate Undefined Behavior (UB), even if the data is never read.
Proof of Concept (PoC):
We constructed a PoC where we pass a misaligned byte slice (offset by 1 byte) and attempt to view it as &[u32] (which requires 4-byte alignment).
use std::mem;
use std::slice;
// The vulnerable function from tensorbase/crates/base/src/mem.rs
pub fn shape_slice<T>(slice: &[u8]) -> &[T] {
unsafe {
slice::from_raw_parts(
slice.as_ptr() as *const T,
slice.len() / mem::size_of::<T>(),
)
}
}
fn main() {
// 1. Create a byte array
let bytes: [u8; 16] = [0; 16];
// 2. Create a "misaligned" sub-slice.
// bytes[0] is aligned (stack allocation), so bytes[1] is definitely
// NOT aligned for u32 (which requires 4-byte alignment).
let misaligned_slice = &bytes[1..];
// 3. Trigger UB
// This attempts to create &[u32] at an address like 0x...01
println!("Attempting to create misaligned slice...");
let _u32_slice: &[u32] = shape_slice(misaligned_slice);
println!("If you see this without Miri, UB has occurred silently.");
}
Miri Output:
Running the PoC with Miri (cargo miri run) confirms the issue:
error: Undefined Behavior: constructing invalid value: encountered an unaligned reference (required 4 byte alignment but found 1)
--> .../slice/raw.rs:138:9
|
138 | &*ptr::slice_from_raw_parts(data, len)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned reference (required 4 byte alignment but found 1)
Hello,
We are working on a static analysis tool designed to detect unsoundness and safety violations in Rust projects. We identified a soundness issue in tensorbase/crates/base/src/mem.rs.
tensorbase/crates/base/src/mem.rs
Line 42 in 7b071a8
tensorbase/crates/base/src/mem.rs
Line 53 in 7b071a8
tensorbase/crates/base/src/mem.rs
Line 66 in 7b071a8
Location:
The vulnerability is located in the public function shape_slice:
This function is pub and located in a pub mod, making it accessible to external users.
Description:
The function casts a byte slice &[u8] (which has an alignment of 1) to a slice of generic type &[T]. However, it does not check if the input slice.as_ptr() satisfies the alignment requirements of T.
According to the safety contract of std::slice::from_raw_parts:
The pointer must be properly aligned.
If a user passes a byte slice that is not aligned to std::mem::align_of::(), creating the returned slice &[T] is immediate Undefined Behavior (UB), even if the data is never read.
Proof of Concept (PoC):
We constructed a PoC where we pass a misaligned byte slice (offset by 1 byte) and attempt to view it as &[u32] (which requires 4-byte alignment).
Miri Output:
Running the PoC with Miri (cargo miri run) confirms the issue: