[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
02/02: gnu: graphicsmagick: Fix CVE-2017-{13775,13776,13777}.
From: |
Efraim Flashner |
Subject: |
02/02: gnu: graphicsmagick: Fix CVE-2017-{13775,13776,13777}. |
Date: |
Thu, 31 Aug 2017 17:03:25 -0400 (EDT) |
efraim pushed a commit to branch master
in repository guix.
commit 0ff44ba4642c4ae672a7c66108a46f8d311955c2
Author: Efraim Flashner <address@hidden>
Date: Fri Sep 1 00:00:14 2017 +0300
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.
---
gnu/local.mk | 2 +
gnu/packages/imagemagick.scm | 5 +-
.../patches/graphicsmagick-CVE-2017-13775.patch | 195 +++++++++++++++++++++
...phicsmagick-CVE-2017-13776+CVE-2017-13777.patch | 179 +++++++++++++++++++
4 files changed, 380 insertions(+), 1 deletion(-)
diff --git a/gnu/local.mk b/gnu/local.mk
index 586fa98..fbc6ff0 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 4056d48..57ac7fd 100644
--- a/gnu/packages/imagemagick.scm
+++ b/gnu/packages/imagemagick.scm
@@ -4,6 +4,7 @@
;;; Copyright © 2015 Ricardo Wurmus <address@hidden>
;;; Copyright © 2016 Leo Famulari <address@hidden>
;;; Copyright © 2016 Mark H Weaver <address@hidden>
+;;; Copyright © 2017 Efraim Flashner <address@hidden>
;;;
;;; 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 0000000..83478c1
--- /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 <address@hidden>
+# 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 0000000..e129fd5
--- /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 <address@hidden>
+# 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;
+