ITADN
pdf-rs/pdf/Issues

Panic: Allocation size too big in enc.rs

#266OpenYomihay-qut 创建于 2025-12-23
Y
Yomihay-qutcommented
**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. ```rust #![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); }); ``` [POC.zip](https://github.com/user-attachments/files/24312656/POC.zip) **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 ```
3 条评论