-
Notifications
You must be signed in to change notification settings - Fork 140
Open
Description
Description
Hello, I discovered a panic in pdf-rs while fuzzing.
The parser panics with "allocation-size-too-big" when processing a specific input. This panic is caused by unchecked casting of negative i32 values to usize, resulting in an integer overflow and an invalid massive allocation size.(Looks like converting i32 to usize really isn't a good idea......)
Crash Location
- pdf/src/enc.rs:306
- Message: AddressSanitizer: allocation-size-too-big
Fuzz Target
Here are the fuzz target and PoC that I used.
#![no_main]
use libfuzzer_sys::fuzz_target;
use pdf::enc::*;
use std::convert::TryInto;
fn get_i32(data: &[u8], offset: &mut usize) -> i32 {
if *offset + 4 > data.len() {
return 0;
}
let val = i32::from_le_bytes(data[*offset..*offset+4].try_into().unwrap());
*offset += 4;
val
}
fuzz_target!(|data: &[u8]| {
if data.len() < 1 { return; }
let mut offset = 0;
// Use the first byte to determine the filter type
// We want to test:
// 0: ASCIIHexDecode
// 1: ASCII85Decode
// 2: LZWDecode
// 3: FlateDecode
// 4: RunLengthDecode
// 5: DCTDecode
let filter_type = data[offset] % 6;
offset += 1;
let filter = match filter_type {
0 => StreamFilter::ASCIIHexDecode,
1 => StreamFilter::ASCII85Decode,
2 | 3 => {
// LZW or Flate
// Needed params: predictor, n_components, bits_per_component, columns, early_change
let predictor = get_i32(data, &mut offset);
let n_components = get_i32(data, &mut offset);
let bits_per_component = get_i32(data, &mut offset);
let columns = get_i32(data, &mut offset);
let early_change = get_i32(data, &mut offset);
let params = LZWFlateParams {
predictor,
n_components,
bits_per_component,
columns,
early_change
};
if filter_type == 2 {
StreamFilter::LZWDecode(params)
} else {
StreamFilter::FlateDecode(params)
}
},
4 => StreamFilter::RunLengthDecode,
5 => {
// DCT
let color_transform = Some(get_i32(data, &mut offset));
StreamFilter::DCTDecode(DCTDecodeParams { color_transform })
},
_ => return
};
if offset > data.len() { return; }
let payload = &data[offset..];
// Execute decode
let _ = decode(payload, &filter);
});Stack Trace
==82489==ERROR: AddressSanitizer: requested allocation size 0x19efa9763262bcd0 (0x19efa9763262ccd0 after adjustments for alignment, red zones etc.) exceeds maximum supported size of 0x10000000000 (thread T0)
#0 0x562d1f0d9169 in calloc /rustc/llvm/src/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:74:3
#1 0x562d1f160b87 in alloc::alloc::alloc_zeroed /rustc/1aa9bab4ecbce4859eaad53000f78158ebe2be2c/library/alloc/src/alloc.rs:178:9
#2 0x562d1f160b87 in <alloc::alloc::Global>::alloc_impl /rustc/1aa9bab4ecbce4859eaad53000f78158ebe2be2c/library/alloc/src/alloc.rs:190:43
#3 0x562d1f160b87 in <alloc::alloc::Global as core::alloc::Allocator>::allocate_zeroed /rustc/1aa9bab4ecbce4859eaad53000f78158ebe2be2c/library/alloc/src/alloc.rs:257:14
#4 0x562d1f160b87 in <alloc::raw_vec::RawVecInner>::try_allocate_in /rustc/1aa9bab4ecbce4859eaad53000f78158ebe2be2c/library/alloc/src/raw_vec/mod.rs:470:40
#5 0x562d1f160b87 in <alloc::raw_vec::RawVecInner>::with_capacity_zeroed_in /rustc/1aa9bab4ecbce4859eaad53000f78158ebe2be2c/library/alloc/src/raw_vec/mod.rs:443:15
#6 0x562d1f160b87 in <alloc::raw_vec::RawVec<u8>>::with_capacity_zeroed_in /rustc/1aa9bab4ecbce4859eaad53000f78158ebe2be2c/library/alloc/src/raw_vec/mod.rs:208:20
#7 0x562d1f160b87 in <u8 as alloc::vec::spec_from_elem::SpecFromElem>::from_elem::<alloc::alloc::Global> /rustc/1aa9bab4ecbce4859eaad53000f78158ebe2be2c/library/alloc/src/vec/spec_from_elem.rs:51:31
#8 0x562d1f160b87 in alloc::vec::from_elem::<u8> /rustc/1aa9bab4ecbce4859eaad53000f78158ebe2be2c/library/alloc/src/vec/mod.rs:3510:5
#9 0x562d1f160b87 in pdf::enc::flate_decode /home/sun/pdf/pdf/src/enc.rs:306:24
#10 0x562d1f1632c8 in pdf::enc::decode /home/sun/pdf/pdf/src/enc.rs:468:50
#11 0x562d1f10b4eb in decode::_::__libfuzzer_sys_run /home/sun/pdf/pdf/fuzz/fuzz_targets/decode.rs:69:13
#12 0x562d1f10d66a in rust_fuzzer_test_input /home/sun/.cargo/registry/src/rsproxy.cn-e3de039b2554c837/libfuzzer-sys-0.4.10/src/lib.rs:276:60
#13 0x562d1f1f38e4 in libfuzzer_sys::test_input_wrap::{closure#0} /home/sun/.cargo/registry/src/rsproxy.cn-e3de039b2554c837/libfuzzer-sys-0.4.10/src/lib.rs:62:9
#14 0x562d1f1f38e4 in std::panicking::catch_unwind::do_call::<libfuzzer_sys::test_input_wrap::{closure#0}, i32> /rustc/1aa9bab4ecbce4859eaad53000f78158ebe2be2c/library/std/src/panicking.rs:581:40
#15 0x562d1f1f4488 in __rust_try libfuzzer_sys.27fa543dd454df52-cgu.0
Metadata
Metadata
Assignees
Labels
No labels