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);
   /*

openSUSE Build Service is sponsored by