Description
I tried this code:
(source: @davidzeng0 from the Community Discord server)
https://play.rust-lang.org/?version=stable&mode=release&edition=2021&gist=198b86fbcfb8144e6fbb39d037f95f4e
use std::io::{Read, BufReader, Result};
pub struct MalformedRead {}
impl Read for MalformedRead {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
Ok(buf.len() * 20)
}
}
fn main() {
let mut reader = BufReader::new(MalformedRead {});
let mut buf = [0u8; 1024];
for _ in 0..8 {
let read = reader.read(&mut buf).unwrap();
dbg!(read);
}
reader.read(&mut buf).unwrap();
dbg!(buf);
}
I expected to see this happen: panic, out of bounds read
Instead, this happened:
In debug: SEGMENTATION VIOLATION
In release: Heap buffer overflow
In miri: Undefined Behavior: out-of-bounds pointer use: alloc893 has size 8192, so pointer to 163840 bytes starting at offset 0 is out-of-bounds
Meta
Stable (1.75.0) and Nightly (1.77.0-nightly 2024-02-01 bf3c6c5) have the issue.
Issue
BufReader
uses read_buf
to read from the Read
er, using the BorrowedBuf
's len as the filled value.
rust/library/std/src/io/buffered/bufreader/buffer.rs
Lines 114 to 118 in bf3c6c5
The default_read_buf
function calls advance(n)
with the dodgy read amount.
rust/library/std/src/io/mod.rs
Lines 580 to 584 in bf3c6c5
BufReader
uses the filled
value as the upper bound of the read buffer.