File GraphicsMagick-CVE-2017-10799.patch of Package GraphicsMagick.7727
# HG changeset patch
# User Bob Friesenhahn <bfriesen@GraphicsMagick.org>
# Date 1499006595 18000
# Node ID f10b9bb3ca621ecc51ec9c8a3b0d52e4503bb7e5
# Parent e5761e3a20128e6d1a3d29904a6e479579306068
DPX: Estimate minimum required file sized based on header, and reject files with insufficient data
diff -r e5761e3a2012 -r f10b9bb3ca62 coders/dpx.c
--- a/coders/dpx.c Sun Jul 02 10:46:37 2017 +0200
+++ b/coders/dpx.c Sun Jul 02 09:43:15 2017 -0500
@@ -2048,6 +2048,51 @@
ThrowDPXReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
/*
+ Validate file size if using a seekable blob
+ */
+ if (BlobIsSeekable(image))
+ {
+ magick_off_t file_size;
+ magick_off_t file_size_estimate = dpx_file_info.image_data_offset;
+
+ /*
+ Verify that file size claimed by header is matched by file size
+ */
+ if ((file_size = GetBlobSize(image)) != 0)
+ {
+ if (file_size < dpx_file_info.file_size)
+ {
+ ThrowDPXReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ }
+ }
+
+ /*
+ Estimate the required file size and assure that actual file
+ size is at least that size.
+ */
+ for (element=0; element < dpx_image_info.elements; element++)
+ {
+ bits_per_sample=dpx_image_info.element_info[element].bits_per_sample;
+ element_descriptor=(DPXImageElementDescriptor)
+ dpx_image_info.element_info[element].descriptor;
+ transfer_characteristic=
+ (DPXTransferCharacteristic) dpx_image_info.element_info[element].transfer_characteristic;
+ packing_method=(ImageComponentPackingMethod) dpx_image_info.element_info[element].packing;
+ samples_per_pixel=DPXSamplesPerPixel(element_descriptor);
+ samples_per_row=samples_per_pixel*image->columns;
+ element_size=DPXRowOctets(image->rows,samples_per_row,
+ bits_per_sample,packing_method);
+ file_size_estimate += element_size;
+ }
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "File size estimate %" MAGICK_OFF_F
+ "u bytes (have %" MAGICK_OFF_F "u bytes)",
+ file_size_estimate, file_size);
+ if ((file_size_estimate <= 0) || (file_size < file_size_estimate))
+ ThrowDPXReaderException(CorruptImageError,InsufficientImageDataInFile,image);
+ }
+
+ /*
Read remainder of header.
*/
for ( ; offset < pixels_offset ; offset++ )
@@ -2070,16 +2115,19 @@
ThrowDPXReaderException(ResourceLimitError,MemoryAllocationFailed,image);
/*
Allocate per-thread-view row samples.
+ FIXME: Unlimited memory allocation here based on width
*/
samples_set=AllocateThreadViewDataArray(image,exception,image->columns,
- max_samples_per_pixel*sizeof(sample_t));
+ MagickArraySize(max_samples_per_pixel,
+ sizeof(sample_t)));
if (samples_set == (ThreadViewDataSet *) NULL)
ThrowDPXReaderException(ResourceLimitError,MemoryAllocationFailed,image);
/*
Allocate per-thread-view scanline storage.
*/
scanline_set=AllocateThreadViewDataArray(image,exception,image->columns,
- max_samples_per_pixel*sizeof(U32));
+ MagickArraySize(max_samples_per_pixel,
+ sizeof(U32)));
if (scanline_set == (ThreadViewDataSet *) NULL)
ThrowDPXReaderException(ResourceLimitError,MemoryAllocationFailed,image);
/*