ndarray-linalg icon indicating copy to clipboard operation
ndarray-linalg copied to clipboard

Buffer overflow on shape mismatch

Open jturner314 opened this issue 6 years ago • 1 comments

Some functions (including solve_inplace but probably many others) are missing checks that the input arrays have matching shapes. As a result, the current implementation of solve_inplace can lead to buffer overflow if the shapes don't match (e.g. if the number of rows in b is less than the number of rows/columns in a).

Example with ndarray 0.12 and ndarray-linalg 0.10:

extern crate ndarray;
extern crate ndarray_linalg;

use ndarray::array;
use ndarray::prelude::*;
use ndarray_linalg::solve::Solve;

fn main() {
    let a = array![[1., 2.], [3., 4.]];
    let mut b = array![1.];

    // This is a read of uninitialized memory one past the end of `b`. This is
    // undefined behavior, but the point of this print statement is to show
    // that calling `a.solve_inplace(&mut b)` changes the value of the element
    // one past the end of `b`.
    //
    // On my system, this prints `0`, but it could print anything because the
    // memory is uninitialized.
    println!("{}", unsafe { *b.as_ptr().wrapping_offset(1) } );

    // This should panic or return an error because `a` is `2x2` and `b` has
    // length `1`.
    a.solve_inplace(&mut b).unwrap();

    // Prints `[-1.9999999999999998]` on my system, which corresponds to the
    // first element in the solution if `b` was `array![1., 0.]`.
    println!("{}", b);

    // This is another read of uninitialized memory one past the end of `b`.
    // This is undefined behavior, but the point of this print statement is to
    // show that calling `a.solve_inplace(&mut b)` changes the value of the
    // element one past the end of `b`.
    //
    // On my system, this prints `1.4999999999999998`, which corresponds to the
    // second element in the solution if `b` was `array![1., 0.]`.
    println!("{}", unsafe { *b.as_ptr().wrapping_offset(1) } );
}

jturner314 avatar Feb 25 '19 22:02 jturner314

Thanks report!

Some functions (including solve_inplace but probably many others) are missing checks that the input arrays have matching shapes.

It will be easy to fix each case, but I expect the list of bug will be large...

  • If input size of matrix/vector are wrong, then each function panic!
  • Another test generator to check these size mismatch.

termoshtt avatar May 12 '19 18:05 termoshtt