Skip to content

Unsafe vector overflow #26550

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

Closed
Veedrac opened this issue Jun 24, 2015 · 8 comments
Closed

Unsafe vector overflow #26550

Veedrac opened this issue Jun 24, 2015 · 8 comments

Comments

@Veedrac
Copy link
Contributor

Veedrac commented Jun 24, 2015

This gives undefined behaviour due to overflow:

fn main() {
    let one_iter = Some(0).into_iter();
    let big_iter = std::iter::repeat(0).take(usize::max_value());

    one_iter.chain(big_iter).collect::<Vec<_>>();
}

The problem is the overflow on the addition here:

rust/src/libcollections/vec.rs

Lines 1485 to 1489 in a643092

let mut vector = Vec::with_capacity(1 + lower);
unsafe {
ptr::write(vector.get_unchecked_mut(0), element);
vector.set_len(1);
}

@alexcrichton
Copy link
Member

Could you clarify what the undefined behavior you're seeing is? This is just a standard panic for me:

thread '<main>' panicked at 'capacity overflow', /home/rustbuild/src/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libcore/option.rs:330

@Veedrac
Copy link
Contributor Author

Veedrac commented Jun 24, 2015

Forgot to mention, this only happens on nightly (in release builds).

http://is.gd/OdmHAG

application terminated abnormally with signal 4 (Illegal instruction)

@sfackler
Copy link
Member

The SIGILL is the result of the failure to malloc the entire address space.

I believe the only undefined behavior badness the from_iter logic can run into is if 1 + lower overflows to 0, in which case the get_unchecked_mut call will end up as an out of bounds write.

@sfackler
Copy link
Member

cc @gankro

sfackler added a commit to sfackler/rust that referenced this issue Jun 25, 2015
@Veedrac
Copy link
Contributor Author

Veedrac commented Jun 25, 2015

I believe the only undefined behavior badness the from_iter logic can run into is if 1 + lower overflows to 0, in which case the get_unchecked_mut call will end up as an out of bounds write.

That's what's happening.

I was expecting oom to give a different error, though. To evidence my claim, gdb says it crashes on a null pointer write:

r::ptr::write<i32> (dst=0x0, src=-1) at ../src/libcore/ptr.rs:247
247 ../src/libcore/ptr.rs: No such file or directory.

whereas decreasing the memory a bit to get an OOM errors inside of with_capacity.

@Veedrac
Copy link
Contributor Author

Veedrac commented Jun 25, 2015

@sfackler
Copy link
Member

They're both fixed in #26563

@Veedrac
Copy link
Contributor Author

Veedrac commented Jun 25, 2015

Indeed, sorry.

alexcrichton pushed a commit to alexcrichton/rust that referenced this issue Jul 1, 2015
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