DPX: Estimate minimum required file sized based on header, and reject files with insufficient data
authorBob Friesenhahn <bfriesen@GraphicsMagick.org>
Sun, 02 Jul 2017 09:43:15 -0500
changeset 15043 f10b9bb3ca62
parent 15042 e5761e3a2012
child 15044 d4a807eaf3d7
DPX: Estimate minimum required file sized based on header, and reject files with insufficient data
ChangeLog
VisualMagick/installer/inc/version.isx
coders/dpx.c
magick/version.h
www/Changelog.html
--- a/ChangeLog	Sun Jul 02 10:46:37 2017 +0200
+++ b/ChangeLog	Sun Jul 02 09:43:15 2017 -0500
@@ -1,13 +1,19 @@
+2017-07-02  Bob Friesenhahn  <bfriesen@simple.dallas.tx.us>
+
+	* coders/dpx.c (ReadDPXImage): Compute required file size and
+	verify that sufficient data exists in file before allocating
+	memory to decode the image data.  Resolves problem with DPX file
+	with valid header (but a huge claimed image width) provided
+	provided via email on Thu, 29 Jun 2017 by LCatro.
+
 2016-07-02  Fojtik Jaroslav  <JaFojtik@seznam.cz>
 
 	* coders/mat.c Check whether reported object size overflows file size.
 
-
 2016-07-01  Fojtik Jaroslav  <JaFojtik@seznam.cz>
 
 	* coders/mat.c Safety check for forged and or corrupted data.
 
-
 2017-07-01  Bob Friesenhahn  <bfriesen@simple.dallas.tx.us>
 
 	* coders/tiff.c ("QuantumTransferMode"): Use a generalized method
--- a/VisualMagick/installer/inc/version.isx	Sun Jul 02 10:46:37 2017 +0200
+++ b/VisualMagick/installer/inc/version.isx	Sun Jul 02 09:43:15 2017 -0500
@@ -10,5 +10,5 @@
 
 #define public MagickPackageName "GraphicsMagick"
 #define public MagickPackageVersion "1.4"
-#define public MagickPackageVersionAddendum ".020170701"
-#define public MagickPackageReleaseDate "snapshot-20170701"
+#define public MagickPackageVersionAddendum ".020170702"
+#define public MagickPackageReleaseDate "snapshot-20170702"
--- 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);
   /*
--- a/magick/version.h	Sun Jul 02 10:46:37 2017 +0200
+++ b/magick/version.h	Sun Jul 02 09:43:15 2017 -0500
@@ -38,8 +38,8 @@
 #define MagickLibVersion  0x181501
 #define MagickLibVersionText  "1.4"
 #define MagickLibVersionNumber 18,15,1
-#define MagickChangeDate   "20170701"
-#define MagickReleaseDate  "snapshot-20170701"
+#define MagickChangeDate   "20170702"
+#define MagickReleaseDate  "snapshot-20170702"
 	
 /*
   The MagickLibInterfaceNewest and MagickLibInterfaceOldest defines
--- a/www/Changelog.html	Sun Jul 02 10:46:37 2017 +0200
+++ b/www/Changelog.html	Sun Jul 02 09:43:15 2017 -0500
@@ -35,6 +35,28 @@
 <div class="document">
 
 
+<p>2017-07-02  Bob Friesenhahn  &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dpx.c (ReadDPXImage): Compute required file size and
+verify that sufficient data exists in file before allocating
+memory to decode the image data.  Resolves problem with DPX file
+with valid header (but a huge claimed image width) provided
+provided via email on Thu, 29 Jun 2017 by LCatro.</li>
+</ul>
+</blockquote>
+<p>2016-07-02  Fojtik Jaroslav  &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/mat.c Check whether reported object size overflows file size.</li>
+</ul>
+</blockquote>
+<p>2016-07-01  Fojtik Jaroslav  &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/mat.c Safety check for forged and or corrupted data.</li>
+</ul>
+</blockquote>
 <p>2017-07-01  Bob Friesenhahn  &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
 <blockquote>
 <ul class="simple">