Showing content from https://github.com/rust-lang/rust/issues/80894 below:
Heap buffer overflow in `read_to_end_with_reservation()` · Issue #80894 · rust-lang/rust · GitHub
fn read_to_end_with_reservation<R, F>( r: &mut R, buf: &mut Vec<u8>, mut reservation_size: F, ) -> Result<usize> where R: Read + ?Sized, F: FnMut(&R) -> usize, { let start_len = buf.len(); let mut g = Guard { len: buf.len(), buf }; let ret; loop { if g.len == g.buf.len() { unsafe { // FIXME(danielhenrymantilla): #42788 // // - This creates a (mut) reference to a slice of // _uninitialized_ integers, which is **undefined behavior** // // - Only the standard library gets to soundly "ignore" this, // based on its privileged knowledge of unstable rustc // internals; g.buf.reserve(reservation_size(r)); let capacity = g.buf.capacity(); g.buf.set_len(capacity); r.initializer().initialize(&mut g.buf[g.len..]); } } match r.read(&mut g.buf[g.len..]) { Ok(0) => { ret = Ok(g.len - start_len); break; } Ok(n) => g.len += n, Err(ref e) if e.kind() == ErrorKind::Interrupted => {} Err(e) => { ret = Err(e); break; } } } ret }
At line 393, the guard object's .len
field is incremented by the value returned from a read implementation. If a questionable Read
returns a value larger than the buffer size, it will take that value and set the length of the vector over the boundary.
This bug is reachable from Read::read_to_end()
and Read::read_to_string()
.
Here is a playground link that demonstrates the bug. It segfaults with double free or corruption (out)
.
the8472, 197g, danielhenrymantilla and taiki-e
RetroSearch is an open source project built by @garambo
| Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4