Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

swap_index can write out bounds and return uninitialized memory #1

Closed
ammaraskar opened this issue Feb 24, 2021 · 3 comments
Closed

Comments

@ammaraskar
Copy link

ammaraskar commented Feb 24, 2021

Hi there, we (Rust group @sslab-gatech) are scanning crates on crates.io for potential soundness bugs. We noticed that in swap_index, the length returned by the iterator is used to set the length of the vector:

reorder/src/lib.rs

Lines 46 to 56 in 59ad9be

let len=bla.len();
let mut vec=Vec::with_capacity(len);
let arr:&mut [u32]=unsafe{std::slice::from_raw_parts_mut(vec.as_mut_ptr(),bla.len())};
for (i,a) in bla.enumerate(){
arr[a as usize]=i as u32;
}
unsafe{
vec.set_len(len);
}
vec

However, as noted in the documentation for ExactSizeIterator's len() function:

This function has the same safety guarantees as the Iterator::size_hint function.

and then size_hint's documentation says:

size_hint() is primarily intended to be used for optimizations such as reserving space for the elements of the iterator, but must not be trusted to e.g., omit bounds checks in unsafe code. An incorrect implementation of size_hint() should not lead to memory safety violations.

Here's an example of some code that will use uninitialized memory through this method:

#![forbid(unsafe_code)]

use reorder::swap_index;

struct IteratorWithWrongLength();

impl Iterator for IteratorWithWrongLength {
    type Item = u32;
    fn next(&mut self) -> Option<Self::Item> { None }
}
impl ExactSizeIterator for IteratorWithWrongLength {
    fn len(&self) -> usize { 1024 }
}

fn main() {
    let v = swap_index(IteratorWithWrongLength());

    println!("{:?}", v);
}
@ammaraskar ammaraskar changed the title swap_index can return uninitialized memory swap_index can return write out bounds and return uninitialized memory Mar 30, 2021
@ammaraskar ammaraskar changed the title swap_index can return write out bounds and return uninitialized memory swap_index can write out bounds and return uninitialized memory Mar 30, 2021
@Shnatsel
Copy link

Heads up: this issue has been included in the RustSec advisory database. It will be surfaced by tools such as cargo-audit or cargo-deny from now on.

Once a fix is released to crates.io, please open a pull request to update the advisory with the patched version, or file an issue on the advisory database repository.

@tiby312
Copy link
Owner

tiby312 commented Apr 5, 2021

Thank you for the heads up! I submitted a pull request to fix this problem.

@tiby312
Copy link
Owner

tiby312 commented Apr 13, 2021

looks like the pull request made it in. thanks for the help

@tiby312 tiby312 closed this as completed Apr 13, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants