summary refs log tree commit diff
diff options
context:
space:
mode:
authorEfraim Flashner <efraim@flashner.co.il>2017-09-01 00:00:14 +0300
committerEfraim Flashner <efraim@flashner.co.il>2017-09-01 00:02:27 +0300
commit0ff44ba4642c4ae672a7c66108a46f8d311955c2 (patch)
treeee89ff0899ffca005626c6c7c6e6015256e19871
parentd36212e94d3e35daaafefed4e600e3b563d369c1 (diff)
downloadguix-0ff44ba4642c4ae672a7c66108a46f8d311955c2.tar.gz
gnu: graphicsmagick: Fix CVE-2017-{13775,13776,13777}.
* gnu/packages/imagemagick.scm (graphicsmagick)[source]: Add patches.
* gnu/packages/patches/graphicsmagick-CVE-2017-13775.patch,
gnu/packages/patches/graphicsmagick-CVE-2017-13776+CVE-2017-13777.patch:
New files.
* gnu/local.mk (dist_patch_DATA): Register them.
-rw-r--r--gnu/local.mk2
-rw-r--r--gnu/packages/imagemagick.scm5
-rw-r--r--gnu/packages/patches/graphicsmagick-CVE-2017-13775.patch195
-rw-r--r--gnu/packages/patches/graphicsmagick-CVE-2017-13776+CVE-2017-13777.patch179
4 files changed, 380 insertions, 1 deletions
diff --git a/gnu/local.mk b/gnu/local.mk
index 586fa9809c..fbc6ff057f 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -676,6 +676,8 @@ dist_patch_DATA =						\
   %D%/packages/patches/graphicsmagick-CVE-2017-12935.patch	\
   %D%/packages/patches/graphicsmagick-CVE-2017-12936.patch	\
   %D%/packages/patches/graphicsmagick-CVE-2017-12937.patch	\
+  %D%/packages/patches/graphicsmagick-CVE-2017-13775.patch	\
+  %D%/packages/patches/graphicsmagick-CVE-2017-13776+CVE-2017-13777.patch	\
   %D%/packages/patches/graphite2-ffloat-store.patch		\
   %D%/packages/patches/grep-gnulib-lock.patch                   \
   %D%/packages/patches/grep-timing-sensitive-test.patch		\
diff --git a/gnu/packages/imagemagick.scm b/gnu/packages/imagemagick.scm
index 4056d486fb..57ac7fda97 100644
--- a/gnu/packages/imagemagick.scm
+++ b/gnu/packages/imagemagick.scm
@@ -4,6 +4,7 @@
 ;;; Copyright © 2015 Ricardo Wurmus <rekado@elephly.net>
 ;;; Copyright © 2016 Leo Famulari <leo@famulari.name>
 ;;; Copyright © 2016 Mark H Weaver <mhw@netris.org>
+;;; Copyright © 2017 Efraim Flashner <efraim@flashner.co.il>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -179,7 +180,9 @@ script.")
               (patches
                (search-patches "graphicsmagick-CVE-2017-12935.patch"
                                "graphicsmagick-CVE-2017-12936.patch"
-                               "graphicsmagick-CVE-2017-12937.patch"))))
+                               "graphicsmagick-CVE-2017-12937.patch"
+                               "graphicsmagick-CVE-2017-13775.patch"
+                               "graphicsmagick-CVE-2017-13776+CVE-2017-13777.patch"))))
     (build-system gnu-build-system)
     (arguments
      `(#:configure-flags
diff --git a/gnu/packages/patches/graphicsmagick-CVE-2017-13775.patch b/gnu/packages/patches/graphicsmagick-CVE-2017-13775.patch
new file mode 100644
index 0000000000..83478c13b3
--- /dev/null
+++ b/gnu/packages/patches/graphicsmagick-CVE-2017-13775.patch
@@ -0,0 +1,195 @@
+http://openwall.com/lists/oss-security/2017/08/31/3
+http://hg.code.sf.net/p/graphicsmagick/code/raw-rev/b037d79b6ccd
+
+some changes were made to make the patch apply
+
+# HG changeset patch
+# User Bob Friesenhahn <bfriesen@GraphicsMagick.org>
+# Date 1503774853 18000
+# Node ID b037d79b6ccd0cfba7ba9ce09b454ed46d688036
+# Parent  198ea602ea7cc767dc3022bbcf887bcd4534158d
+JNX: Fix DOS issues
+
+diff -r 198ea602ea7c -r b037d79b6ccd coders/jnx.c
+--- a/coders/jnx.c	Tue Aug 22 08:08:30 2017 -0500
++++ b/coders/jnx.c	Sat Aug 26 14:14:13 2017 -0500
+@@ -1,5 +1,5 @@
+ /*
+-% Copyright (C) 2012-2015 GraphicsMagick Group
++% Copyright (C) 2012-2017 GraphicsMagick Group
+ %
+ % This program is covered by multiple licenses, which are described in
+ % Copyright.txt. You should have received a copy of Copyright.txt with this
+@@ -100,6 +100,7 @@
+ 
+   char img_label_str[MaxTextExtent];
+ 
++
+   alloc_size = TileInfo->PicSize + 2;
+ 
+   if (image->logging)
+@@ -242,6 +243,9 @@
+     total_tiles,
+     current_tile;
+ 
++  magick_off_t
++    file_size;
++
+   /* Open image file. */
+   assert(image_info != (const ImageInfo *) NULL);
+   assert(image_info->signature == MagickSignature);
+@@ -254,9 +258,8 @@
+   if (status == False)
+     ThrowReaderException(FileOpenError, UnableToOpenFile, image);
+ 
+-  memset(JNXLevelInfo, 0, sizeof(JNXLevelInfo));
+-
+   /* Read JNX image header. */
++  (void) memset(&JNXHeader, 0, sizeof(JNXHeader));
+   JNXHeader.Version = ReadBlobLSBLong(image);
+   if (JNXHeader.Version > 4)
+     ThrowReaderException(CorruptImageError, ImproperImageHeader, image);
+@@ -266,8 +269,6 @@
+   JNXHeader.MapBounds.SouthWest.lat = ReadBlobLSBLong(image);
+   JNXHeader.MapBounds.SouthWest.lon = ReadBlobLSBLong(image);
+   JNXHeader.Levels = ReadBlobLSBLong(image);
+-  if (JNXHeader.Levels > 20)
+-    ThrowReaderException(CorruptImageError, ImproperImageHeader, image);
+   JNXHeader.Expiration = ReadBlobLSBLong(image);
+   JNXHeader.ProductID = ReadBlobLSBLong(image);
+   JNXHeader.CRC = ReadBlobLSBLong(image);
+@@ -279,7 +280,41 @@
+   if (EOFBlob(image))
+     ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ 
++  file_size = GetBlobSize(image);
++
++  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
++                        "JNX Header:\n"
++                        "    Version:    %u\n"
++                        "    DeviceSN:   %u\n"
++                        "    MapBounds:\n"
++                        "      NorthEast: lat = %u, lon = %u\n"
++                        "      SouthWest: lat = %u, lon = %u\n"
++                        "    Levels:     %u\n"
++                        "    Expiration: %u\n"
++                        "    ProductID:  %u\n"
++                        "    CRC:        %u\n"
++                        "    SigVersion: %u\n"
++                        "    SigOffset:  %u\n"
++                        "    ZOrder:     %u",
++                        JNXHeader.Version,
++                        JNXHeader.DeviceSN,
++                        JNXHeader.MapBounds.NorthEast.lat,
++                        JNXHeader.MapBounds.NorthEast.lon,
++                        JNXHeader.MapBounds.SouthWest.lat,
++                        JNXHeader.MapBounds.SouthWest.lon,
++                        JNXHeader.Levels,
++                        JNXHeader.Expiration,
++                        JNXHeader.ProductID,
++                        JNXHeader.CRC,
++                        JNXHeader.SigVersion,
++                        JNXHeader.SigOffset,
++                        JNXHeader.ZOrder);
++
++  if (JNXHeader.Levels > 20)
++    ThrowReaderException(CorruptImageError, ImproperImageHeader, image);
++
+   /* Read JNX image level info. */
++  memset(JNXLevelInfo, 0, sizeof(JNXLevelInfo));
+   total_tiles = 0;
+   current_tile = 0;
+   for (i = 0; i < JNXHeader.Levels; i++)
+@@ -302,11 +337,23 @@
+         {
+           JNXLevelInfo[i].Copyright = NULL;
+         }
++
++      if (EOFBlob(image))
++        ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
++
++      if (image->logging)
++        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
++                              "Level[%u] Info:"
++                              "  TileCount: %4u"
++                              "  TilesOffset: %6u"
++                              "  Scale: %04u",
++                              i,
++                              JNXLevelInfo[i].TileCount,
++                              JNXLevelInfo[i].TilesOffset,
++                              JNXLevelInfo[i].Scale
++                              );
+     }
+ 
+-  if (EOFBlob(image))
+-    ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+-
+   /* Get the current limit */
+   SaveLimit = GetMagickResourceLimit(MapResource);
+ 
+@@ -316,11 +363,32 @@
+   /* Read JNX image data. */
+   for (i = 0; i < JNXHeader.Levels; i++)
+     {
++      /*
++        Validate TileCount against remaining file data
++      */
++      const magick_off_t current_offset = TellBlob(image);
++      const size_t pos_list_entry_size =
++        sizeof(magick_uint32_t) + sizeof(magick_uint32_t) + sizeof(magick_uint32_t) +
++        sizeof(magick_uint32_t) + sizeof(magick_uint16_t) + sizeof(magick_uint16_t) +
++        sizeof(magick_uint32_t) + sizeof(magick_uint32_t);
++      const magick_off_t remaining = file_size-current_offset;
++      const size_t needed = MagickArraySize(pos_list_entry_size,JNXLevelInfo[i].TileCount);
++
++      if ((needed == 0U) || (remaining <= 0) || (remaining < (magick_off_t) needed))
++        {
++          (void) SetMagickResourceLimit(MapResource, SaveLimit);
++          ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
++        }
++
+       PositionList = MagickAllocateArray(TJNXTileInfo *,
+                                          JNXLevelInfo[i].TileCount,
+                                          sizeof(TJNXTileInfo));
+       if (PositionList == NULL)
+-        continue;
++        {
++          (void) SetMagickResourceLimit(MapResource, SaveLimit);
++          ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
++                               image);
++        }
+ 
+       (void) SeekBlob(image, JNXLevelInfo[i].TilesOffset, SEEK_SET);
+       for (j = 0; j < JNXLevelInfo[i].TileCount; j++)
+@@ -333,12 +401,15 @@
+           PositionList[j].PicHeight = ReadBlobLSBShort(image);
+           PositionList[j].PicSize = ReadBlobLSBLong(image);
+           PositionList[j].PicOffset = ReadBlobLSBLong(image);
+-        }
+ 
+-      if (EOFBlob(image))
+-        {
+-          MagickFreeMemory(PositionList);
+-          ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
++          if (EOFBlob(image) ||
++              ((magick_off_t) PositionList[j].PicOffset +
++               PositionList[j].PicSize > file_size))
++            {
++              (void) SetMagickResourceLimit(MapResource, SaveLimit);
++              MagickFreeMemory(PositionList);
++              ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
++            }
+         }
+ 
+       for (j = 0; j < JNXLevelInfo[i].TileCount; j++)
+@@ -351,6 +422,9 @@
+           image = ExtractTileJPG(image, image_info, PositionList+j, exception);
+           (void) SetMonitorHandler(previous_handler);
+ 
++          if (exception->severity >= ErrorException)
++            break;
++
+           current_tile++;
+           if (QuantumTick(current_tile,total_tiles))
+             if (!MagickMonitorFormatted(current_tile,total_tiles,exception,
+
diff --git a/gnu/packages/patches/graphicsmagick-CVE-2017-13776+CVE-2017-13777.patch b/gnu/packages/patches/graphicsmagick-CVE-2017-13776+CVE-2017-13777.patch
new file mode 100644
index 0000000000..e129fd58fc
--- /dev/null
+++ b/gnu/packages/patches/graphicsmagick-CVE-2017-13776+CVE-2017-13777.patch
@@ -0,0 +1,179 @@
+http://openwall.com/lists/oss-security/2017/08/31/1
+http://openwall.com/lists/oss-security/2017/08/31/2
+http://hg.code.sf.net/p/graphicsmagick/code/raw-rev/233a720bfd5e
+
+some changes were made to make the patch apply
+
+# HG changeset patch
+# User Bob Friesenhahn <bfriesen@GraphicsMagick.org>
+# Date 1503779175 18000
+# Node ID 233a720bfd5efd378f133a776507ed41230da617
+# Parent  b037d79b6ccd0cfba7ba9ce09b454ed46d688036
+XBM: Fix DOS issues.
+
+diff -r b037d79b6ccd -r 233a720bfd5e coders/xbm.c
+--- a/coders/xbm.c	Sat Aug 26 14:14:13 2017 -0500
++++ b/coders/xbm.c	Sat Aug 26 15:26:15 2017 -0500
+@@ -1,5 +1,5 @@
+ /*
+-% Copyright (C) 2003 -2012 GraphicsMagick Group
++% Copyright (C) 2003-2017 GraphicsMagick Group
+ % Copyright (C) 2002 ImageMagick Studio
+ % Copyright 1991-1999 E. I. du Pont de Nemours and Company
+ %
+@@ -121,13 +121,15 @@
+ 
+ static int XBMInteger(Image *image,short int *hex_digits)
+ {
++  unsigned int
++    flag;
++
+   int
+     c,
+-    flag,
+     value;
+ 
+   value=0;
+-  flag=0;
++  flag=0U;
+   for ( ; ; )
+   {
+     c=ReadBlobByte(image);
+@@ -158,18 +160,14 @@
+   Image
+     *image;
+ 
+-  int
+-    bit;
+-
+-  long
+-    y;
+-
+   register IndexPacket
+     *indexes;
+ 
+-  register long
++  register size_t
++    bytes_per_line,
+     i,
+-    x;
++    x,
++    y;
+ 
+   register PixelPacket
+     *q;
+@@ -177,22 +175,24 @@
+   register unsigned char
+     *p;
+ 
+-  short int
+-    hex_digits[256];
+-
+   unsigned char
+     *data;
+ 
+   unsigned int
++    bit,
++    byte,
++    padding,
++    version;
++
++  int
++    value;
++
++  short int
++    hex_digits[256];
++
++  MagickPassFail
+     status;
+ 
+-  unsigned long
+-    byte,
+-    bytes_per_line,
+-    padding,
+-    value,
+-    version;
+-
+   /*
+     Open image file.
+   */
+@@ -207,6 +207,8 @@
+   /*
+     Read X bitmap header.
+   */
++  (void) memset(buffer,0,sizeof(buffer));
++  name[0]='\0';
+   while (ReadBlobString(image,buffer) != (char *) NULL)
+     if (sscanf(buffer,"#define %s %lu",name,&image->columns) == 2)
+       if ((strlen(name) >= 6) &&
+@@ -278,6 +280,8 @@
+   /*
+     Initialize hex values.
+   */
++  for (i = 0; i < sizeof(hex_digits)/sizeof(hex_digits[0]); i++)
++    hex_digits[i]=(-1);
+   hex_digits['0']=0;
+   hex_digits['1']=1;
+   hex_digits['2']=2;
+@@ -311,40 +315,50 @@
+   */
+   p=data;
+   if (version == 10)
+-    for (i=0; i < (long) (bytes_per_line*image->rows); (i+=2))
++    for (i=0; i < (bytes_per_line*image->rows); (i+=2))
+     {
+       value=XBMInteger(image,hex_digits);
++      if (value < 0)
++        {
++          MagickFreeMemory(data);
++          ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
++        }
+       *p++=(unsigned char) value;
+       if (!padding || ((i+2) % bytes_per_line))
+         *p++=(unsigned char) (value >> 8);
+     }
+   else
+-    for (i=0; i < (long) (bytes_per_line*image->rows); i++)
++    for (i=0; i < (bytes_per_line*image->rows); i++)
+     {
+       value=XBMInteger(image,hex_digits);
++      if (value < 0)
++        {
++          MagickFreeMemory(data);
++          ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
++        }
+       *p++=(unsigned char) value;
+     }
+   /*
+     Convert X bitmap image to pixel packets.
+   */
+   p=data;
+-  for (y=0; y < (long) image->rows; y++)
++  for (y=0; y < image->rows; y++)
+   {
+     q=SetImagePixels(image,0,y,image->columns,1);
+     if (q == (PixelPacket *) NULL)
+       break;
+     indexes=AccessMutableIndexes(image);
+-    bit=0;
+-    byte=0;
+-    for (x=0; x < (long) image->columns; x++)
++    bit=0U;
++    byte=0U;
++    for (x=0; x < image->columns; x++)
+     {
+-      if (bit == 0)
++      if (bit == 0U)
+         byte=(*p++);
+       indexes[x]=byte & 0x01 ? 0x01 : 0x00;
+       bit++;
+-      byte>>=1;
+-      if (bit == 8)
+-        bit=0;
++      byte>>=1U;
++      if (bit == 8U)
++        bit=0U;
+     }
+     if (!SyncImagePixels(image))
+       break;
+