DPX: Estimate minimum required file sized based on header, and reject files with insufficient data
--- 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 <<a class="reference external" href="mailto:bfriesen%40simple.dallas.tx.us">bfriesen<span>@</span>simple<span>.</span>dallas<span>.</span>tx<span>.</span>us</a>></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 <<a class="reference external" href="mailto:JaFojtik%40seznam.cz">JaFojtik<span>@</span>seznam<span>.</span>cz</a>></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 <<a class="reference external" href="mailto:JaFojtik%40seznam.cz">JaFojtik<span>@</span>seznam<span>.</span>cz</a>></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 <<a class="reference external" href="mailto:bfriesen%40simple.dallas.tx.us">bfriesen<span>@</span>simple<span>.</span>dallas<span>.</span>tx<span>.</span>us</a>></p>
<blockquote>
<ul class="simple">