ArjunD3456 opened a new pull request, #4035:
URL: https://github.com/apache/avro/pull/4035

   ## What is the purpose of the change
   
   `DataFileReaderBase::readDataBlock` sets up a `z_stream` with `inflateInit2` 
for every deflate-coded block it reads and only reaches the matching 
`inflateEnd` once the inflate loop has run to completion. When a block does not 
inflate, the `throw` inside that loop leaves the scope with the stream still 
live, so the ~7 KiB of state zlib allocated for it is lost. The payload comes 
straight from the file, so any corrupt or crafted container leaks it, and a 
process that keeps reading untrusted files and handles `avro::Exception` grows 
without bound. `DataFileWriterBase::sync` has the same shape around 
`deflateInit2`, and the `resize` call in either loop can leave the scope the 
same way. Giving the stream a small scope guard puts the 
`inflateEnd`/`deflateEnd` call on every exit path, which is how 
`ZstdCompressWrapper` and `ZstdDecompressWrapper` already release their 
contexts.
   
   ## Verifying this change
   
   This change added tests and can be verified as follows:
   - added `testCorruptDeflateBlock` to `DataFileTests`, which writes a deflate 
file, rewrites the first payload byte so the block header carries the reserved 
RFC 1951 `BTYPE` 3, and checks the read is rejected rather than decoded; 
`./build.sh test` and `./build.sh lint` both stay green
   - measured the leak: reading that file 2000 times and catching the exception 
each time grew the heap by 14336048 bytes (7168 per failed read) before this 
change and by 48 bytes after
   
   ## Documentation
   
   - Does this pull request introduce a new feature? no
   


-- 
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