techgopal opened a new issue, #11690:
URL: https://github.com/apache/arrow-rs/issues/11690

   ### Describe the bug
   
   `ParquetMetaDataPushDecoder::try_decode` computes the start of the metadata 
from the footer's metadata length without checking it against the file length 
(`parquet/src/file/metadata/push_decoder.rs`):
   
   ```rust
   let metadata_len: u64 = footer_tail.metadata_length() as u64;
   let metadata_start = file_len - footer_len - metadata_len;
   let metadata_end = metadata_start + metadata_len;
   ```
   
   If the footer claims a metadata length larger than `file_len - 8`, the 
subtraction underflows:
   
   - with overflow checks (debug builds) it panics with `attempt to subtract 
with overflow`;
   - without them the value wraps, `metadata_end` wraps back to a small value, 
and the decoder then panics in `Bytes::slice` (`range start must not be greater 
than end`).
   
   `ParquetMetaDataReader::parse_and_finish` on the same bytes returns 
`EOF("Parquet file too small. Size is 12 but need 1008")`, so only the push 
decoder is affected.
   
   ### To Reproduce
   
   With `parquet = "60.0.0"`:
   
   ```rust
   use parquet::file::metadata::ParquetMetaDataPushDecoder;
   use parquet::DecodeResult;
   
   fn main() {
       // A 12-byte "file": 4 bytes of data, then a footer whose metadata
       // length (1000) is larger than the file.
       let mut file = vec![0u8; 4];
       file.extend_from_slice(&1000u32.to_le_bytes());
       file.extend_from_slice(b"PAR1");
       let len = file.len() as u64;
   
       let mut decoder = ParquetMetaDataPushDecoder::try_new(len).unwrap();
       decoder.push_range(0..len, file.into()).unwrap();
       match decoder.try_decode() {
           Ok(DecodeResult::NeedsData(r)) => println!("needs data: {r:?}"),
           Ok(DecodeResult::Data(_)) => println!("data"),
           Ok(DecodeResult::Finished) => println!("finished"),
           Err(e) => println!("error: {e}"),
       }
   }
   ```
   
   Debug build:
   
   ```
   thread 'main' panicked at 
parquet-60.0.0/src/file/metadata/push_decoder.rs:390:42:
   attempt to subtract with overflow
   ```
   
   Release build:
   
   ```
   thread 'main' panicked at bytes-1.12.1/src/bytes.rs:374:28:
   range start must not be greater than end: 18446744073709550620 <= 4
   ```
   
   (from `bytes::Bytes::slice` called by 
`ParquetMetaDataPushDecoder::try_decode`)
   
   ### Expected behavior
   
   `try_decode` returns a `ParquetError` (like `ParquetMetaDataReader`, e.g. 
"file too small ... need N bytes") instead of panicking.
   
   ### Additional context
   
   - Reproduces with `parquet` 60.0.0 and on `main` at 33d338ddf 
(`push_decoder.rs:430`).
   - Found while fuzzing a Parquet reader built on arrow-rs. Related: #9742, 
#10563.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to