-
Notifications
You must be signed in to change notification settings - Fork 19
Description
Hi there, we (Rust group @sslab-gatech) are scanning crates on crates.io for potential soundness bugs. We noticed that in these three code locations, unsafe memory is passed to Copy::copy, Copy::copy_mat and Gemv::gemv:
Lines 30 to 38 in bf6d331
| fn into(self) -> Vec<T> { | |
| let n = self.len() as usize; | |
| let mut x = Vec::with_capacity(n); | |
| unsafe { x.set_len(n); } | |
| Copy::copy(self, &mut x); | |
| x | |
| } |
Lines 121 to 123 in bf6d331
| unsafe { result.data.set_len(len); } | |
| Copy::copy_mat(a, &mut result); |
rust-blas/src/math/matrix_vector.rs
Lines 23 to 29 in bf6d331
| let mut result = Vec::with_capacity(n); | |
| unsafe { result.set_len(n); } | |
| let scale = Default::one(); | |
| let clear = Default::zero(); | |
| let t = Transpose::NoTrans; | |
| Gemv::gemv(t, &scale, self, x, &clear, &mut result); |
Copy and Gemv are currently public and safe traits to implement, maybe they should be marked as unsafe or the individual methods that can receive undefined memory marked as unsafe.
Also note that the Into<Vec<T>> implementation can invoke undefined behavior, see https://doc.rust-lang.org/std/mem/union.MaybeUninit.html#initialization-invariant
As a consequence, zero-initializing a variable of reference type causes instantaneous undefined behavior, no matter whether that reference ever gets used to access memory
which means that just doing something like this can invoke undefined behavior:
#![forbid(unsafe_code)]
use rblas::matrix::Matrix;
use rblas::vector::ops::Copy;
use rblas::vector::Vector;
#[derive(Clone, Debug)]
struct MyType(Box<u64>);
impl Copy for MyType {
fn copy<V, W>(src: &V, dst: &mut W)
where
V: ?Sized + Vector<Self>,
W: ?Sized + Vector<Self>,
{
}
fn copy_mat(src: &Matrix<Self>, dst: &mut Matrix<Self>) {}
}
fn main() {
let vec = vec![MyType(Box::new(42))];
let as_blas_vector = &vec as &Vector<_>;
let back_to_vec: Vec<MyType> = as_blas_vector.into();
}