mirror of
https://github.com/rust-osdev/uefi-rs
synced 2026-08-26 18:26:05 -04:00
media/file: clamp firmware-reported read length in read_chunked
`read_chunked` trusted the byte count reported by the read callback. A firmware reporting more than the requested size made `remaining_size` underflow and advanced `output_ptr` past the end of the caller buffer, causing out-of-bounds writes on the following chunk. Clamp the reported length to the requested size.
This commit is contained in:
parent
e06b2e8330
commit
b17551c70e
1 changed files with 18 additions and 0 deletions
|
|
@ -177,6 +177,10 @@ where
|
|||
let status = read(output_ptr, &mut read_size);
|
||||
|
||||
if status.is_success() {
|
||||
// Never trust a firmware-reported length larger than what we
|
||||
// requested; otherwise the pointer/size arithmetic below would
|
||||
// run out of bounds.
|
||||
let read_size = read_size.min(requested_read_size);
|
||||
total_read_size += read_size;
|
||||
remaining_size -= read_size;
|
||||
// SAFETY: The memory is valid.
|
||||
|
|
@ -282,4 +286,18 @@ mod tests {
|
|||
assert_eq!(read_chunked(&mut buffer, 10, read), Ok(0));
|
||||
assert_eq!(buffer, [0; 10]);
|
||||
}
|
||||
|
||||
// Regression test: a callback (i.e. firmware) reporting a read length
|
||||
// larger than requested must not cause `remaining_size` to underflow or
|
||||
// `output_ptr` to walk out of bounds. The over-reported length is clamped.
|
||||
#[test]
|
||||
fn test_file_read_chunked_over_report() {
|
||||
// A misbehaving read that always reports 2 bytes more than requested.
|
||||
let read = |_buf: *mut u8, buf_size: &mut usize| {
|
||||
*buf_size += 2;
|
||||
Status::SUCCESS
|
||||
};
|
||||
let mut buffer = [0u8; 8];
|
||||
assert_eq!(read_chunked(&mut buffer, 4, read), Ok(8));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue