diff options
Diffstat (limited to 'gnu/packages/patches')
31 files changed, 2539 insertions, 1101 deletions
diff --git a/gnu/packages/patches/gd-CVE-2017-7890.patch b/gnu/packages/patches/gd-CVE-2017-7890.patch deleted file mode 100644 index 66034c5703..0000000000 --- a/gnu/packages/patches/gd-CVE-2017-7890.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 99ba5c353373ed198f54af66fe4e355ebb96e363 Mon Sep 17 00:00:00 2001 -From: LEPILLER Julien <julien@lepiller.eu> -Date: Thu, 3 Aug 2017 17:04:17 +0200 -Subject: [PATCH] Fix #399: Buffer over-read into uninitialized memory. - -The stack allocated color map buffers were not zeroed before usage, and -so undefined palette indexes could cause information leakage. - -This is CVE-2017-7890. ---- - src/gd_gif_in.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/src/gd_gif_in.c b/src/gd_gif_in.c -index 008d1ec..c195448 100644 ---- a/src/gd_gif_in.c -+++ b/src/gd_gif_in.c -@@ -216,6 +216,9 @@ BGD_DECLARE(gdImagePtr) gdImageCreateFromGifCtx(gdIOCtxPtr fd) - - gdImagePtr im = 0; - -+ memset(ColorMap, 0, 3 * MAXCOLORMAPSIZE); -+ memset(localColorMap, 0, 3 * MAXCOLORMAPSIZE); -+ - if(!ReadOK(fd, buf, 6)) { - return 0; - } --- -2.13.3 - 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; + diff --git a/gnu/packages/patches/libxml2-CVE-2017-0663.patch b/gnu/packages/patches/libxml2-CVE-2017-0663.patch new file mode 100644 index 0000000000..b0277a2d23 --- /dev/null +++ b/gnu/packages/patches/libxml2-CVE-2017-0663.patch @@ -0,0 +1,53 @@ +Fix CVE-2017-0663: + +https://bugzilla.gnome.org/show_bug.cgi?id=780228 (not yet public) +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-0663 +https://security-tracker.debian.org/tracker/CVE-2017-0663 + +Patch copied from upstream source repository: + +https://git.gnome.org/browse/libxml2/commit/?id=92b9e8c8b3787068565a1820ba575d042f9eec66 + +From 92b9e8c8b3787068565a1820ba575d042f9eec66 Mon Sep 17 00:00:00 2001 +From: Nick Wellnhofer <wellnhofer@aevum.de> +Date: Tue, 6 Jun 2017 12:56:28 +0200 +Subject: [PATCH] Fix type confusion in xmlValidateOneNamespace + +Comment out code that casts xmlNsPtr to xmlAttrPtr. ID types on +namespace declarations make no practical sense anyway. + +Fixes bug 780228. + +Found with libFuzzer and ASan. +--- + valid.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/valid.c b/valid.c +index 8075d3a0..c51ea290 100644 +--- a/valid.c ++++ b/valid.c +@@ -4627,6 +4627,12 @@ xmlNodePtr elem, const xmlChar *prefix, xmlNsPtr ns, const xmlChar *value) { + } + } + ++ /* ++ * Casting ns to xmlAttrPtr is wrong. We'd need separate functions ++ * xmlAddID and xmlAddRef for namespace declarations, but it makes ++ * no practical sense to use ID types anyway. ++ */ ++#if 0 + /* Validity Constraint: ID uniqueness */ + if (attrDecl->atype == XML_ATTRIBUTE_ID) { + if (xmlAddID(ctxt, doc, value, (xmlAttrPtr) ns) == NULL) +@@ -4638,6 +4644,7 @@ xmlNodePtr elem, const xmlChar *prefix, xmlNsPtr ns, const xmlChar *value) { + if (xmlAddRef(ctxt, doc, value, (xmlAttrPtr) ns) == NULL) + ret = 0; + } ++#endif + + /* Validity Constraint: Notation Attributes */ + if (attrDecl->atype == XML_ATTRIBUTE_NOTATION) { +-- +2.14.1 + diff --git a/gnu/packages/patches/libxml2-CVE-2017-7375.patch b/gnu/packages/patches/libxml2-CVE-2017-7375.patch new file mode 100644 index 0000000000..32af1ff6ba --- /dev/null +++ b/gnu/packages/patches/libxml2-CVE-2017-7375.patch @@ -0,0 +1,45 @@ +Fix CVE-2017-7375: + +https://bugzilla.gnome.org/show_bug.cgi?id=780691 (not yet public) +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-7375 +https://security-tracker.debian.org/tracker/CVE-2017-7375 + +Patch copied from upstream source repository: + +https://git.gnome.org/browse/libxml2/commit/?id=90ccb58242866b0ba3edbef8fe44214a101c2b3e + +From 90ccb58242866b0ba3edbef8fe44214a101c2b3e Mon Sep 17 00:00:00 2001 +From: Neel Mehta <nmehta@google.com> +Date: Fri, 7 Apr 2017 17:43:02 +0200 +Subject: [PATCH] Prevent unwanted external entity reference + +For https://bugzilla.gnome.org/show_bug.cgi?id=780691 + +* parser.c: add a specific check to avoid PE reference +--- + parser.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/parser.c b/parser.c +index 609a2703..c2c812de 100644 +--- a/parser.c ++++ b/parser.c +@@ -8123,6 +8123,15 @@ xmlParsePEReference(xmlParserCtxtPtr ctxt) + if (xmlPushInput(ctxt, input) < 0) + return; + } else { ++ if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) && ++ ((ctxt->options & XML_PARSE_NOENT) == 0) && ++ ((ctxt->options & XML_PARSE_DTDVALID) == 0) && ++ ((ctxt->options & XML_PARSE_DTDLOAD) == 0) && ++ ((ctxt->options & XML_PARSE_DTDATTR) == 0) && ++ (ctxt->replaceEntities == 0) && ++ (ctxt->validate == 0)) ++ return; ++ + /* + * TODO !!! + * handle the extra spaces added before and after +-- +2.14.1 + diff --git a/gnu/packages/patches/libxml2-CVE-2017-7376.patch b/gnu/packages/patches/libxml2-CVE-2017-7376.patch new file mode 100644 index 0000000000..5b9e45bd83 --- /dev/null +++ b/gnu/packages/patches/libxml2-CVE-2017-7376.patch @@ -0,0 +1,41 @@ +Fix CVE-2017-7376: + +https://bugzilla.gnome.org/show_bug.cgi?id=780690 (not yet public) +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-7376 +https://security-tracker.debian.org/tracker/CVE-2017-7376 + +Patch copied from upstream source repository: + +https://git.gnome.org/browse/libxml2/commit/?id=5dca9eea1bd4263bfa4d037ab2443de1cd730f7e + +From 5dca9eea1bd4263bfa4d037ab2443de1cd730f7e Mon Sep 17 00:00:00 2001 +From: Daniel Veillard <veillard@redhat.com> +Date: Fri, 7 Apr 2017 17:13:28 +0200 +Subject: [PATCH] Increase buffer space for port in HTTP redirect support + +For https://bugzilla.gnome.org/show_bug.cgi?id=780690 + +nanohttp.c: the code wrongly assumed a short int port value. +--- + nanohttp.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/nanohttp.c b/nanohttp.c +index e109ad75..373425de 100644 +--- a/nanohttp.c ++++ b/nanohttp.c +@@ -1423,9 +1423,9 @@ retry: + if (ctxt->port != 80) { + /* reserve space for ':xxxxx', incl. potential proxy */ + if (proxy) +- blen += 12; ++ blen += 17; + else +- blen += 6; ++ blen += 11; + } + bp = (char*)xmlMallocAtomic(blen); + if ( bp == NULL ) { +-- +2.14.1 + diff --git a/gnu/packages/patches/libxml2-CVE-2017-9047+CVE-2017-9048.patch b/gnu/packages/patches/libxml2-CVE-2017-9047+CVE-2017-9048.patch new file mode 100644 index 0000000000..0a0e6d34cf --- /dev/null +++ b/gnu/packages/patches/libxml2-CVE-2017-9047+CVE-2017-9048.patch @@ -0,0 +1,130 @@ +Fix CVE-2017-{9047,9048}: + +https://bugzilla.gnome.org/show_bug.cgi?id=781333 (not yet public) +https://bugzilla.gnome.org/show_bug.cgi?id=781701 (not yet public) +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-9047 +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-9048 +http://www.openwall.com/lists/oss-security/2017/05/15/1 +https://security-tracker.debian.org/tracker/CVE-2017-9047 +https://security-tracker.debian.org/tracker/CVE-2017-9048 + +Patch copied from upstream source repository: + +https://git.gnome.org/browse/libxml2/commit/?id=932cc9896ab41475d4aa429c27d9afd175959d74 + +From 932cc9896ab41475d4aa429c27d9afd175959d74 Mon Sep 17 00:00:00 2001 +From: Nick Wellnhofer <wellnhofer@aevum.de> +Date: Sat, 3 Jun 2017 02:01:29 +0200 +Subject: [PATCH] Fix buffer size checks in xmlSnprintfElementContent +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +xmlSnprintfElementContent failed to correctly check the available +buffer space in two locations. + +Fixes bug 781333 (CVE-2017-9047) and bug 781701 (CVE-2017-9048). + +Thanks to Marcel Böhme and Thuan Pham for the report. +--- + result/valid/781333.xml | 5 +++++ + result/valid/781333.xml.err | 3 +++ + result/valid/781333.xml.err.rdr | 6 ++++++ + test/valid/781333.xml | 4 ++++ + valid.c | 20 +++++++++++--------- + 5 files changed, 29 insertions(+), 9 deletions(-) + create mode 100644 result/valid/781333.xml + create mode 100644 result/valid/781333.xml.err + create mode 100644 result/valid/781333.xml.err.rdr + create mode 100644 test/valid/781333.xml + +diff --git a/result/valid/781333.xml b/result/valid/781333.xml +new file mode 100644 +index 00000000..45dc451d +--- /dev/null ++++ b/result/valid/781333.xml +@@ -0,0 +1,5 @@ ++<?xml version="1.0"?> ++<!DOCTYPE a [ ++<!ELEMENT a (pppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp:llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll)> ++]> ++<a/> +diff --git a/result/valid/781333.xml.err b/result/valid/781333.xml.err +new file mode 100644 +index 00000000..b401b49a +--- /dev/null ++++ b/result/valid/781333.xml.err +@@ -0,0 +1,3 @@ ++./test/valid/781333.xml:4: element a: validity error : Element a content does not follow the DTD, expecting ( ..., got ++<a/> ++ ^ +diff --git a/result/valid/781333.xml.err.rdr b/result/valid/781333.xml.err.rdr +new file mode 100644 +index 00000000..5ff56992 +--- /dev/null ++++ b/result/valid/781333.xml.err.rdr +@@ -0,0 +1,6 @@ ++./test/valid/781333.xml:4: element a: validity error : Element a content does not follow the DTD, expecting ( ..., got ++<a/> ++ ^ ++./test/valid/781333.xml:5: element a: validity error : Element a content does not follow the DTD, Expecting more child ++ ++^ +diff --git a/test/valid/781333.xml b/test/valid/781333.xml +new file mode 100644 +index 00000000..b29e5a68 +--- /dev/null ++++ b/test/valid/781333.xml +@@ -0,0 +1,4 @@ ++<!DOCTYPE a [ ++ <!ELEMENT a (pppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp:llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll)> ++]> ++<a/> +diff --git a/valid.c b/valid.c +index 19f84b82..9b2df56a 100644 +--- a/valid.c ++++ b/valid.c +@@ -1262,22 +1262,23 @@ xmlSnprintfElementContent(char *buf, int size, xmlElementContentPtr content, int + case XML_ELEMENT_CONTENT_PCDATA: + strcat(buf, "#PCDATA"); + break; +- case XML_ELEMENT_CONTENT_ELEMENT: ++ case XML_ELEMENT_CONTENT_ELEMENT: { ++ int qnameLen = xmlStrlen(content->name); ++ ++ if (content->prefix != NULL) ++ qnameLen += xmlStrlen(content->prefix) + 1; ++ if (size - len < qnameLen + 10) { ++ strcat(buf, " ..."); ++ return; ++ } + if (content->prefix != NULL) { +- if (size - len < xmlStrlen(content->prefix) + 10) { +- strcat(buf, " ..."); +- return; +- } + strcat(buf, (char *) content->prefix); + strcat(buf, ":"); + } +- if (size - len < xmlStrlen(content->name) + 10) { +- strcat(buf, " ..."); +- return; +- } + if (content->name != NULL) + strcat(buf, (char *) content->name); + break; ++ } + case XML_ELEMENT_CONTENT_SEQ: + if ((content->c1->type == XML_ELEMENT_CONTENT_OR) || + (content->c1->type == XML_ELEMENT_CONTENT_SEQ)) +@@ -1319,6 +1320,7 @@ xmlSnprintfElementContent(char *buf, int size, xmlElementContentPtr content, int + xmlSnprintfElementContent(buf, size, content->c2, 0); + break; + } ++ if (size - strlen(buf) <= 2) return; + if (englob) + strcat(buf, ")"); + switch (content->ocur) { +-- +2.14.1 + diff --git a/gnu/packages/patches/libxml2-CVE-2017-9049+CVE-2017-9050.patch b/gnu/packages/patches/libxml2-CVE-2017-9049+CVE-2017-9050.patch new file mode 100644 index 0000000000..890e9c2284 --- /dev/null +++ b/gnu/packages/patches/libxml2-CVE-2017-9049+CVE-2017-9050.patch @@ -0,0 +1,319 @@ +Fix CVE-2017-{9049,9050}: + +https://bugzilla.gnome.org/show_bug.cgi?id=781205 (not yet public) +https://bugzilla.gnome.org/show_bug.cgi?id=781361 (not yet public) +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-9049 +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-9050 +http://www.openwall.com/lists/oss-security/2017/05/15/1 +https://security-tracker.debian.org/tracker/CVE-2017-9049 +https://security-tracker.debian.org/tracker/CVE-2017-9050 + +Patch copied from upstream source repository: + +https://git.gnome.org/browse/libxml2/commit/?id=e26630548e7d138d2c560844c43820b6767251e3 + +Changes to 'runtest.c' are removed since they introduce test failure +when applying to libxml2 2.9.4 release tarball. + +From e26630548e7d138d2c560844c43820b6767251e3 Mon Sep 17 00:00:00 2001 +From: Nick Wellnhofer <wellnhofer@aevum.de> +Date: Mon, 5 Jun 2017 15:37:17 +0200 +Subject: [PATCH] Fix handling of parameter-entity references +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +There were two bugs where parameter-entity references could lead to an +unexpected change of the input buffer in xmlParseNameComplex and +xmlDictLookup being called with an invalid pointer. + +Percent sign in DTD Names +========================= + +The NEXTL macro used to call xmlParserHandlePEReference. When parsing +"complex" names inside the DTD, this could result in entity expansion +which created a new input buffer. The fix is to simply remove the call +to xmlParserHandlePEReference from the NEXTL macro. This is safe because +no users of the macro require expansion of parameter entities. + +- xmlParseNameComplex +- xmlParseNCNameComplex +- xmlParseNmtoken + +The percent sign is not allowed in names, which are grammatical tokens. + +- xmlParseEntityValue + +Parameter-entity references in entity values are expanded but this +happens in a separate step in this function. + +- xmlParseSystemLiteral + +Parameter-entity references are ignored in the system literal. + +- xmlParseAttValueComplex +- xmlParseCharDataComplex +- xmlParseCommentComplex +- xmlParsePI +- xmlParseCDSect + +Parameter-entity references are ignored outside the DTD. + +- xmlLoadEntityContent + +This function is only called from xmlStringLenDecodeEntities and +entities are replaced in a separate step immediately after the function +call. + +This bug could also be triggered with an internal subset and double +entity expansion. + +This fixes bug 766956 initially reported by Wei Lei and independently by +Chromium's ClusterFuzz, Hanno Böck, and Marco Grassi. Thanks to everyone +involved. + +xmlParseNameComplex with XML_PARSE_OLD10 +======================================== + +When parsing Names inside an expanded parameter entity with the +XML_PARSE_OLD10 option, xmlParseNameComplex would call xmlGROW via the +GROW macro if the input buffer was exhausted. At the end of the +parameter entity's replacement text, this function would then call +xmlPopInput which invalidated the input buffer. + +There should be no need to invoke GROW in this situation because the +buffer is grown periodically every XML_PARSER_CHUNK_SIZE characters and, +at least for UTF-8, in xmlCurrentChar. This also matches the code path +executed when XML_PARSE_OLD10 is not set. + +This fixes bugs 781205 (CVE-2017-9049) and 781361 (CVE-2017-9050). +Thanks to Marcel Böhme and Thuan Pham for the report. + +Additional hardening +==================== + +A separate check was added in xmlParseNameComplex to validate the +buffer size. +--- + Makefile.am | 18 ++++++++++++++++++ + parser.c | 18 ++++++++++-------- + result/errors10/781205.xml | 0 + result/errors10/781205.xml.err | 21 +++++++++++++++++++++ + result/errors10/781361.xml | 0 + result/errors10/781361.xml.err | 13 +++++++++++++ + result/valid/766956.xml | 0 + result/valid/766956.xml.err | 9 +++++++++ + result/valid/766956.xml.err.rdr | 10 ++++++++++ + runtest.c | 3 +++ + test/errors10/781205.xml | 3 +++ + test/errors10/781361.xml | 3 +++ + test/valid/766956.xml | 2 ++ + test/valid/dtds/766956.dtd | 2 ++ + 14 files changed, 94 insertions(+), 8 deletions(-) + create mode 100644 result/errors10/781205.xml + create mode 100644 result/errors10/781205.xml.err + create mode 100644 result/errors10/781361.xml + create mode 100644 result/errors10/781361.xml.err + create mode 100644 result/valid/766956.xml + create mode 100644 result/valid/766956.xml.err + create mode 100644 result/valid/766956.xml.err.rdr + create mode 100644 test/errors10/781205.xml + create mode 100644 test/errors10/781361.xml + create mode 100644 test/valid/766956.xml + create mode 100644 test/valid/dtds/766956.dtd + +diff --git a/Makefile.am b/Makefile.am +index 6fc8ffa9..10e716a5 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -427,6 +427,24 @@ Errtests : xmllint$(EXEEXT) + if [ -n "$$log" ] ; then echo $$name result ; echo "$$log" ; fi ; \ + rm result.$$name error.$$name ; \ + fi ; fi ; done) ++ @echo "## Error cases regression tests (old 1.0)" ++ -@(for i in $(srcdir)/test/errors10/*.xml ; do \ ++ name=`basename $$i`; \ ++ if [ ! -d $$i ] ; then \ ++ if [ ! -f $(srcdir)/result/errors10/$$name ] ; then \ ++ echo New test file $$name ; \ ++ $(CHECKER) $(top_builddir)/xmllint --oldxml10 $$i \ ++ 2> $(srcdir)/result/errors10/$$name.err \ ++ > $(srcdir)/result/errors10/$$name ; \ ++ grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0"; \ ++ else \ ++ log=`$(CHECKER) $(top_builddir)/xmllint --oldxml10 $$i 2> error.$$name > result.$$name ; \ ++ grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0"; \ ++ diff $(srcdir)/result/errors10/$$name result.$$name ; \ ++ diff $(srcdir)/result/errors10/$$name.err error.$$name` ; \ ++ if [ -n "$$log" ] ; then echo $$name result ; echo "$$log" ; fi ; \ ++ rm result.$$name error.$$name ; \ ++ fi ; fi ; done) + @echo "## Error cases stream regression tests" + -@(for i in $(srcdir)/test/errors/*.xml ; do \ + name=`basename $$i`; \ +diff --git a/parser.c b/parser.c +index df2efa55..a175ac4e 100644 +--- a/parser.c ++++ b/parser.c +@@ -2121,7 +2121,6 @@ static void xmlGROW (xmlParserCtxtPtr ctxt) { + ctxt->input->line++; ctxt->input->col = 1; \ + } else ctxt->input->col++; \ + ctxt->input->cur += l; \ +- if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt); \ + } while (0) + + #define CUR_CHAR(l) xmlCurrentChar(ctxt, &l) +@@ -3412,13 +3411,6 @@ xmlParseNameComplex(xmlParserCtxtPtr ctxt) { + len += l; + NEXTL(l); + c = CUR_CHAR(l); +- if (c == 0) { +- count = 0; +- GROW; +- if (ctxt->instate == XML_PARSER_EOF) +- return(NULL); +- c = CUR_CHAR(l); +- } + } + } + if ((len > XML_MAX_NAME_LENGTH) && +@@ -3426,6 +3418,16 @@ xmlParseNameComplex(xmlParserCtxtPtr ctxt) { + xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Name"); + return(NULL); + } ++ if (ctxt->input->cur - ctxt->input->base < len) { ++ /* ++ * There were a couple of bugs where PERefs lead to to a change ++ * of the buffer. Check the buffer size to avoid passing an invalid ++ * pointer to xmlDictLookup. ++ */ ++ xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, ++ "unexpected change of input buffer"); ++ return (NULL); ++ } + if ((*ctxt->input->cur == '\n') && (ctxt->input->cur[-1] == '\r')) + return(xmlDictLookup(ctxt->dict, ctxt->input->cur - (len + 1), len)); + return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len)); +diff --git a/result/errors10/781205.xml b/result/errors10/781205.xml +new file mode 100644 +index 00000000..e69de29b +diff --git a/result/errors10/781205.xml.err b/result/errors10/781205.xml.err +new file mode 100644 +index 00000000..da15c3f7 +--- /dev/null ++++ b/result/errors10/781205.xml.err +@@ -0,0 +1,21 @@ ++Entity: line 1: parser error : internal error: xmlParseInternalSubset: error detected in Markup declaration ++ ++ %a; ++ ^ ++Entity: line 1: ++<:0000 ++^ ++Entity: line 1: parser error : DOCTYPE improperly terminated ++ %a; ++ ^ ++Entity: line 1: ++<:0000 ++^ ++namespace error : Failed to parse QName ':0000' ++ %a; ++ ^ ++<:0000 ++ ^ ++./test/errors10/781205.xml:4: parser error : Couldn't find end of Start Tag :0000 line 1 ++ ++^ +diff --git a/result/errors10/781361.xml b/result/errors10/781361.xml +new file mode 100644 +index 00000000..e69de29b +diff --git a/result/errors10/781361.xml.err b/result/errors10/781361.xml.err +new file mode 100644 +index 00000000..655f41a2 +--- /dev/null ++++ b/result/errors10/781361.xml.err +@@ -0,0 +1,13 @@ ++./test/errors10/781361.xml:4: parser error : xmlParseElementDecl: 'EMPTY', 'ANY' or '(' expected ++ ++^ ++./test/errors10/781361.xml:4: parser error : internal error: xmlParseInternalSubset: error detected in Markup declaration ++ ++ ++^ ++./test/errors10/781361.xml:4: parser error : DOCTYPE improperly terminated ++ ++^ ++./test/errors10/781361.xml:4: parser error : Start tag expected, '<' not found ++ ++^ +diff --git a/result/valid/766956.xml b/result/valid/766956.xml +new file mode 100644 +index 00000000..e69de29b +diff --git a/result/valid/766956.xml.err b/result/valid/766956.xml.err +new file mode 100644 +index 00000000..34b1dae6 +--- /dev/null ++++ b/result/valid/766956.xml.err +@@ -0,0 +1,9 @@ ++test/valid/dtds/766956.dtd:2: parser error : PEReference: expecting ';' ++%ä%ent; ++ ^ ++Entity: line 1: parser error : Content error in the external subset ++ %ent; ++ ^ ++Entity: line 1: ++value ++^ +diff --git a/result/valid/766956.xml.err.rdr b/result/valid/766956.xml.err.rdr +new file mode 100644 +index 00000000..77603462 +--- /dev/null ++++ b/result/valid/766956.xml.err.rdr +@@ -0,0 +1,10 @@ ++test/valid/dtds/766956.dtd:2: parser error : PEReference: expecting ';' ++%ä%ent; ++ ^ ++Entity: line 1: parser error : Content error in the external subset ++ %ent; ++ ^ ++Entity: line 1: ++value ++^ ++./test/valid/766956.xml : failed to parse +diff --git a/test/errors10/781205.xml b/test/errors10/781205.xml +new file mode 100644 +index 00000000..d9e9e839 +--- /dev/null ++++ b/test/errors10/781205.xml +@@ -0,0 +1,3 @@ ++<!DOCTYPE D [ ++ <!ENTITY % a "<:0000"> ++ %a; +diff --git a/test/errors10/781361.xml b/test/errors10/781361.xml +new file mode 100644 +index 00000000..67476bcb +--- /dev/null ++++ b/test/errors10/781361.xml +@@ -0,0 +1,3 @@ ++<!DOCTYPE doc [ ++ <!ENTITY % elem "<!ELEMENT e0000000000"> ++ %elem; +diff --git a/test/valid/766956.xml b/test/valid/766956.xml +new file mode 100644 +index 00000000..19a95a0e +--- /dev/null ++++ b/test/valid/766956.xml +@@ -0,0 +1,2 @@ ++<!DOCTYPE test SYSTEM "dtds/766956.dtd"> ++<test/> +diff --git a/test/valid/dtds/766956.dtd b/test/valid/dtds/766956.dtd +new file mode 100644 +index 00000000..dddde68b +--- /dev/null ++++ b/test/valid/dtds/766956.dtd +@@ -0,0 +1,2 @@ ++<!ENTITY % ent "value"> ++%ä%ent; +-- +2.14.1 + diff --git a/gnu/packages/patches/libzip-CVE-2017-12858.patch b/gnu/packages/patches/libzip-CVE-2017-12858.patch new file mode 100644 index 0000000000..8125173f95 --- /dev/null +++ b/gnu/packages/patches/libzip-CVE-2017-12858.patch @@ -0,0 +1,45 @@ +Fix CVE-2017-12858: + +http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-12858 + +Patch copied from upstream source repository: + +https://github.com/nih-at/libzip/commit/2217022b7d1142738656d891e00b3d2d9179b796 + +From 2217022b7d1142738656d891e00b3d2d9179b796 Mon Sep 17 00:00:00 2001 +From: Thomas Klausner <tk@giga.or.at> +Date: Mon, 14 Aug 2017 10:55:44 +0200 +Subject: [PATCH] Fix double free(). + +Found by Brian 'geeknik' Carpenter using AFL. +--- + THANKS | 1 + + lib/zip_dirent.c | 3 --- + 2 files changed, 1 insertion(+), 3 deletions(-) + +diff --git a/THANKS b/THANKS +index be0cca9..a80ee1d 100644 +--- a/THANKS ++++ b/THANKS +@@ -12,6 +12,7 @@ BALATON Zoltan <balaton@eik.bme.hu> + Benjamin Gilbert <bgilbert@backtick.net> + Boaz Stolk <bstolk@aweta.nl> + Bogdan <bogiebog@gmail.com> ++Brian 'geeknik' Carpenter <geeknik@protonmail.ch> + Chris Nehren <cnehren+libzip@pobox.com> + Coverity <info@coverity.com> + Dane Springmeyer <dane.springmeyer@gmail.com> +diff --git a/lib/zip_dirent.c b/lib/zip_dirent.c +index a369900..e5a7cc9 100644 +--- a/lib/zip_dirent.c ++++ b/lib/zip_dirent.c +@@ -579,9 +579,6 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo + } + + if (!_zip_dirent_process_winzip_aes(zde, error)) { +- if (!from_buffer) { +- _zip_buffer_free(buffer); +- } + return -1; + } + diff --git a/gnu/packages/patches/metabat-fix-boost-issue.patch b/gnu/packages/patches/metabat-fix-boost-issue.patch deleted file mode 100644 index 3382d84d66..0000000000 --- a/gnu/packages/patches/metabat-fix-boost-issue.patch +++ /dev/null @@ -1,27 +0,0 @@ -This patch fixes the issue described at -https://bitbucket.org/berkeleylab/metabat/issues/28/compilation-fail-with-boost-164 - -diff --git a/src/metabat.h b/src/metabat.h -index 32ae94c..2292c04 100644 ---- a/src/metabat.h -+++ b/src/metabat.h -@@ -35,6 +35,7 @@ KSEQ_INIT(gzFile, gzread) - - #include <boost/program_options.hpp> - #include <boost/algorithm/string.hpp> -+#include <boost/serialization/array_wrapper.hpp> - #include <boost/numeric/ublas/matrix.hpp> - #include <boost/math/distributions.hpp> - #include <boost/serialization/serialization.hpp> -diff --git a/src/metabat2.h b/src/metabat2.h -index 60a9998..19fa815 100644 ---- a/src/metabat2.h -+++ b/src/metabat2.h -@@ -41,6 +41,7 @@ KSEQ_INIT(gzFile, gzread) - - #include <boost/program_options.hpp> - #include <boost/algorithm/string.hpp> -+#include <boost/serialization/array_wrapper.hpp> - #include <boost/numeric/ublas/matrix.hpp> - #include <boost/numeric/ublas/matrix_sparse.hpp> - #include <boost/numeric/ublas/matrix_proxy.hpp> diff --git a/gnu/packages/patches/metabat-remove-compilation-date.patch b/gnu/packages/patches/metabat-remove-compilation-date.patch deleted file mode 100644 index 7672205b22..0000000000 --- a/gnu/packages/patches/metabat-remove-compilation-date.patch +++ /dev/null @@ -1,16 +0,0 @@ -Remove the reference to the compilation date so that the build is -reproducible. - -diff --git a/src/metabat.cpp b/src/metabat.cpp -index 88e06de..c95cb1a 100644 ---- a/src/metabat.cpp -+++ b/src/metabat.cpp -@@ -49,7 +49,7 @@ int main(int ac, char* av[]) { - po::notify(vm); - - if (vm.count("help") || inFile.length() == 0 || outFile.length() == 0) { -- cerr << "\nMetaBAT: Metagenome Binning based on Abundance and Tetranucleotide frequency (version " << version << "; " << __DATE__ << " " << __TIME__ << ")" << endl; -+ cerr << "\nMetaBAT: Metagenome Binning based on Abundance and Tetranucleotide frequency (version " << version << "; unknown compilation date)" << endl; - cerr << "by Don Kang (ddkang@lbl.gov), Jeff Froula, Rob Egan, and Zhong Wang (zhongwang@lbl.gov) \n" << endl; - cerr << desc << endl << endl; - diff --git a/gnu/packages/patches/multiqc-fix-git-subprocess-error.patch b/gnu/packages/patches/multiqc-fix-git-subprocess-error.patch deleted file mode 100644 index 87be6142f4..0000000000 --- a/gnu/packages/patches/multiqc-fix-git-subprocess-error.patch +++ /dev/null @@ -1,16 +0,0 @@ -Without this patch, the incorrect exception is caught when 'git' is not in -PATH. See https://github.com/ewels/MultiQC/pull/377. - -diff --git a/multiqc/utils/config.py b/multiqc/utils/config.py -index 01fa554..4a11793 100755 ---- a/multiqc/utils/config.py -+++ b/multiqc/utils/config.py -@@ -28,7 +28,7 @@ try: - git_hash = subprocess.check_output(['git', 'rev-parse', 'HEAD'], stderr=subprocess.STDOUT) - git_hash_short = git_hash[:7] - version = '{} ({})'.format(version, git_hash_short) --except subprocess.CalledProcessError: -+except (subprocess.CalledProcessError, FileNotFoundError): - pass - os.chdir(cwd) - diff --git a/gnu/packages/patches/python2-larch-coverage-4.0a6-compatibility.patch b/gnu/packages/patches/python2-larch-coverage-4.0a6-compatibility.patch new file mode 100644 index 0000000000..f1db5d7c3b --- /dev/null +++ b/gnu/packages/patches/python2-larch-coverage-4.0a6-compatibility.patch @@ -0,0 +1,29 @@ +From ca548da9ba78ddee90779051210e3e89185e4f7d Mon Sep 17 00:00:00 2001 +From: Michel Alexandre Salim <michel@michel-slm.name> +Date: Mon, 15 Feb 2016 23:03:42 +0700 +Subject: coverage-4.0a6 compatibility + +coverage 4.0a6 no longer generates .coverage file, so use -f when +deleting .coverage to ensure deletion does not fail. +--- + Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +(limited to 'Makefile') + +diff --git a/Makefile b/Makefile +index 7818f57..362c07f 100644 +--- a/Makefile ++++ b/Makefile +@@ -23,7 +23,7 @@ fsck-larch.1: fsck-larch.1.in fsck-larch + + check: + python -m CoverageTestRunner --ignore-missing-from=without-tests +- rm .coverage ++ rm -f .coverage + ./insert-remove-test tempdir 100 + rm -r tempdir larch.log + cmdtest tests +-- +cgit v1.1 + diff --git a/gnu/packages/patches/qemu-CVE-2017-10664.patch b/gnu/packages/patches/qemu-CVE-2017-10664.patch deleted file mode 100644 index 2b60de3dca..0000000000 --- a/gnu/packages/patches/qemu-CVE-2017-10664.patch +++ /dev/null @@ -1,27 +0,0 @@ -Fix CVE-2017-10664: - -https://lists.gnu.org/archive/html/qemu-devel/2017-06/msg02693.html -https://bugzilla.redhat.com/show_bug.cgi?id=1466190 -https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-10664 -https://security-tracker.debian.org/tracker/CVE-2017-10664 - -Patch copied from upstream source repository: - -https://git.qemu.org/gitweb.cgi?p=qemu.git;a=commitdiff;h=041e32b8d9d076980b4e35317c0339e57ab888f1 - -diff --git a/qemu-nbd.c b/qemu-nbd.c -index 9464a0461c..4dd3fd4732 100644 ---- a/qemu-nbd.c -+++ b/qemu-nbd.c -@@ -581,6 +581,10 @@ int main(int argc, char **argv) - sa_sigterm.sa_handler = termsig_handler; - sigaction(SIGTERM, &sa_sigterm, NULL); - -+#ifdef CONFIG_POSIX -+ signal(SIGPIPE, SIG_IGN); -+#endif -+ - module_call_init(MODULE_INIT_TRACE); - qcrypto_init(&error_fatal); - - diff --git a/gnu/packages/patches/qemu-CVE-2017-10806.patch b/gnu/packages/patches/qemu-CVE-2017-10806.patch deleted file mode 100644 index ebf782fe7b..0000000000 --- a/gnu/packages/patches/qemu-CVE-2017-10806.patch +++ /dev/null @@ -1,38 +0,0 @@ -Fix CVE-2017-10806: - -https://lists.nongnu.org/archive/html/qemu-devel/2017-05/msg03087.html -https://bugzilla.redhat.com/show_bug.cgi?id=1468496 -https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-10806 -https://security-tracker.debian.org/tracker/CVE-2017-10806 - -Patch copied from upstream source repository: - -https://git.qemu.org/gitweb.cgi?p=qemu.git;a=commit;h=bd4a683505b27adc1ac809f71e918e58573d851d - -diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c -index b001a27f05..ad5ef783a6 100644 ---- a/hw/usb/redirect.c -+++ b/hw/usb/redirect.c -@@ -229,21 +229,10 @@ static void usbredir_log(void *priv, int level, const char *msg) - static void usbredir_log_data(USBRedirDevice *dev, const char *desc, - const uint8_t *data, int len) - { -- int i, j, n; -- - if (dev->debug < usbredirparser_debug_data) { - return; - } -- -- for (i = 0; i < len; i += j) { -- char buf[128]; -- -- n = sprintf(buf, "%s", desc); -- for (j = 0; j < 8 && i + j < len; j++) { -- n += sprintf(buf + n, " %02X", data[i + j]); -- } -- error_report("%s", buf); -- } -+ qemu_hexdump((char *)data, stderr, desc, len); - } - - /* diff --git a/gnu/packages/patches/qemu-CVE-2017-10911.patch b/gnu/packages/patches/qemu-CVE-2017-10911.patch deleted file mode 100644 index 1dcb860a2d..0000000000 --- a/gnu/packages/patches/qemu-CVE-2017-10911.patch +++ /dev/null @@ -1,106 +0,0 @@ -Fix CVE-2017-10911: - -https://xenbits.xen.org/xsa/advisory-216.html -https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-10911 -https://security-tracker.debian.org/tracker/CVE-2017-10911 - -Patch copied from Xen Security Advisory: - -https://xenbits.xen.org/xsa/xsa216-qemuu.patch - ---- a/hw/block/xen_blkif.h -+++ b/hw/block/xen_blkif.h -@@ -14,9 +14,6 @@ - struct blkif_common_request { - char dummy; - }; --struct blkif_common_response { -- char dummy; --}; - - /* i386 protocol version */ - #pragma pack(push, 4) -@@ -36,13 +33,7 @@ struct blkif_x86_32_request_discard { - blkif_sector_t sector_number; /* start sector idx on disk (r/w only) */ - uint64_t nr_sectors; /* # of contiguous sectors to discard */ - }; --struct blkif_x86_32_response { -- uint64_t id; /* copied from request */ -- uint8_t operation; /* copied from request */ -- int16_t status; /* BLKIF_RSP_??? */ --}; - typedef struct blkif_x86_32_request blkif_x86_32_request_t; --typedef struct blkif_x86_32_response blkif_x86_32_response_t; - #pragma pack(pop) - - /* x86_64 protocol version */ -@@ -62,20 +53,14 @@ struct blkif_x86_64_request_discard { - blkif_sector_t sector_number; /* start sector idx on disk (r/w only) */ - uint64_t nr_sectors; /* # of contiguous sectors to discard */ - }; --struct blkif_x86_64_response { -- uint64_t __attribute__((__aligned__(8))) id; -- uint8_t operation; /* copied from request */ -- int16_t status; /* BLKIF_RSP_??? */ --}; - typedef struct blkif_x86_64_request blkif_x86_64_request_t; --typedef struct blkif_x86_64_response blkif_x86_64_response_t; - - DEFINE_RING_TYPES(blkif_common, struct blkif_common_request, -- struct blkif_common_response); -+ struct blkif_response); - DEFINE_RING_TYPES(blkif_x86_32, struct blkif_x86_32_request, -- struct blkif_x86_32_response); -+ struct blkif_response QEMU_PACKED); - DEFINE_RING_TYPES(blkif_x86_64, struct blkif_x86_64_request, -- struct blkif_x86_64_response); -+ struct blkif_response); - - union blkif_back_rings { - blkif_back_ring_t native; ---- a/hw/block/xen_disk.c -+++ b/hw/block/xen_disk.c -@@ -769,31 +769,30 @@ static int blk_send_response_one(struct - struct XenBlkDev *blkdev = ioreq->blkdev; - int send_notify = 0; - int have_requests = 0; -- blkif_response_t resp; -- void *dst; -- -- resp.id = ioreq->req.id; -- resp.operation = ioreq->req.operation; -- resp.status = ioreq->status; -+ blkif_response_t *resp; - - /* Place on the response ring for the relevant domain. */ - switch (blkdev->protocol) { - case BLKIF_PROTOCOL_NATIVE: -- dst = RING_GET_RESPONSE(&blkdev->rings.native, blkdev->rings.native.rsp_prod_pvt); -+ resp = RING_GET_RESPONSE(&blkdev->rings.native, -+ blkdev->rings.native.rsp_prod_pvt); - break; - case BLKIF_PROTOCOL_X86_32: -- dst = RING_GET_RESPONSE(&blkdev->rings.x86_32_part, -- blkdev->rings.x86_32_part.rsp_prod_pvt); -+ resp = RING_GET_RESPONSE(&blkdev->rings.x86_32_part, -+ blkdev->rings.x86_32_part.rsp_prod_pvt); - break; - case BLKIF_PROTOCOL_X86_64: -- dst = RING_GET_RESPONSE(&blkdev->rings.x86_64_part, -- blkdev->rings.x86_64_part.rsp_prod_pvt); -+ resp = RING_GET_RESPONSE(&blkdev->rings.x86_64_part, -+ blkdev->rings.x86_64_part.rsp_prod_pvt); - break; - default: -- dst = NULL; - return 0; - } -- memcpy(dst, &resp, sizeof(resp)); -+ -+ resp->id = ioreq->req.id; -+ resp->operation = ioreq->req.operation; -+ resp->status = ioreq->status; -+ - blkdev->rings.common.rsp_prod_pvt++; - - RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&blkdev->rings.common, send_notify); diff --git a/gnu/packages/patches/qemu-CVE-2017-11334.patch b/gnu/packages/patches/qemu-CVE-2017-11334.patch deleted file mode 100644 index cb68c803aa..0000000000 --- a/gnu/packages/patches/qemu-CVE-2017-11334.patch +++ /dev/null @@ -1,52 +0,0 @@ -Fix CVE-2017-11334: - -https://bugzilla.redhat.com/show_bug.cgi?id=1471638 -https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-11334 - -Patch copied from upstream source repository: - -http://git.qemu.org/?p=qemu.git;a=commitdiff;h=04bf2526ce87f21b32c9acba1c5518708c243ad0 - -From 04bf2526ce87f21b32c9acba1c5518708c243ad0 Mon Sep 17 00:00:00 2001 -From: Prasad J Pandit <pjp@fedoraproject.org> -Date: Wed, 12 Jul 2017 18:08:40 +0530 -Subject: [PATCH] exec: use qemu_ram_ptr_length to access guest ram - -When accessing guest's ram block during DMA operation, use -'qemu_ram_ptr_length' to get ram block pointer. It ensures -that DMA operation of given length is possible; And avoids -any OOB memory access situations. - -Reported-by: Alex <broscutamaker@gmail.com> -Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org> -Message-Id: <20170712123840.29328-1-ppandit@redhat.com> -Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> ---- - exec.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/exec.c b/exec.c -index a083ff89ad..ad103ce483 100644 ---- a/exec.c -+++ b/exec.c -@@ -2929,7 +2929,7 @@ static MemTxResult address_space_write_continue(AddressSpace *as, hwaddr addr, - } - } else { - /* RAM case */ -- ptr = qemu_map_ram_ptr(mr->ram_block, addr1); -+ ptr = qemu_ram_ptr_length(mr->ram_block, addr1, &l); - memcpy(ptr, buf, l); - invalidate_and_set_dirty(mr, addr1, l); - } -@@ -3020,7 +3020,7 @@ MemTxResult address_space_read_continue(AddressSpace *as, hwaddr addr, - } - } else { - /* RAM case */ -- ptr = qemu_map_ram_ptr(mr->ram_block, addr1); -+ ptr = qemu_ram_ptr_length(mr->ram_block, addr1, &l); - memcpy(buf, ptr, l); - } - --- -2.13.3 - diff --git a/gnu/packages/patches/qemu-CVE-2017-11434.patch b/gnu/packages/patches/qemu-CVE-2017-11434.patch deleted file mode 100644 index 4da701a73d..0000000000 --- a/gnu/packages/patches/qemu-CVE-2017-11434.patch +++ /dev/null @@ -1,25 +0,0 @@ -Fix CVE-2017-11434: - -https://lists.gnu.org/archive/html/qemu-devel/2017-07/msg05001.html -https://bugzilla.redhat.com/show_bug.cgi?id=1472611 -https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-11434 -https://security-tracker.debian.org/tracker/CVE-2017-11434 - -Patch copied from upstream source repository: - -https://git.qemu.org/gitweb.cgi?p=qemu.git;a=commit;h=413d463f43fbc4dd3a601e80a5724aa384a265a0 - -diff --git a/slirp/bootp.c b/slirp/bootp.c -index 5a4646c182..5dd1a415b5 100644 ---- a/slirp/bootp.c -+++ b/slirp/bootp.c -@@ -123,6 +123,9 @@ static void dhcp_decode(const struct bootp_t *bp, int *pmsg_type, - if (p >= p_end) - break; - len = *p++; -+ if (p + len > p_end) { -+ break; -+ } - DPRINTF("dhcp: tag=%d len=%d\n", tag, len); - - switch(tag) { diff --git a/gnu/packages/patches/qemu-CVE-2017-12809.patch b/gnu/packages/patches/qemu-CVE-2017-12809.patch deleted file mode 100644 index e40a14b4e0..0000000000 --- a/gnu/packages/patches/qemu-CVE-2017-12809.patch +++ /dev/null @@ -1,38 +0,0 @@ -http://openwall.com/lists/oss-security/2017/08/21/2 -https://lists.gnu.org/archive/html/qemu-devel/2017-08/msg01850.html - -The block backend changed in a way that flushing empty CDROM drives now -crashes. Amend IDE to avoid doing so until the root problem can be -addressed for 2.11. - -Original patch by John Snow <address@hidden>. - -Reported-by: Kieron Shorrock <address@hidden> -Signed-off-by: Stefan Hajnoczi <address@hidden> ---- - hw/ide/core.c | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - -diff --git a/hw/ide/core.c b/hw/ide/core.c -index 0b48b64d3a..bea39536b0 100644 ---- a/hw/ide/core.c -+++ b/hw/ide/core.c -@@ -1063,7 +1063,15 @@ static void ide_flush_cache(IDEState *s) - s->status |= BUSY_STAT; - ide_set_retry(s); - block_acct_start(blk_get_stats(s->blk), &s->acct, 0, BLOCK_ACCT_FLUSH); -- s->pio_aiocb = blk_aio_flush(s->blk, ide_flush_cb, s); -+ -+ if (blk_bs(s->blk)) { -+ s->pio_aiocb = blk_aio_flush(s->blk, ide_flush_cb, s); -+ } else { -+ /* XXX blk_aio_flush() crashes when blk_bs(blk) is NULL, remove this -+ * temporary workaround when blk_aio_*() functions handle NULL blk_bs. -+ */ -+ ide_flush_cb(s, 0); -+ } - } - - static void ide_cfata_metadata_inquiry(IDEState *s) --- -2.13.3 diff --git a/gnu/packages/patches/qemu-CVE-2017-7493.patch b/gnu/packages/patches/qemu-CVE-2017-7493.patch deleted file mode 100644 index 67b26fad81..0000000000 --- a/gnu/packages/patches/qemu-CVE-2017-7493.patch +++ /dev/null @@ -1,182 +0,0 @@ -Fix CVE-2017-7493: - -https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-7493 - -Patch copied from upstream source repository: - -http://git.qemu.org/?p=qemu.git;a=commit;h=7a95434e0ca8a037fd8aa1a2e2461f92585eb77b - -From 7a95434e0ca8a037fd8aa1a2e2461f92585eb77b Mon Sep 17 00:00:00 2001 -From: Greg Kurz <groug@kaod.org> -Date: Fri, 5 May 2017 14:48:08 +0200 -Subject: [PATCH] 9pfs: local: forbid client access to metadata (CVE-2017-7493) - -When using the mapped-file security mode, we shouldn't let the client mess -with the metadata. The current code already tries to hide the metadata dir -from the client by skipping it in local_readdir(). But the client can still -access or modify it through several other operations. This can be used to -escalate privileges in the guest. - -Affected backend operations are: -- local_mknod() -- local_mkdir() -- local_open2() -- local_symlink() -- local_link() -- local_unlinkat() -- local_renameat() -- local_rename() -- local_name_to_path() - -Other operations are safe because they are only passed a fid path, which -is computed internally in local_name_to_path(). - -This patch converts all the functions listed above to fail and return -EINVAL when being passed the name of the metadata dir. This may look -like a poor choice for errno, but there's no such thing as an illegal -path name on Linux and I could not think of anything better. - -This fixes CVE-2017-7493. - -Reported-by: Leo Gaspard <leo@gaspard.io> -Signed-off-by: Greg Kurz <groug@kaod.org> -Reviewed-by: Eric Blake <eblake@redhat.com> ---- - hw/9pfs/9p-local.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- - 1 file changed, 56 insertions(+), 2 deletions(-) - -diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c -index f3ebca4f7a..a2486566af 100644 ---- a/hw/9pfs/9p-local.c -+++ b/hw/9pfs/9p-local.c -@@ -452,6 +452,11 @@ static off_t local_telldir(FsContext *ctx, V9fsFidOpenState *fs) - return telldir(fs->dir.stream); - } - -+static bool local_is_mapped_file_metadata(FsContext *fs_ctx, const char *name) -+{ -+ return !strcmp(name, VIRTFS_META_DIR); -+} -+ - static struct dirent *local_readdir(FsContext *ctx, V9fsFidOpenState *fs) - { - struct dirent *entry; -@@ -465,8 +470,8 @@ again: - if (ctx->export_flags & V9FS_SM_MAPPED) { - entry->d_type = DT_UNKNOWN; - } else if (ctx->export_flags & V9FS_SM_MAPPED_FILE) { -- if (!strcmp(entry->d_name, VIRTFS_META_DIR)) { -- /* skp the meta data directory */ -+ if (local_is_mapped_file_metadata(ctx, entry->d_name)) { -+ /* skip the meta data directory */ - goto again; - } - entry->d_type = DT_UNKNOWN; -@@ -559,6 +564,12 @@ static int local_mknod(FsContext *fs_ctx, V9fsPath *dir_path, - int err = -1; - int dirfd; - -+ if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE && -+ local_is_mapped_file_metadata(fs_ctx, name)) { -+ errno = EINVAL; -+ return -1; -+ } -+ - dirfd = local_opendir_nofollow(fs_ctx, dir_path->data); - if (dirfd == -1) { - return -1; -@@ -605,6 +616,12 @@ static int local_mkdir(FsContext *fs_ctx, V9fsPath *dir_path, - int err = -1; - int dirfd; - -+ if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE && -+ local_is_mapped_file_metadata(fs_ctx, name)) { -+ errno = EINVAL; -+ return -1; -+ } -+ - dirfd = local_opendir_nofollow(fs_ctx, dir_path->data); - if (dirfd == -1) { - return -1; -@@ -694,6 +711,12 @@ static int local_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name, - int err = -1; - int dirfd; - -+ if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE && -+ local_is_mapped_file_metadata(fs_ctx, name)) { -+ errno = EINVAL; -+ return -1; -+ } -+ - /* - * Mark all the open to not follow symlinks - */ -@@ -752,6 +775,12 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath, - int err = -1; - int dirfd; - -+ if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE && -+ local_is_mapped_file_metadata(fs_ctx, name)) { -+ errno = EINVAL; -+ return -1; -+ } -+ - dirfd = local_opendir_nofollow(fs_ctx, dir_path->data); - if (dirfd == -1) { - return -1; -@@ -826,6 +855,12 @@ static int local_link(FsContext *ctx, V9fsPath *oldpath, - int ret = -1; - int odirfd, ndirfd; - -+ if (ctx->export_flags & V9FS_SM_MAPPED_FILE && -+ local_is_mapped_file_metadata(ctx, name)) { -+ errno = EINVAL; -+ return -1; -+ } -+ - odirfd = local_opendir_nofollow(ctx, odirpath); - if (odirfd == -1) { - goto out; -@@ -1096,6 +1131,12 @@ static int local_lremovexattr(FsContext *ctx, V9fsPath *fs_path, - static int local_name_to_path(FsContext *ctx, V9fsPath *dir_path, - const char *name, V9fsPath *target) - { -+ if (ctx->export_flags & V9FS_SM_MAPPED_FILE && -+ local_is_mapped_file_metadata(ctx, name)) { -+ errno = EINVAL; -+ return -1; -+ } -+ - if (dir_path) { - v9fs_path_sprintf(target, "%s/%s", dir_path->data, name); - } else if (strcmp(name, "/")) { -@@ -1116,6 +1157,13 @@ static int local_renameat(FsContext *ctx, V9fsPath *olddir, - int ret; - int odirfd, ndirfd; - -+ if (ctx->export_flags & V9FS_SM_MAPPED_FILE && -+ (local_is_mapped_file_metadata(ctx, old_name) || -+ local_is_mapped_file_metadata(ctx, new_name))) { -+ errno = EINVAL; -+ return -1; -+ } -+ - odirfd = local_opendir_nofollow(ctx, olddir->data); - if (odirfd == -1) { - return -1; -@@ -1206,6 +1254,12 @@ static int local_unlinkat(FsContext *ctx, V9fsPath *dir, - int ret; - int dirfd; - -+ if (ctx->export_flags & V9FS_SM_MAPPED_FILE && -+ local_is_mapped_file_metadata(ctx, name)) { -+ errno = EINVAL; -+ return -1; -+ } -+ - dirfd = local_opendir_nofollow(ctx, dir->data); - if (dirfd == -1) { - return -1; --- -2.13.0 - diff --git a/gnu/packages/patches/qemu-CVE-2017-8112.patch b/gnu/packages/patches/qemu-CVE-2017-8112.patch deleted file mode 100644 index 88b33aa2f0..0000000000 --- a/gnu/packages/patches/qemu-CVE-2017-8112.patch +++ /dev/null @@ -1,41 +0,0 @@ -Fix CVE-2017-8112: - -https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-8112 - -Patch copied from upstream source repository: - -http://git.qemu.org/?p=qemu.git;a=commitdiff;h=f68826989cd4d1217797251339579c57b3c0934e - -From f68826989cd4d1217797251339579c57b3c0934e Mon Sep 17 00:00:00 2001 -From: P J P <ppandit@redhat.com> -Date: Tue, 25 Apr 2017 18:36:23 +0530 -Subject: [PATCH] vmw_pvscsi: check message ring page count at initialisation - -A guest could set the message ring page count to zero, resulting in -infinite loop. Add check to avoid it. - -Reported-by: YY Z <bigbird475958471@gmail.com> -Signed-off-by: P J P <ppandit@redhat.com> -Message-Id: <20170425130623.3649-1-ppandit@redhat.com> -Reviewed-by: Dmitry Fleytman <dmitry@daynix.com> -Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> ---- - hw/scsi/vmw_pvscsi.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c -index 75575461e2..4a106da856 100644 ---- a/hw/scsi/vmw_pvscsi.c -+++ b/hw/scsi/vmw_pvscsi.c -@@ -202,7 +202,7 @@ pvscsi_ring_init_msg(PVSCSIRingInfo *m, PVSCSICmdDescSetupMsgRing *ri) - uint32_t len_log2; - uint32_t ring_size; - -- if (ri->numPages > PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES) { -+ if (!ri->numPages || ri->numPages > PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES) { - return -1; - } - ring_size = ri->numPages * PVSCSI_MAX_NUM_MSG_ENTRIES_PER_PAGE; --- -2.13.0 - diff --git a/gnu/packages/patches/qemu-CVE-2017-8309.patch b/gnu/packages/patches/qemu-CVE-2017-8309.patch deleted file mode 100644 index dc4b4006b7..0000000000 --- a/gnu/packages/patches/qemu-CVE-2017-8309.patch +++ /dev/null @@ -1,46 +0,0 @@ -Fix CVE-2017-8309: - -https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-8309 - -Patch copied from upstream source repository: - -http://git.qemu.org/?p=qemu.git;a=commitdiff;h=3268a845f41253fb55852a8429c32b50f36f349a - -From 3268a845f41253fb55852a8429c32b50f36f349a Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann <kraxel@redhat.com> -Date: Fri, 28 Apr 2017 09:56:12 +0200 -Subject: [PATCH] audio: release capture buffers - -AUD_add_capture() allocates two buffers which are never released. -Add the missing calls to AUD_del_capture(). - -Impact: Allows vnc clients to exhaust host memory by repeatedly -starting and stopping audio capture. - -Fixes: CVE-2017-8309 -Cc: P J P <ppandit@redhat.com> -Cc: Huawei PSIRT <PSIRT@huawei.com> -Reported-by: "Jiangxin (hunter, SCC)" <jiangxin1@huawei.com> -Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> -Reviewed-by: Prasad J Pandit <pjp@fedoraproject.org> -Message-id: 20170428075612.9997-1-kraxel@redhat.com ---- - audio/audio.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/audio/audio.c b/audio/audio.c -index c8898d8422..beafed209b 100644 ---- a/audio/audio.c -+++ b/audio/audio.c -@@ -2028,6 +2028,8 @@ void AUD_del_capture (CaptureVoiceOut *cap, void *cb_opaque) - sw = sw1; - } - QLIST_REMOVE (cap, entries); -+ g_free (cap->hw.mix_buf); -+ g_free (cap->buf); - g_free (cap); - } - return; --- -2.13.0 - diff --git a/gnu/packages/patches/qemu-CVE-2017-8379.patch b/gnu/packages/patches/qemu-CVE-2017-8379.patch deleted file mode 100644 index 200b133d3e..0000000000 --- a/gnu/packages/patches/qemu-CVE-2017-8379.patch +++ /dev/null @@ -1,98 +0,0 @@ -Fix CVE-2017-8379: - -https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-8379 - -Patch copied from upstream source repository: - -http://git.qemu.org/?p=qemu.git;a=commitdiff;h=fa18f36a461984eae50ab957e47ec78dae3c14fc - -From fa18f36a461984eae50ab957e47ec78dae3c14fc Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann <kraxel@redhat.com> -Date: Fri, 28 Apr 2017 10:42:37 +0200 -Subject: [PATCH] input: limit kbd queue depth - -Apply a limit to the number of items we accept into the keyboard queue. - -Impact: Without this limit vnc clients can exhaust host memory by -sending keyboard events faster than qemu feeds them to the guest. - -Fixes: CVE-2017-8379 -Cc: P J P <ppandit@redhat.com> -Cc: Huawei PSIRT <PSIRT@huawei.com> -Reported-by: jiangxin1@huawei.com -Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> -Message-id: 20170428084237.23960-1-kraxel@redhat.com ---- - ui/input.c | 14 +++++++++++--- - 1 file changed, 11 insertions(+), 3 deletions(-) - -diff --git a/ui/input.c b/ui/input.c -index ed88cda6d6..fb1f404095 100644 ---- a/ui/input.c -+++ b/ui/input.c -@@ -41,6 +41,8 @@ static QTAILQ_HEAD(QemuInputEventQueueHead, QemuInputEventQueue) kbd_queue = - QTAILQ_HEAD_INITIALIZER(kbd_queue); - static QEMUTimer *kbd_timer; - static uint32_t kbd_default_delay_ms = 10; -+static uint32_t queue_count; -+static uint32_t queue_limit = 1024; - - QemuInputHandlerState *qemu_input_handler_register(DeviceState *dev, - QemuInputHandler *handler) -@@ -268,6 +270,7 @@ static void qemu_input_queue_process(void *opaque) - break; - } - QTAILQ_REMOVE(queue, item, node); -+ queue_count--; - g_free(item); - } - } -@@ -282,6 +285,7 @@ static void qemu_input_queue_delay(struct QemuInputEventQueueHead *queue, - item->delay_ms = delay_ms; - item->timer = timer; - QTAILQ_INSERT_TAIL(queue, item, node); -+ queue_count++; - - if (start_timer) { - timer_mod(item->timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) -@@ -298,6 +302,7 @@ static void qemu_input_queue_event(struct QemuInputEventQueueHead *queue, - item->src = src; - item->evt = evt; - QTAILQ_INSERT_TAIL(queue, item, node); -+ queue_count++; - } - - static void qemu_input_queue_sync(struct QemuInputEventQueueHead *queue) -@@ -306,6 +311,7 @@ static void qemu_input_queue_sync(struct QemuInputEventQueueHead *queue) - - item->type = QEMU_INPUT_QUEUE_SYNC; - QTAILQ_INSERT_TAIL(queue, item, node); -+ queue_count++; - } - - void qemu_input_event_send_impl(QemuConsole *src, InputEvent *evt) -@@ -381,7 +387,7 @@ void qemu_input_event_send_key(QemuConsole *src, KeyValue *key, bool down) - qemu_input_event_send(src, evt); - qemu_input_event_sync(); - qapi_free_InputEvent(evt); -- } else { -+ } else if (queue_count < queue_limit) { - qemu_input_queue_event(&kbd_queue, src, evt); - qemu_input_queue_sync(&kbd_queue); - } -@@ -409,8 +415,10 @@ void qemu_input_event_send_key_delay(uint32_t delay_ms) - kbd_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, qemu_input_queue_process, - &kbd_queue); - } -- qemu_input_queue_delay(&kbd_queue, kbd_timer, -- delay_ms ? delay_ms : kbd_default_delay_ms); -+ if (queue_count < queue_limit) { -+ qemu_input_queue_delay(&kbd_queue, kbd_timer, -+ delay_ms ? delay_ms : kbd_default_delay_ms); -+ } - } - - InputEvent *qemu_input_event_new_btn(InputButton btn, bool down) --- -2.13.0 - diff --git a/gnu/packages/patches/qemu-CVE-2017-8380.patch b/gnu/packages/patches/qemu-CVE-2017-8380.patch deleted file mode 100644 index 65e49fc885..0000000000 --- a/gnu/packages/patches/qemu-CVE-2017-8380.patch +++ /dev/null @@ -1,53 +0,0 @@ -Fix CVE-2017-8380: - -https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-8380 - -Patch copied from upstream source repository: - -http://git.qemu.org/?p=qemu.git;a=commitdiff;h=24dfa9fa2f90a95ac33c7372de4f4f2c8a2c141f - -From 24dfa9fa2f90a95ac33c7372de4f4f2c8a2c141f Mon Sep 17 00:00:00 2001 -From: Prasad J Pandit <pjp@fedoraproject.org> -Date: Mon, 24 Apr 2017 17:36:34 +0530 -Subject: [PATCH] scsi: avoid an off-by-one error in megasas_mmio_write - -While reading magic sequence(MFI_SEQ) in megasas_mmio_write, -an off-by-one error could occur as 's->adp_reset' index is not -reset after reading the last sequence. - -Reported-by: YY Z <bigbird475958471@gmail.com> -Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org> -Message-Id: <20170424120634.12268-1-ppandit@redhat.com> -Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> ---- - hw/scsi/megasas.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c -index 84b8caf901..804122ab05 100644 ---- a/hw/scsi/megasas.c -+++ b/hw/scsi/megasas.c -@@ -2138,15 +2138,15 @@ static void megasas_mmio_write(void *opaque, hwaddr addr, - case MFI_SEQ: - trace_megasas_mmio_writel("MFI_SEQ", val); - /* Magic sequence to start ADP reset */ -- if (adp_reset_seq[s->adp_reset] == val) { -- s->adp_reset++; -+ if (adp_reset_seq[s->adp_reset++] == val) { -+ if (s->adp_reset == 6) { -+ s->adp_reset = 0; -+ s->diag = MFI_DIAG_WRITE_ENABLE; -+ } - } else { - s->adp_reset = 0; - s->diag = 0; - } -- if (s->adp_reset == 6) { -- s->diag = MFI_DIAG_WRITE_ENABLE; -- } - break; - case MFI_DIAG: - trace_megasas_mmio_writel("MFI_DIAG", val); --- -2.13.0 - diff --git a/gnu/packages/patches/qemu-CVE-2017-9524.patch b/gnu/packages/patches/qemu-CVE-2017-9524.patch deleted file mode 100644 index 57160055e3..0000000000 --- a/gnu/packages/patches/qemu-CVE-2017-9524.patch +++ /dev/null @@ -1,287 +0,0 @@ -Fix CVE-2017-9524: - -https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-9524 -http://seclists.org/oss-sec/2017/q2/454 - -Patches copied from upstream source repository: - -http://git.qemu.org/?p=qemu.git;a=commitdiff;h=df8ad9f128c15aa0a0ebc7b24e9a22c9775b67af -http://git.qemu.org/?p=qemu.git;a=commitdiff;h=0c9390d978cbf61e8f16c9f580fa96b305c43568 - -From df8ad9f128c15aa0a0ebc7b24e9a22c9775b67af Mon Sep 17 00:00:00 2001 -From: Eric Blake <eblake@redhat.com> -Date: Fri, 26 May 2017 22:04:21 -0500 -Subject: [PATCH] nbd: Fully initialize client in case of failed negotiation - -If a non-NBD client connects to qemu-nbd, we would end up with -a SIGSEGV in nbd_client_put() because we were trying to -unregister the client's association to the export, even though -we skipped inserting the client into that list. Easy trigger -in two terminals: - -$ qemu-nbd -p 30001 --format=raw file -$ nmap 127.0.0.1 -p 30001 - -nmap claims that it thinks it connected to a pago-services1 -server (which probably means nmap could be updated to learn the -NBD protocol and give a more accurate diagnosis of the open -port - but that's not our problem), then terminates immediately, -so our call to nbd_negotiate() fails. The fix is to reorder -nbd_co_client_start() to ensure that all initialization occurs -before we ever try talking to a client in nbd_negotiate(), so -that the teardown sequence on negotiation failure doesn't fault -while dereferencing a half-initialized object. - -While debugging this, I also noticed that nbd_update_server_watch() -called by nbd_client_closed() was still adding a channel to accept -the next client, even when the state was no longer RUNNING. That -is fixed by making nbd_can_accept() pay attention to the current -state. - -Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1451614 - -Signed-off-by: Eric Blake <eblake@redhat.com> -Message-Id: <20170527030421.28366-1-eblake@redhat.com> -Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> ---- - nbd/server.c | 8 +++----- - qemu-nbd.c | 2 +- - 2 files changed, 4 insertions(+), 6 deletions(-) - -diff --git a/nbd/server.c b/nbd/server.c -index ee59e5d234..49b55f6ede 100644 ---- a/nbd/server.c -+++ b/nbd/server.c -@@ -1358,16 +1358,14 @@ static coroutine_fn void nbd_co_client_start(void *opaque) - - if (exp) { - nbd_export_get(exp); -+ QTAILQ_INSERT_TAIL(&exp->clients, client, next); - } -+ qemu_co_mutex_init(&client->send_lock); -+ - if (nbd_negotiate(data)) { - client_close(client); - goto out; - } -- qemu_co_mutex_init(&client->send_lock); -- -- if (exp) { -- QTAILQ_INSERT_TAIL(&exp->clients, client, next); -- } - - nbd_client_receive_next_request(client); - -diff --git a/qemu-nbd.c b/qemu-nbd.c -index f60842fd86..651f85ecc1 100644 ---- a/qemu-nbd.c -+++ b/qemu-nbd.c -@@ -325,7 +325,7 @@ out: - - static int nbd_can_accept(void) - { -- return nb_fds < shared; -+ return state == RUNNING && nb_fds < shared; - } - - static void nbd_export_closed(NBDExport *exp) --- -2.13.1 - -From 0c9390d978cbf61e8f16c9f580fa96b305c43568 Mon Sep 17 00:00:00 2001 -From: Eric Blake <eblake@redhat.com> -Date: Thu, 8 Jun 2017 17:26:17 -0500 -Subject: [PATCH] nbd: Fix regression on resiliency to port scan - -Back in qemu 2.5, qemu-nbd was immune to port probes (a transient -server would not quit, regardless of how many probe connections -came and went, until a connection actually negotiated). But we -broke that in commit ee7d7aa when removing the return value to -nbd_client_new(), although that patch also introduced a bug causing -an assertion failure on a client that fails negotiation. We then -made it worse during refactoring in commit 1a6245a (a segfault -before we could even assert); the (masked) assertion was cleaned -up in d3780c2 (still in 2.6), and just recently we finally fixed -the segfault ("nbd: Fully intialize client in case of failed -negotiation"). But that still means that ever since we added -TLS support to qemu-nbd, we have been vulnerable to an ill-timed -port-scan being able to cause a denial of service by taking down -qemu-nbd before a real client has a chance to connect. - -Since negotiation is now handled asynchronously via coroutines, -we no longer have a synchronous point of return by re-adding a -return value to nbd_client_new(). So this patch instead wires -things up to pass the negotiation status through the close_fn -callback function. - -Simple test across two terminals: -$ qemu-nbd -f raw -p 30001 file -$ nmap 127.0.0.1 -p 30001 && \ - qemu-io -c 'r 0 512' -f raw nbd://localhost:30001 - -Note that this patch does not change what constitutes successful -negotiation (thus, a client must enter transmission phase before -that client can be considered as a reason to terminate the server -when the connection ends). Perhaps we may want to tweak things -in a later patch to also treat a client that uses NBD_OPT_ABORT -as being a 'successful' negotiation (the client correctly talked -the NBD protocol, and informed us it was not going to use our -export after all), but that's a discussion for another day. - -Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1451614 - -Signed-off-by: Eric Blake <eblake@redhat.com> -Message-Id: <20170608222617.20376-1-eblake@redhat.com> -Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> ---- - blockdev-nbd.c | 6 +++++- - include/block/nbd.h | 2 +- - nbd/server.c | 24 +++++++++++++++--------- - qemu-nbd.c | 4 ++-- - 4 files changed, 23 insertions(+), 13 deletions(-) - -diff --git a/blockdev-nbd.c b/blockdev-nbd.c -index dd0860f4a6..28f551a7b0 100644 ---- a/blockdev-nbd.c -+++ b/blockdev-nbd.c -@@ -27,6 +27,10 @@ typedef struct NBDServerData { - - static NBDServerData *nbd_server; - -+static void nbd_blockdev_client_closed(NBDClient *client, bool ignored) -+{ -+ nbd_client_put(client); -+} - - static gboolean nbd_accept(QIOChannel *ioc, GIOCondition condition, - gpointer opaque) -@@ -46,7 +50,7 @@ static gboolean nbd_accept(QIOChannel *ioc, GIOCondition condition, - qio_channel_set_name(QIO_CHANNEL(cioc), "nbd-server"); - nbd_client_new(NULL, cioc, - nbd_server->tlscreds, NULL, -- nbd_client_put); -+ nbd_blockdev_client_closed); - object_unref(OBJECT(cioc)); - return TRUE; - } -diff --git a/include/block/nbd.h b/include/block/nbd.h -index 416257abca..8fa5ce51f3 100644 ---- a/include/block/nbd.h -+++ b/include/block/nbd.h -@@ -162,7 +162,7 @@ void nbd_client_new(NBDExport *exp, - QIOChannelSocket *sioc, - QCryptoTLSCreds *tlscreds, - const char *tlsaclname, -- void (*close)(NBDClient *)); -+ void (*close_fn)(NBDClient *, bool)); - void nbd_client_get(NBDClient *client); - void nbd_client_put(NBDClient *client); - -diff --git a/nbd/server.c b/nbd/server.c -index 49b55f6ede..f2b1aa47ce 100644 ---- a/nbd/server.c -+++ b/nbd/server.c -@@ -81,7 +81,7 @@ static QTAILQ_HEAD(, NBDExport) exports = QTAILQ_HEAD_INITIALIZER(exports); - - struct NBDClient { - int refcount; -- void (*close)(NBDClient *client); -+ void (*close_fn)(NBDClient *client, bool negotiated); - - bool no_zeroes; - NBDExport *exp; -@@ -778,7 +778,7 @@ void nbd_client_put(NBDClient *client) - } - } - --static void client_close(NBDClient *client) -+static void client_close(NBDClient *client, bool negotiated) - { - if (client->closing) { - return; -@@ -793,8 +793,8 @@ static void client_close(NBDClient *client) - NULL); - - /* Also tell the client, so that they release their reference. */ -- if (client->close) { -- client->close(client); -+ if (client->close_fn) { -+ client->close_fn(client, negotiated); - } - } - -@@ -975,7 +975,7 @@ void nbd_export_close(NBDExport *exp) - - nbd_export_get(exp); - QTAILQ_FOREACH_SAFE(client, &exp->clients, next, next) { -- client_close(client); -+ client_close(client, true); - } - nbd_export_set_name(exp, NULL); - nbd_export_set_description(exp, NULL); -@@ -1337,7 +1337,7 @@ done: - - out: - nbd_request_put(req); -- client_close(client); -+ client_close(client, true); - nbd_client_put(client); - } - -@@ -1363,7 +1363,7 @@ static coroutine_fn void nbd_co_client_start(void *opaque) - qemu_co_mutex_init(&client->send_lock); - - if (nbd_negotiate(data)) { -- client_close(client); -+ client_close(client, false); - goto out; - } - -@@ -1373,11 +1373,17 @@ out: - g_free(data); - } - -+/* -+ * Create a new client listener on the given export @exp, using the -+ * given channel @sioc. Begin servicing it in a coroutine. When the -+ * connection closes, call @close_fn with an indication of whether the -+ * client completed negotiation. -+ */ - void nbd_client_new(NBDExport *exp, - QIOChannelSocket *sioc, - QCryptoTLSCreds *tlscreds, - const char *tlsaclname, -- void (*close_fn)(NBDClient *)) -+ void (*close_fn)(NBDClient *, bool)) - { - NBDClient *client; - NBDClientNewData *data = g_new(NBDClientNewData, 1); -@@ -1394,7 +1400,7 @@ void nbd_client_new(NBDExport *exp, - object_ref(OBJECT(client->sioc)); - client->ioc = QIO_CHANNEL(sioc); - object_ref(OBJECT(client->ioc)); -- client->close = close_fn; -+ client->close_fn = close_fn; - - data->client = client; - data->co = qemu_coroutine_create(nbd_co_client_start, data); -diff --git a/qemu-nbd.c b/qemu-nbd.c -index 651f85ecc1..9464a0461c 100644 ---- a/qemu-nbd.c -+++ b/qemu-nbd.c -@@ -336,10 +336,10 @@ static void nbd_export_closed(NBDExport *exp) - - static void nbd_update_server_watch(void); - --static void nbd_client_closed(NBDClient *client) -+static void nbd_client_closed(NBDClient *client, bool negotiated) - { - nb_fds--; -- if (nb_fds == 0 && !persistent && state == RUNNING) { -+ if (negotiated && nb_fds == 0 && !persistent && state == RUNNING) { - state = TERMINATE; - } - nbd_update_server_watch(); --- -2.13.1 - diff --git a/gnu/packages/patches/ruby-2.2.7-rubygems-2613-ruby22.patch b/gnu/packages/patches/ruby-2.2.7-rubygems-2613-ruby22.patch new file mode 100644 index 0000000000..d68b836c71 --- /dev/null +++ b/gnu/packages/patches/ruby-2.2.7-rubygems-2613-ruby22.patch @@ -0,0 +1,355 @@ +diff --git lib/rubygems.rb lib/rubygems.rb +index f48496aa31..0e1855b148 100644 +--- ruby-2.2.7/lib/rubygems.rb ++++ ruby-2.2.7/lib/rubygems.rb +@@ -9,7 +9,7 @@ require 'rbconfig' + require 'thread' + + module Gem +- VERSION = '2.4.5.2' ++ VERSION = '2.4.5.3' + end + + # Must be first since it unloads the prelude from 1.9.2 +diff --git lib/rubygems/commands/query_command.rb lib/rubygems/commands/query_command.rb +index 432250e033..44364cfab2 100644 +--- ruby-2.2.7/lib/rubygems/commands/query_command.rb ++++ ruby-2.2.7/lib/rubygems/commands/query_command.rb +@@ -218,7 +218,7 @@ is too hard to use. + end + end + +- output << make_entry(matching_tuples, platforms) ++ output << clean_text(make_entry(matching_tuples, platforms)) + end + end + +@@ -336,7 +336,8 @@ is too hard to use. + end + + def spec_summary entry, spec +- entry << "\n\n" << format_text(spec.summary, 68, 4) ++ summary = truncate_text(spec.summary, "the summary for #{spec.full_name}") ++ entry << "\n\n" << format_text(summary, 68, 4) + end + + end +diff --git lib/rubygems/installer.rb lib/rubygems/installer.rb +index 10fc1a34a5..a27569fe2e 100644 +--- ruby-2.2.7/lib/rubygems/installer.rb ++++ ruby-2.2.7/lib/rubygems/installer.rb +@@ -646,6 +646,11 @@ class Gem::Installer + unpack or File.writable?(gem_home) + end + ++ def verify_spec_name ++ return if spec.name =~ Gem::Specification::VALID_NAME_PATTERN ++ raise Gem::InstallError, "#{spec} has an invalid name" ++ end ++ + ## + # Return the text for an application file. + +@@ -771,6 +776,8 @@ TEXT + + ensure_loadable_spec + ++ verify_spec_name ++ + if options[:install_as_default] + Gem.ensure_default_gem_subdirectories gem_home + else +diff --git lib/rubygems/remote_fetcher.rb lib/rubygems/remote_fetcher.rb +index b1f6dd17fc..2b9d61c0a1 100644 +--- ruby-2.2.7/lib/rubygems/remote_fetcher.rb ++++ ruby-2.2.7/lib/rubygems/remote_fetcher.rb +@@ -96,7 +96,7 @@ class Gem::RemoteFetcher + else + target = res.target.to_s.strip + +- if /\.#{Regexp.quote(host)}\z/ =~ target ++ if URI("http://" + target).host.end_with?(".#{host}") + return URI.parse "#{uri.scheme}://#{target}#{uri.path}" + end + +diff --git lib/rubygems/specification.rb lib/rubygems/specification.rb +index ab1cd92270..faca837128 100644 +--- ruby-2.2.7/lib/rubygems/specification.rb ++++ ruby-2.2.7/lib/rubygems/specification.rb +@@ -106,6 +106,8 @@ class Gem::Specification < Gem::BasicSpecification + + private_constant :LOAD_CACHE if defined? private_constant + ++ VALID_NAME_PATTERN = /\A[a-zA-Z0-9\.\-\_]+\z/ # :nodoc: ++ + # :startdoc: + + ## +@@ -2477,9 +2479,15 @@ class Gem::Specification < Gem::BasicSpecification + end + end + +- unless String === name then ++ if !name.is_a?(String) then + raise Gem::InvalidSpecificationException, +- "invalid value for attribute name: \"#{name.inspect}\"" ++ "invalid value for attribute name: \"#{name.inspect}\" must be a string" ++ elsif name !~ /[a-zA-Z]/ then ++ raise Gem::InvalidSpecificationException, ++ "invalid value for attribute name: #{name.dump} must include at least one letter" ++ elsif name !~ VALID_NAME_PATTERN then ++ raise Gem::InvalidSpecificationException, ++ "invalid value for attribute name: #{name.dump} can only include letters, numbers, dashes, and underscores" + end + + if raw_require_paths.empty? then +diff --git lib/rubygems/text.rb lib/rubygems/text.rb +index 5c9287ad2e..86a722ffc0 100644 +--- ruby-2.2.7/lib/rubygems/text.rb ++++ ruby-2.2.7/lib/rubygems/text.rb +@@ -5,13 +5,26 @@ require 'rubygems' + + module Gem::Text + ++ ## ++ # Remove any non-printable characters and make the text suitable for ++ # printing. ++ def clean_text(text) ++ text.gsub(/[\000-\b\v-\f\016-\037\177]/, ".".freeze) ++ end ++ ++ def truncate_text(text, description, max_length = 100_000) ++ raise ArgumentError, "max_length must be positive" unless max_length > 0 ++ return text if text.size <= max_length ++ "Truncating #{description} to #{max_length.to_s.reverse.gsub(/...(?=.)/,'\&,').reverse} characters:\n" + text[0, max_length] ++ end ++ + ## + # Wraps +text+ to +wrap+ characters and optionally indents by +indent+ + # characters + + def format_text(text, wrap, indent=0) + result = [] +- work = text.dup ++ work = clean_text(text) + + while work.length > wrap do + if work =~ /^(.{0,#{wrap}})[ \n]/ then +diff --git test/rubygems/test_gem_commands_query_command.rb test/rubygems/test_gem_commands_query_command.rb +index 43fa82571d..ccd2621874 100644 +--- ruby-2.2.7/test/rubygems/test_gem_commands_query_command.rb ++++ ruby-2.2.7/test/rubygems/test_gem_commands_query_command.rb +@@ -147,6 +147,86 @@ a (2) + This is a lot of text. This is a lot of text. This is a lot of text. + This is a lot of text. + ++pl (1) ++ Platform: i386-linux ++ Author: A User ++ Homepage: http://example.com ++ ++ this is a summary ++ EOF ++ ++ assert_equal expected, @ui.output ++ assert_equal '', @ui.error ++ end ++ ++ def test_execute_details_cleans_text ++ spec_fetcher do |fetcher| ++ fetcher.spec 'a', 2 do |s| ++ s.summary = 'This is a lot of text. ' * 4 ++ s.authors = ["Abraham Lincoln \x01", "\x02 Hirohito"] ++ s.homepage = "http://a.example.com/\x03" ++ end ++ ++ fetcher.legacy_platform ++ end ++ ++ @cmd.handle_options %w[-r -d] ++ ++ use_ui @ui do ++ @cmd.execute ++ end ++ ++ expected = <<-EOF ++ ++*** REMOTE GEMS *** ++ ++a (2) ++ Authors: Abraham Lincoln ., . Hirohito ++ Homepage: http://a.example.com/. ++ ++ This is a lot of text. This is a lot of text. This is a lot of text. ++ This is a lot of text. ++ ++pl (1) ++ Platform: i386-linux ++ Author: A User ++ Homepage: http://example.com ++ ++ this is a summary ++ EOF ++ ++ assert_equal expected, @ui.output ++ assert_equal '', @ui.error ++ end ++ ++ def test_execute_details_truncates_summary ++ spec_fetcher do |fetcher| ++ fetcher.spec 'a', 2 do |s| ++ s.summary = 'This is a lot of text. ' * 10_000 ++ s.authors = ["Abraham Lincoln \x01", "\x02 Hirohito"] ++ s.homepage = "http://a.example.com/\x03" ++ end ++ ++ fetcher.legacy_platform ++ end ++ ++ @cmd.handle_options %w[-r -d] ++ ++ use_ui @ui do ++ @cmd.execute ++ end ++ ++ expected = <<-EOF ++ ++*** REMOTE GEMS *** ++ ++a (2) ++ Authors: Abraham Lincoln ., . Hirohito ++ Homepage: http://a.example.com/. ++ ++ Truncating the summary for a-2 to 100,000 characters: ++#{" This is a lot of text. This is a lot of text. This is a lot of text.\n" * 1449} This is a lot of te ++ + pl (1) + Platform: i386-linux + Author: A User +diff --git test/rubygems/test_gem_installer.rb test/rubygems/test_gem_installer.rb +index 6f8012feb8..aba73af181 100644 +--- ruby-2.2.7/test/rubygems/test_gem_installer.rb ++++ ruby-2.2.7/test/rubygems/test_gem_installer.rb +@@ -1214,6 +1214,26 @@ gem 'other', version + end + end + ++ def test_pre_install_checks_malicious_name ++ spec = util_spec '../malicious', '1' ++ def spec.full_name # so the spec is buildable ++ "malicious-1" ++ end ++ def spec.validate; end ++ ++ util_build_gem spec ++ ++ gem = File.join(@gemhome, 'cache', spec.file_name) ++ ++ use_ui @ui do ++ @installer = Gem::Installer.at gem ++ e = assert_raises Gem::InstallError do ++ @installer.pre_install_checks ++ end ++ assert_equal '#<Gem::Specification name=../malicious version=1> has an invalid name', e.message ++ end ++ end ++ + def test_shebang + util_make_exec @spec, "#!/usr/bin/ruby" + +diff --git test/rubygems/test_gem_remote_fetcher.rb test/rubygems/test_gem_remote_fetcher.rb +index 63dd8feb38..ca4627810b 100644 +--- ruby-2.2.7/test/rubygems/test_gem_remote_fetcher.rb ++++ ruby-2.2.7/test/rubygems/test_gem_remote_fetcher.rb +@@ -181,6 +181,21 @@ gems: + dns.verify + end + ++ def test_api_endpoint_ignores_trans_domain_values_that_end_with_original_in_path ++ uri = URI.parse "http://example.com/foo" ++ target = MiniTest::Mock.new ++ target.expect :target, "evil.com/a.example.com" ++ ++ dns = MiniTest::Mock.new ++ dns.expect :getresource, target, [String, Object] ++ ++ fetch = Gem::RemoteFetcher.new nil, dns ++ assert_equal URI.parse("http://example.com/foo"), fetch.api_endpoint(uri) ++ ++ target.verify ++ dns.verify ++ end ++ + def test_api_endpoint_ignores_trans_domain_values + uri = URI.parse "http://gems.example.com/foo" + target = MiniTest::Mock.new +diff --git test/rubygems/test_gem_specification.rb test/rubygems/test_gem_specification.rb +index 3cadc55d5d..4f7076a03a 100644 +--- ruby-2.2.7/test/rubygems/test_gem_specification.rb ++++ ruby-2.2.7/test/rubygems/test_gem_specification.rb +@@ -2610,7 +2610,37 @@ http://opensource.org/licenses/alphabetical + @a1.validate + end + +- assert_equal 'invalid value for attribute name: ":json"', e.message ++ assert_equal 'invalid value for attribute name: ":json" must be a string', e.message ++ ++ @a1.name = [] ++ e = assert_raises Gem::InvalidSpecificationException do ++ @a1.validate ++ end ++ assert_equal "invalid value for attribute name: \"[]\" must be a string", e.message ++ ++ @a1.name = "" ++ e = assert_raises Gem::InvalidSpecificationException do ++ @a1.validate ++ end ++ assert_equal "invalid value for attribute name: \"\" must include at least one letter", e.message ++ ++ @a1.name = "12345" ++ e = assert_raises Gem::InvalidSpecificationException do ++ @a1.validate ++ end ++ assert_equal "invalid value for attribute name: \"12345\" must include at least one letter", e.message ++ ++ @a1.name = "../malicious" ++ e = assert_raises Gem::InvalidSpecificationException do ++ @a1.validate ++ end ++ assert_equal "invalid value for attribute name: \"../malicious\" can only include letters, numbers, dashes, and underscores", e.message ++ ++ @a1.name = "\ba\t" ++ e = assert_raises Gem::InvalidSpecificationException do ++ @a1.validate ++ end ++ assert_equal "invalid value for attribute name: \"\\ba\\t\" can only include letters, numbers, dashes, and underscores", e.message + end + + def test_validate_non_nil +diff --git test/rubygems/test_gem_text.rb test/rubygems/test_gem_text.rb +index e5cfc41e61..9b270b481b 100644 +--- ruby-2.2.7/test/rubygems/test_gem_text.rb ++++ ruby-2.2.7/test/rubygems/test_gem_text.rb +@@ -35,6 +35,10 @@ Without the wrapping, the text might not look good in the RSS feed. + assert_equal expected, format_text(text, 78) + end + ++ def test_format_removes_nonprintable_characters ++ assert_equal "text with weird .. stuff .", format_text("text with weird \x1b\x02 stuff \x7f", 40) ++ end ++ + def test_min3 + assert_equal 1, min3(1, 1, 1) + assert_equal 1, min3(1, 1, 2) +@@ -71,4 +75,11 @@ Without the wrapping, the text might not look good in the RSS feed. + assert_equal 7, levenshtein_distance("xxxxxxx", "ZenTest") + assert_equal 7, levenshtein_distance("zentest", "xxxxxxx") + end ++ ++ def test_truncate_text ++ assert_equal "abc", truncate_text("abc", "desc") ++ assert_equal "Truncating desc to 2 characters:\nab", truncate_text("abc", "desc", 2) ++ s = "ab" * 500_001 ++ assert_equal "Truncating desc to 1,000,000 characters:\n#{s[0, 1_000_000]}", truncate_text(s, "desc", 1_000_000) ++ end + end diff --git a/gnu/packages/patches/ruby-2.3.4-rubygems-2613-ruby23.patch b/gnu/packages/patches/ruby-2.3.4-rubygems-2613-ruby23.patch new file mode 100644 index 0000000000..8f4758293e --- /dev/null +++ b/gnu/packages/patches/ruby-2.3.4-rubygems-2613-ruby23.patch @@ -0,0 +1,355 @@ +diff --git lib/rubygems.rb lib/rubygems.rb +index 04031c765c..9c0219ce06 100644 +--- ruby-2.3.4/lib/rubygems.rb ++++ ruby-2.3.4/lib/rubygems.rb +@@ -10,7 +10,7 @@ + require 'thread' + + module Gem +- VERSION = '2.5.2' ++ VERSION = '2.5.2.1' + end + + # Must be first since it unloads the prelude from 1.9.2 +diff --git lib/rubygems/commands/query_command.rb lib/rubygems/commands/query_command.rb +index d6196b44ed..61e9808860 100644 +--- ruby-2.3.4/lib/rubygems/commands/query_command.rb ++++ ruby-2.3.4/lib/rubygems/commands/query_command.rb +@@ -226,7 +226,7 @@ def output_versions output, versions + end + end + +- output << make_entry(matching_tuples, platforms) ++ output << clean_text(make_entry(matching_tuples, platforms)) + end + end + +@@ -344,7 +344,8 @@ def spec_platforms entry, platforms + end + + def spec_summary entry, spec +- entry << "\n\n" << format_text(spec.summary, 68, 4) ++ summary = truncate_text(spec.summary, "the summary for #{spec.full_name}") ++ entry << "\n\n" << format_text(summary, 68, 4) + end + + end +diff --git lib/rubygems/installer.rb lib/rubygems/installer.rb +index 85358e0d1a..709b77d126 100644 +--- ruby-2.3.4/lib/rubygems/installer.rb ++++ ruby-2.3.4/lib/rubygems/installer.rb +@@ -693,6 +693,11 @@ def verify_gem_home(unpack = false) # :nodoc: + unpack or File.writable?(gem_home) + end + ++ def verify_spec_name ++ return if spec.name =~ Gem::Specification::VALID_NAME_PATTERN ++ raise Gem::InstallError, "#{spec} has an invalid name" ++ end ++ + ## + # Return the text for an application file. + +@@ -812,6 +817,8 @@ def pre_install_checks + + ensure_loadable_spec + ++ verify_spec_name ++ + if options[:install_as_default] + Gem.ensure_default_gem_subdirectories gem_home + else +diff --git lib/rubygems/remote_fetcher.rb lib/rubygems/remote_fetcher.rb +index fda1e067ef..254bebfadf 100644 +--- ruby-2.3.4/lib/rubygems/remote_fetcher.rb ++++ ruby-2.3.4/lib/rubygems/remote_fetcher.rb +@@ -104,7 +104,7 @@ def api_endpoint(uri) + else + target = res.target.to_s.strip + +- if /\.#{Regexp.quote(host)}\z/ =~ target ++ if URI("http://" + target).host.end_with?(".#{host}") + return URI.parse "#{uri.scheme}://#{target}#{uri.path}" + end + +diff --git lib/rubygems/specification.rb lib/rubygems/specification.rb +index 8e2557cdb2..dd4fde1776 100644 +--- ruby-2.3.4/lib/rubygems/specification.rb ++++ ruby-2.3.4/lib/rubygems/specification.rb +@@ -108,6 +108,8 @@ class Gem::Specification < Gem::BasicSpecification + + private_constant :LOAD_CACHE if defined? private_constant + ++ VALID_NAME_PATTERN = /\A[a-zA-Z0-9\.\-\_]+\z/ # :nodoc: ++ + # :startdoc: + + ## +@@ -2665,9 +2667,15 @@ def validate packaging = true + end + end + +- unless String === name then ++ if !name.is_a?(String) then + raise Gem::InvalidSpecificationException, +- "invalid value for attribute name: \"#{name.inspect}\"" ++ "invalid value for attribute name: \"#{name.inspect}\" must be a string" ++ elsif name !~ /[a-zA-Z]/ then ++ raise Gem::InvalidSpecificationException, ++ "invalid value for attribute name: #{name.dump} must include at least one letter" ++ elsif name !~ VALID_NAME_PATTERN then ++ raise Gem::InvalidSpecificationException, ++ "invalid value for attribute name: #{name.dump} can only include letters, numbers, dashes, and underscores" + end + + if raw_require_paths.empty? then +diff --git lib/rubygems/text.rb lib/rubygems/text.rb +index 732f1b99f2..b944b62c27 100644 +--- ruby-2.3.4/lib/rubygems/text.rb ++++ ruby-2.3.4/lib/rubygems/text.rb +@@ -6,13 +6,26 @@ + + module Gem::Text + ++ ## ++ # Remove any non-printable characters and make the text suitable for ++ # printing. ++ def clean_text(text) ++ text.gsub(/[\000-\b\v-\f\016-\037\177]/, ".".freeze) ++ end ++ ++ def truncate_text(text, description, max_length = 100_000) ++ raise ArgumentError, "max_length must be positive" unless max_length > 0 ++ return text if text.size <= max_length ++ "Truncating #{description} to #{max_length.to_s.reverse.gsub(/...(?=.)/,'\&,').reverse} characters:\n" + text[0, max_length] ++ end ++ + ## + # Wraps +text+ to +wrap+ characters and optionally indents by +indent+ + # characters + + def format_text(text, wrap, indent=0) + result = [] +- work = text.dup ++ work = clean_text(text) + + while work.length > wrap do + if work =~ /^(.{0,#{wrap}})[ \n]/ then +diff --git test/rubygems/test_gem_commands_query_command.rb test/rubygems/test_gem_commands_query_command.rb +index 78c15a1770..9ec715492f 100644 +--- ruby-2.3.4/test/rubygems/test_gem_commands_query_command.rb ++++ ruby-2.3.4/test/rubygems/test_gem_commands_query_command.rb +@@ -116,6 +116,86 @@ def test_execute_details + This is a lot of text. This is a lot of text. This is a lot of text. + This is a lot of text. + ++pl (1) ++ Platform: i386-linux ++ Author: A User ++ Homepage: http://example.com ++ ++ this is a summary ++ EOF ++ ++ assert_equal expected, @ui.output ++ assert_equal '', @ui.error ++ end ++ ++ def test_execute_details_cleans_text ++ spec_fetcher do |fetcher| ++ fetcher.spec 'a', 2 do |s| ++ s.summary = 'This is a lot of text. ' * 4 ++ s.authors = ["Abraham Lincoln \x01", "\x02 Hirohito"] ++ s.homepage = "http://a.example.com/\x03" ++ end ++ ++ fetcher.legacy_platform ++ end ++ ++ @cmd.handle_options %w[-r -d] ++ ++ use_ui @ui do ++ @cmd.execute ++ end ++ ++ expected = <<-EOF ++ ++*** REMOTE GEMS *** ++ ++a (2) ++ Authors: Abraham Lincoln ., . Hirohito ++ Homepage: http://a.example.com/. ++ ++ This is a lot of text. This is a lot of text. This is a lot of text. ++ This is a lot of text. ++ ++pl (1) ++ Platform: i386-linux ++ Author: A User ++ Homepage: http://example.com ++ ++ this is a summary ++ EOF ++ ++ assert_equal expected, @ui.output ++ assert_equal '', @ui.error ++ end ++ ++ def test_execute_details_truncates_summary ++ spec_fetcher do |fetcher| ++ fetcher.spec 'a', 2 do |s| ++ s.summary = 'This is a lot of text. ' * 10_000 ++ s.authors = ["Abraham Lincoln \x01", "\x02 Hirohito"] ++ s.homepage = "http://a.example.com/\x03" ++ end ++ ++ fetcher.legacy_platform ++ end ++ ++ @cmd.handle_options %w[-r -d] ++ ++ use_ui @ui do ++ @cmd.execute ++ end ++ ++ expected = <<-EOF ++ ++*** REMOTE GEMS *** ++ ++a (2) ++ Authors: Abraham Lincoln ., . Hirohito ++ Homepage: http://a.example.com/. ++ ++ Truncating the summary for a-2 to 100,000 characters: ++#{" This is a lot of text. This is a lot of text. This is a lot of text.\n" * 1449} This is a lot of te ++ + pl (1) + Platform: i386-linux + Author: A User +diff --git test/rubygems/test_gem_installer.rb test/rubygems/test_gem_installer.rb +index 5ec71d0a01..1092a0c68f 100644 +--- ruby-2.3.4/test/rubygems/test_gem_installer.rb ++++ ruby-2.3.4/test/rubygems/test_gem_installer.rb +@@ -1227,6 +1227,26 @@ def test_pre_install_checks_wrong_rubygems_version + end + end + ++ def test_pre_install_checks_malicious_name ++ spec = util_spec '../malicious', '1' ++ def spec.full_name # so the spec is buildable ++ "malicious-1" ++ end ++ def spec.validate; end ++ ++ util_build_gem spec ++ ++ gem = File.join(@gemhome, 'cache', spec.file_name) ++ ++ use_ui @ui do ++ @installer = Gem::Installer.at gem ++ e = assert_raises Gem::InstallError do ++ @installer.pre_install_checks ++ end ++ assert_equal '#<Gem::Specification name=../malicious version=1> has an invalid name', e.message ++ end ++ end ++ + def test_shebang + util_make_exec @spec, "#!/usr/bin/ruby" + +diff --git test/rubygems/test_gem_remote_fetcher.rb test/rubygems/test_gem_remote_fetcher.rb +index 49b6b6656c..a3919c8ef2 100644 +--- ruby-2.3.4/test/rubygems/test_gem_remote_fetcher.rb ++++ ruby-2.3.4/test/rubygems/test_gem_remote_fetcher.rb +@@ -253,6 +253,21 @@ def test_api_endpoint_ignores_trans_domain_values_that_end_with_original + dns.verify + end + ++ def test_api_endpoint_ignores_trans_domain_values_that_end_with_original_in_path ++ uri = URI.parse "http://example.com/foo" ++ target = MiniTest::Mock.new ++ target.expect :target, "evil.com/a.example.com" ++ ++ dns = MiniTest::Mock.new ++ dns.expect :getresource, target, [String, Object] ++ ++ fetch = Gem::RemoteFetcher.new nil, dns ++ assert_equal URI.parse("http://example.com/foo"), fetch.api_endpoint(uri) ++ ++ target.verify ++ dns.verify ++ end ++ + def test_api_endpoint_timeout_warning + uri = URI.parse "http://gems.example.com/foo" + +diff --git test/rubygems/test_gem_specification.rb test/rubygems/test_gem_specification.rb +index bc1c8d2ca7..9a49bbbf59 100644 +--- ruby-2.3.4/test/rubygems/test_gem_specification.rb ++++ ruby-2.3.4/test/rubygems/test_gem_specification.rb +@@ -2974,7 +2974,37 @@ def test_validate_name + @a1.validate + end + +- assert_equal 'invalid value for attribute name: ":json"', e.message ++ assert_equal 'invalid value for attribute name: ":json" must be a string', e.message ++ ++ @a1.name = [] ++ e = assert_raises Gem::InvalidSpecificationException do ++ @a1.validate ++ end ++ assert_equal "invalid value for attribute name: \"[]\" must be a string", e.message ++ ++ @a1.name = "" ++ e = assert_raises Gem::InvalidSpecificationException do ++ @a1.validate ++ end ++ assert_equal "invalid value for attribute name: \"\" must include at least one letter", e.message ++ ++ @a1.name = "12345" ++ e = assert_raises Gem::InvalidSpecificationException do ++ @a1.validate ++ end ++ assert_equal "invalid value for attribute name: \"12345\" must include at least one letter", e.message ++ ++ @a1.name = "../malicious" ++ e = assert_raises Gem::InvalidSpecificationException do ++ @a1.validate ++ end ++ assert_equal "invalid value for attribute name: \"../malicious\" can only include letters, numbers, dashes, and underscores", e.message ++ ++ @a1.name = "\ba\t" ++ e = assert_raises Gem::InvalidSpecificationException do ++ @a1.validate ++ end ++ assert_equal "invalid value for attribute name: \"\\ba\\t\" can only include letters, numbers, dashes, and underscores", e.message + end + + def test_validate_non_nil +diff --git test/rubygems/test_gem_text.rb test/rubygems/test_gem_text.rb +index a6e22e04da..04f3f605e8 100644 +--- ruby-2.3.4/test/rubygems/test_gem_text.rb ++++ ruby-2.3.4/test/rubygems/test_gem_text.rb +@@ -36,6 +36,10 @@ def test_format_text_trailing # for two spaces after . + assert_equal expected, format_text(text, 78) + end + ++ def test_format_removes_nonprintable_characters ++ assert_equal "text with weird .. stuff .", format_text("text with weird \x1b\x02 stuff \x7f", 40) ++ end ++ + def test_min3 + assert_equal 1, min3(1, 1, 1) + assert_equal 1, min3(1, 1, 2) +@@ -74,4 +78,11 @@ def test_levenshtein_distance_replace + assert_equal 7, levenshtein_distance("xxxxxxx", "ZenTest") + assert_equal 7, levenshtein_distance("zentest", "xxxxxxx") + end ++ ++ def test_truncate_text ++ assert_equal "abc", truncate_text("abc", "desc") ++ assert_equal "Truncating desc to 2 characters:\nab", truncate_text("abc", "desc", 2) ++ s = "ab" * 500_001 ++ assert_equal "Truncating desc to 1,000,000 characters:\n#{s[0, 1_000_000]}", truncate_text(s, "desc", 1_000_000) ++ end + end diff --git a/gnu/packages/patches/ruby-rubygems-2612-ruby24.patch b/gnu/packages/patches/ruby-rubygems-2612-ruby24.patch new file mode 100644 index 0000000000..8ee32c0c6e --- /dev/null +++ b/gnu/packages/patches/ruby-rubygems-2612-ruby24.patch @@ -0,0 +1,437 @@ +diff --git lib/rubygems.rb lib/rubygems.rb +index 5cd1a4c47a..bc5bf9b4c2 100644 +--- ruby-2.4.1/lib/rubygems.rb ++++ ruby-2.4.1/lib/rubygems.rb +@@ -10,7 +10,7 @@ + require 'thread' + + module Gem +- VERSION = "2.6.11" ++ VERSION = "2.6.12" + end + + # Must be first since it unloads the prelude from 1.9.2 +@@ -234,6 +234,7 @@ def self.needs + + def self.finish_resolve(request_set=Gem::RequestSet.new) + request_set.import Gem::Specification.unresolved_deps.values ++ request_set.import Gem.loaded_specs.values.map {|s| Gem::Dependency.new(s.name, s.version) } + + request_set.resolve_current.each do |s| + s.full_spec.activate +diff --git lib/rubygems/commands/open_command.rb lib/rubygems/commands/open_command.rb +index a89b7421e3..059635e835 100644 +--- ruby-2.4.1/lib/rubygems/commands/open_command.rb ++++ ruby-2.4.1/lib/rubygems/commands/open_command.rb +@@ -72,7 +72,7 @@ def open_editor path + end + + def spec_for name +- spec = Gem::Specification.find_all_by_name(name, @version).last ++ spec = Gem::Specification.find_all_by_name(name, @version).first + + return spec if spec + +diff --git lib/rubygems/commands/query_command.rb lib/rubygems/commands/query_command.rb +index f25d120b88..70f8127292 100644 +--- ruby-2.4.1/lib/rubygems/commands/query_command.rb ++++ ruby-2.4.1/lib/rubygems/commands/query_command.rb +@@ -86,7 +86,7 @@ def execute + name = Array(options[:name]) + else + args = options[:args].to_a +- name = options[:exact] ? args : args.map{|arg| /#{arg}/i } ++ name = options[:exact] ? args.map{|arg| /\A#{Regexp.escape(arg)}\Z/ } : args.map{|arg| /#{arg}/i } + end + + prerelease = options[:prerelease] +diff --git lib/rubygems/commands/sources_command.rb lib/rubygems/commands/sources_command.rb +index 9832afd214..7e46963a4c 100644 +--- ruby-2.4.1/lib/rubygems/commands/sources_command.rb ++++ ruby-2.4.1/lib/rubygems/commands/sources_command.rb +@@ -44,7 +44,7 @@ def add_source source_uri # :nodoc: + source = Gem::Source.new source_uri + + begin +- if Gem.sources.include? source_uri then ++ if Gem.sources.include? source then + say "source #{source_uri} already present in the cache" + else + source.load_specs :released +diff --git lib/rubygems/dependency_list.rb lib/rubygems/dependency_list.rb +index 35fe7c4c1a..d8314eaf60 100644 +--- ruby-2.4.1/lib/rubygems/dependency_list.rb ++++ ruby-2.4.1/lib/rubygems/dependency_list.rb +@@ -104,7 +104,7 @@ def find_name(full_name) + end + + def inspect # :nodoc: +- "#<%s:0x%x %p>" % [self.class, object_id, map { |s| s.full_name }] ++ "%s %p>" % [super[0..-2], map { |s| s.full_name }] + end + + ## +diff --git lib/rubygems/installer.rb lib/rubygems/installer.rb +index f4d3e728de..967543c2d1 100644 +--- ruby-2.4.1/lib/rubygems/installer.rb ++++ ruby-2.4.1/lib/rubygems/installer.rb +@@ -214,7 +214,7 @@ def check_executable_overwrite filename # :nodoc: + + ruby_executable = true + existing = io.read.slice(%r{ +- ^( ++ ^\s*( + gem \s | + load \s Gem\.bin_path\( | + load \s Gem\.activate_bin_path\( +@@ -701,6 +701,8 @@ def verify_gem_home(unpack = false) # :nodoc: + # Return the text for an application file. + + def app_script_text(bin_file_name) ++ # note that the `load` lines cannot be indented, as old RG versions match ++ # against the beginning of the line + return <<-TEXT + #{shebang bin_file_name} + # +@@ -723,7 +725,12 @@ def app_script_text(bin_file_name) + end + end + ++if Gem.respond_to?(:activate_bin_path) + load Gem.activate_bin_path('#{spec.name}', '#{bin_file_name}', version) ++else ++gem #{spec.name.dump}, version ++load Gem.bin_path(#{spec.name.dump}, #{bin_file_name.dump}, version) ++end + TEXT + end + +diff --git lib/rubygems/platform.rb lib/rubygems/platform.rb +index d22d91ae54..2dd9ed5782 100644 +--- ruby-2.4.1/lib/rubygems/platform.rb ++++ ruby-2.4.1/lib/rubygems/platform.rb +@@ -112,7 +112,7 @@ def initialize(arch) + end + + def inspect +- "#<%s:0x%x @cpu=%p, @os=%p, @version=%p>" % [self.class, object_id, *to_a] ++ "%s @cpu=%p, @os=%p, @version=%p>" % [super[0..-2], *to_a] + end + + def to_a +diff --git lib/rubygems/security.rb lib/rubygems/security.rb +index 119d6d56f7..6963ca156f 100644 +--- ruby-2.4.1/lib/rubygems/security.rb ++++ ruby-2.4.1/lib/rubygems/security.rb +@@ -455,7 +455,7 @@ def self.create_cert_self_signed subject, key, age = ONE_YEAR, + + ## + # Creates a new key pair of the specified +length+ and +algorithm+. The +- # default is a 2048 bit RSA key. ++ # default is a 3072 bit RSA key. + + def self.create_key length = KEY_LENGTH, algorithm = KEY_ALGORITHM + algorithm.new length +diff --git lib/rubygems/server.rb lib/rubygems/server.rb +index 81df0e608e..df4eb566d3 100644 +--- ruby-2.4.1/lib/rubygems/server.rb ++++ ruby-2.4.1/lib/rubygems/server.rb +@@ -657,7 +657,7 @@ def root(req, res) + "only_one_executable" => true, + "full_name" => "rubygems-#{Gem::VERSION}", + "has_deps" => false, +- "homepage" => "http://docs.rubygems.org/", ++ "homepage" => "http://guides.rubygems.org/", + "name" => 'rubygems', + "ri_installed" => true, + "summary" => "RubyGems itself", +diff --git lib/rubygems/specification.rb lib/rubygems/specification.rb +index a2f289d162..500f0af768 100644 +--- ruby-2.4.1/lib/rubygems/specification.rb ++++ ruby-2.4.1/lib/rubygems/specification.rb +@@ -2105,7 +2105,7 @@ def inspect # :nodoc: + if $DEBUG + super + else +- "#<#{self.class}:0x#{__id__.to_s(16)} #{full_name}>" ++ "#{super[0..-2]} #{full_name}>" + end + end + +diff --git lib/rubygems/test_case.rb lib/rubygems/test_case.rb +index 86b68e1efb..4e48f1eb4c 100644 +--- ruby-2.4.1/lib/rubygems/test_case.rb ++++ ruby-2.4.1/lib/rubygems/test_case.rb +@@ -484,7 +484,7 @@ def git_gem name = 'a', version = 1 + + system @git, 'add', gemspec + system @git, 'commit', '-a', '-m', 'a non-empty commit message', '--quiet' +- head = Gem::Util.popen('git', 'rev-parse', 'master').strip ++ head = Gem::Util.popen(@git, 'rev-parse', 'master').strip + end + + return name, git_spec.version, directory, head +@@ -1498,6 +1498,8 @@ def self.key_path key_name + begin + gem 'rdoc' + require 'rdoc' ++ ++ require 'rubygems/rdoc' + rescue LoadError, Gem::LoadError + end + +@@ -1514,3 +1516,4 @@ def self.key_path key_name + pid = $$ + END {tmpdirs.each {|dir| Dir.rmdir(dir)} if $$ == pid} + Gem.clear_paths ++Gem.loaded_specs.clear +diff --git test/rubygems/test_gem.rb test/rubygems/test_gem.rb +index a605f9cdfe..62b36dfd41 100644 +--- ruby-2.4.1/test/rubygems/test_gem.rb ++++ ruby-2.4.1/test/rubygems/test_gem.rb +@@ -75,6 +75,29 @@ def test_self_finish_resolve_wtf + end + end + ++ def test_self_finish_resolve_respects_loaded_specs ++ save_loaded_features do ++ a1 = new_spec "a", "1", "b" => "> 0" ++ b1 = new_spec "b", "1", "c" => ">= 1" ++ b2 = new_spec "b", "2", "c" => ">= 2" ++ c1 = new_spec "c", "1" ++ c2 = new_spec "c", "2" ++ ++ install_specs c1, c2, b1, b2, a1 ++ ++ a1.activate ++ c1.activate ++ ++ assert_equal %w(a-1 c-1), loaded_spec_names ++ assert_equal ["b (> 0)"], unresolved_names ++ ++ Gem.finish_resolve ++ ++ assert_equal %w(a-1 b-1 c-1), loaded_spec_names ++ assert_equal [], unresolved_names ++ end ++ end ++ + def test_self_install + spec_fetcher do |f| + f.gem 'a', 1 +@@ -492,7 +515,7 @@ def test_self_find_files_with_gemfile + skip if RUBY_VERSION <= "1.8.7" + + cwd = File.expand_path("test/rubygems", @@project_dir) +- $LOAD_PATH.unshift cwd ++ actual_load_path = $LOAD_PATH.unshift(cwd).dup + + discover_path = File.join 'lib', 'sff', 'discover.rb' + +@@ -518,12 +541,12 @@ def test_self_find_files_with_gemfile + expected = [ + File.expand_path('test/rubygems/sff/discover.rb', @@project_dir), + File.join(foo1.full_gem_path, discover_path) +- ] ++ ].sort + +- assert_equal expected, Gem.find_files('sff/discover') +- assert_equal expected, Gem.find_files('sff/**.rb'), '[ruby-core:31730]' ++ assert_equal expected, Gem.find_files('sff/discover').sort ++ assert_equal expected, Gem.find_files('sff/**.rb').sort, '[ruby-core:31730]' + ensure +- assert_equal cwd, $LOAD_PATH.shift unless RUBY_VERSION <= "1.8.7" ++ assert_equal cwd, actual_load_path.shift unless RUBY_VERSION <= "1.8.7" + end + + def test_self_find_latest_files +diff --git test/rubygems/test_gem_commands_open_command.rb test/rubygems/test_gem_commands_open_command.rb +index 3ec38972e6..a96fa6ea23 100644 +--- ruby-2.4.1/test/rubygems/test_gem_commands_open_command.rb ++++ ruby-2.4.1/test/rubygems/test_gem_commands_open_command.rb +@@ -24,7 +24,8 @@ def test_execute + @cmd.options[:args] = %w[foo] + @cmd.options[:editor] = "#{Gem.ruby} -e0 --" + +- spec = gem 'foo' ++ gem 'foo', '1.0.0' ++ spec = gem 'foo', '1.0.1' + mock = MiniTest::Mock.new + mock.expect(:call, true, [spec.full_gem_path]) + +diff --git test/rubygems/test_gem_commands_query_command.rb test/rubygems/test_gem_commands_query_command.rb +index 223f205b2d..d8d682b136 100644 +--- ruby-2.4.1/test/rubygems/test_gem_commands_query_command.rb ++++ ruby-2.4.1/test/rubygems/test_gem_commands_query_command.rb +@@ -642,7 +642,7 @@ def test_execute_local_details + assert_equal expected, @ui.output + end + +- def test_execute_exact ++ def test_execute_exact_remote + spec_fetcher do |fetcher| + fetcher.spec 'coolgem-omg', 3 + fetcher.spec 'coolgem', '4.2.1' +@@ -665,6 +665,60 @@ def test_execute_exact + assert_equal expected, @ui.output + end + ++ def test_execute_exact_local ++ spec_fetcher do |fetcher| ++ fetcher.spec 'coolgem-omg', 3 ++ fetcher.spec 'coolgem', '4.2.1' ++ fetcher.spec 'wow_coolgem', 1 ++ end ++ ++ @cmd.handle_options %w[--exact coolgem] ++ ++ use_ui @ui do ++ @cmd.execute ++ end ++ ++ expected = <<-EOF ++ ++*** LOCAL GEMS *** ++ ++coolgem (4.2.1) ++ EOF ++ ++ assert_equal expected, @ui.output ++ end ++ ++ def test_execute_exact_multiple ++ spec_fetcher do |fetcher| ++ fetcher.spec 'coolgem-omg', 3 ++ fetcher.spec 'coolgem', '4.2.1' ++ fetcher.spec 'wow_coolgem', 1 ++ ++ fetcher.spec 'othergem-omg', 3 ++ fetcher.spec 'othergem', '1.2.3' ++ fetcher.spec 'wow_othergem', 1 ++ end ++ ++ @cmd.handle_options %w[--exact coolgem othergem] ++ ++ use_ui @ui do ++ @cmd.execute ++ end ++ ++ expected = <<-EOF ++ ++*** LOCAL GEMS *** ++ ++coolgem (4.2.1) ++ ++*** LOCAL GEMS *** ++ ++othergem (1.2.3) ++ EOF ++ ++ assert_equal expected, @ui.output ++ end ++ + private + + def add_gems_to_fetcher +diff --git test/rubygems/test_gem_commands_sources_command.rb test/rubygems/test_gem_commands_sources_command.rb +index 014b4b4c12..d5b6d99419 100644 +--- ruby-2.4.1/test/rubygems/test_gem_commands_sources_command.rb ++++ ruby-2.4.1/test/rubygems/test_gem_commands_sources_command.rb +@@ -108,6 +108,58 @@ def test_execute_add_redundant_source + assert_equal '', @ui.error + end + ++ def test_execute_add_redundant_source_trailing_slash ++ # Remove pre-existing gem source (w/ slash) ++ repo_with_slash = "http://gems.example.com/" ++ @cmd.handle_options %W[--remove #{repo_with_slash}] ++ use_ui @ui do ++ @cmd.execute ++ end ++ source = Gem::Source.new repo_with_slash ++ assert_equal false, Gem.sources.include?(source) ++ ++ expected = <<-EOF ++#{repo_with_slash} removed from sources ++ EOF ++ ++ assert_equal expected, @ui.output ++ assert_equal '', @ui.error ++ ++ # Re-add pre-existing gem source (w/o slash) ++ repo_without_slash = "http://gems.example.com" ++ @cmd.handle_options %W[--add #{repo_without_slash}] ++ use_ui @ui do ++ @cmd.execute ++ end ++ source = Gem::Source.new repo_without_slash ++ assert_equal true, Gem.sources.include?(source) ++ ++ expected = <<-EOF ++http://gems.example.com/ removed from sources ++http://gems.example.com added to sources ++ EOF ++ ++ assert_equal expected, @ui.output ++ assert_equal '', @ui.error ++ ++ # Re-add original gem source (w/ slash) ++ @cmd.handle_options %W[--add #{repo_with_slash}] ++ use_ui @ui do ++ @cmd.execute ++ end ++ source = Gem::Source.new repo_with_slash ++ assert_equal true, Gem.sources.include?(source) ++ ++ expected = <<-EOF ++http://gems.example.com/ removed from sources ++http://gems.example.com added to sources ++source http://gems.example.com/ already present in the cache ++ EOF ++ ++ assert_equal expected, @ui.output ++ assert_equal '', @ui.error ++ end ++ + def test_execute_add_http_rubygems_org + http_rubygems_org = 'http://rubygems.org' + +diff --git test/rubygems/test_gem_installer.rb test/rubygems/test_gem_installer.rb +index 6ceb2c6dfc..882981d344 100644 +--- ruby-2.4.1/test/rubygems/test_gem_installer.rb ++++ ruby-2.4.1/test/rubygems/test_gem_installer.rb +@@ -62,7 +62,12 @@ def test_app_script_text + end + end + ++if Gem.respond_to?(:activate_bin_path) + load Gem.activate_bin_path('a', 'executable', version) ++else ++gem "a", version ++load Gem.bin_path("a", "executable", version) ++end + EOF + + wrapper = @installer.app_script_text 'executable' +diff --git test/rubygems/test_require.rb test/rubygems/test_require.rb +index dd606e44d4..936f78fb2a 100644 +--- ruby-2.4.1/test/rubygems/test_require.rb ++++ ruby-2.4.1/test/rubygems/test_require.rb +@@ -301,6 +301,17 @@ def test_default_gem_only + assert_equal %w(default-2.0.0.0), loaded_spec_names + end + ++ def test_realworld_default_gem ++ skip "no default gems on ruby < 2.0" unless RUBY_VERSION >= "2" ++ cmd = <<-RUBY ++ $stderr = $stdout ++ require "json" ++ puts Gem.loaded_specs["json"].default_gem? ++ RUBY ++ output = Gem::Util.popen(Gem.ruby, "-e", cmd).strip ++ assert_equal "true", output ++ end ++ + def test_default_gem_and_normal_gem + default_gem_spec = new_default_spec("default", "2.0.0.0", + nil, "default/gem.rb") diff --git a/gnu/packages/patches/ruby-rubygems-2613-ruby24.patch b/gnu/packages/patches/ruby-rubygems-2613-ruby24.patch new file mode 100644 index 0000000000..c253cc912d --- /dev/null +++ b/gnu/packages/patches/ruby-rubygems-2613-ruby24.patch @@ -0,0 +1,355 @@ +diff --git lib/rubygems.rb lib/rubygems.rb +index bc5bf9b4c2..55aa85b8b2 100644 +--- ruby-2.4.1/lib/rubygems.rb ++++ ruby-2.4.1/lib/rubygems.rb +@@ -10,7 +10,7 @@ + require 'thread' + + module Gem +- VERSION = "2.6.12" ++ VERSION = "2.6.13" + end + + # Must be first since it unloads the prelude from 1.9.2 +diff --git lib/rubygems/commands/query_command.rb lib/rubygems/commands/query_command.rb +index 70f8127292..44144203e0 100644 +--- ruby-2.4.1/lib/rubygems/commands/query_command.rb ++++ ruby-2.4.1/lib/rubygems/commands/query_command.rb +@@ -226,7 +226,7 @@ def output_versions output, versions + end + end + +- output << make_entry(matching_tuples, platforms) ++ output << clean_text(make_entry(matching_tuples, platforms)) + end + end + +@@ -353,7 +353,8 @@ def spec_platforms entry, platforms + end + + def spec_summary entry, spec +- entry << "\n\n" << format_text(spec.summary, 68, 4) ++ summary = truncate_text(spec.summary, "the summary for #{spec.full_name}") ++ entry << "\n\n" << format_text(summary, 68, 4) + end + + end +diff --git lib/rubygems/installer.rb lib/rubygems/installer.rb +index 967543c2d1..6fd3399dd4 100644 +--- ruby-2.4.1/lib/rubygems/installer.rb ++++ ruby-2.4.1/lib/rubygems/installer.rb +@@ -697,6 +697,11 @@ def verify_gem_home(unpack = false) # :nodoc: + unpack or File.writable?(gem_home) + end + ++ def verify_spec_name ++ return if spec.name =~ Gem::Specification::VALID_NAME_PATTERN ++ raise Gem::InstallError, "#{spec} has an invalid name" ++ end ++ + ## + # Return the text for an application file. + +@@ -823,6 +828,8 @@ def pre_install_checks + + ensure_loadable_spec + ++ verify_spec_name ++ + if options[:install_as_default] + Gem.ensure_default_gem_subdirectories gem_home + else +diff --git lib/rubygems/remote_fetcher.rb lib/rubygems/remote_fetcher.rb +index e6a13d4b8c..8f0cf0b402 100644 +--- ruby-2.4.1/lib/rubygems/remote_fetcher.rb ++++ ruby-2.4.1/lib/rubygems/remote_fetcher.rb +@@ -110,7 +110,7 @@ def api_endpoint(uri) + else + target = res.target.to_s.strip + +- if /\.#{Regexp.quote(host)}\z/ =~ target ++ if URI("http://" + target).host.end_with?(".#{host}") + return URI.parse "#{uri.scheme}://#{target}#{uri.path}" + end + +diff --git lib/rubygems/specification.rb lib/rubygems/specification.rb +index 500f0af768..88e320c05a 100644 +--- ruby-2.4.1/lib/rubygems/specification.rb ++++ ruby-2.4.1/lib/rubygems/specification.rb +@@ -108,6 +108,8 @@ class Gem::Specification < Gem::BasicSpecification + + private_constant :LOAD_CACHE if defined? private_constant + ++ VALID_NAME_PATTERN = /\A[a-zA-Z0-9\.\-\_]+\z/ # :nodoc: ++ + # :startdoc: + + ## +@@ -2671,9 +2673,15 @@ def validate packaging = true + end + end + +- unless String === name then ++ if !name.is_a?(String) then + raise Gem::InvalidSpecificationException, +- "invalid value for attribute name: \"#{name.inspect}\"" ++ "invalid value for attribute name: \"#{name.inspect}\" must be a string" ++ elsif name !~ /[a-zA-Z]/ then ++ raise Gem::InvalidSpecificationException, ++ "invalid value for attribute name: #{name.dump} must include at least one letter" ++ elsif name !~ VALID_NAME_PATTERN then ++ raise Gem::InvalidSpecificationException, ++ "invalid value for attribute name: #{name.dump} can only include letters, numbers, dashes, and underscores" + end + + if raw_require_paths.empty? then +diff --git lib/rubygems/text.rb lib/rubygems/text.rb +index 732f1b99f2..b944b62c27 100644 +--- ruby-2.4.1/lib/rubygems/text.rb ++++ ruby-2.4.1/lib/rubygems/text.rb +@@ -6,13 +6,26 @@ + + module Gem::Text + ++ ## ++ # Remove any non-printable characters and make the text suitable for ++ # printing. ++ def clean_text(text) ++ text.gsub(/[\000-\b\v-\f\016-\037\177]/, ".".freeze) ++ end ++ ++ def truncate_text(text, description, max_length = 100_000) ++ raise ArgumentError, "max_length must be positive" unless max_length > 0 ++ return text if text.size <= max_length ++ "Truncating #{description} to #{max_length.to_s.reverse.gsub(/...(?=.)/,'\&,').reverse} characters:\n" + text[0, max_length] ++ end ++ + ## + # Wraps +text+ to +wrap+ characters and optionally indents by +indent+ + # characters + + def format_text(text, wrap, indent=0) + result = [] +- work = text.dup ++ work = clean_text(text) + + while work.length > wrap do + if work =~ /^(.{0,#{wrap}})[ \n]/ then +diff --git test/rubygems/test_gem_commands_query_command.rb test/rubygems/test_gem_commands_query_command.rb +index d8d682b136..469223c6c0 100644 +--- ruby-2.4.1/test/rubygems/test_gem_commands_query_command.rb ++++ ruby-2.4.1/test/rubygems/test_gem_commands_query_command.rb +@@ -116,6 +116,86 @@ def test_execute_details + This is a lot of text. This is a lot of text. This is a lot of text. + This is a lot of text. + ++pl (1) ++ Platform: i386-linux ++ Author: A User ++ Homepage: http://example.com ++ ++ this is a summary ++ EOF ++ ++ assert_equal expected, @ui.output ++ assert_equal '', @ui.error ++ end ++ ++ def test_execute_details_cleans_text ++ spec_fetcher do |fetcher| ++ fetcher.spec 'a', 2 do |s| ++ s.summary = 'This is a lot of text. ' * 4 ++ s.authors = ["Abraham Lincoln \x01", "\x02 Hirohito"] ++ s.homepage = "http://a.example.com/\x03" ++ end ++ ++ fetcher.legacy_platform ++ end ++ ++ @cmd.handle_options %w[-r -d] ++ ++ use_ui @ui do ++ @cmd.execute ++ end ++ ++ expected = <<-EOF ++ ++*** REMOTE GEMS *** ++ ++a (2) ++ Authors: Abraham Lincoln ., . Hirohito ++ Homepage: http://a.example.com/. ++ ++ This is a lot of text. This is a lot of text. This is a lot of text. ++ This is a lot of text. ++ ++pl (1) ++ Platform: i386-linux ++ Author: A User ++ Homepage: http://example.com ++ ++ this is a summary ++ EOF ++ ++ assert_equal expected, @ui.output ++ assert_equal '', @ui.error ++ end ++ ++ def test_execute_details_truncates_summary ++ spec_fetcher do |fetcher| ++ fetcher.spec 'a', 2 do |s| ++ s.summary = 'This is a lot of text. ' * 10_000 ++ s.authors = ["Abraham Lincoln \x01", "\x02 Hirohito"] ++ s.homepage = "http://a.example.com/\x03" ++ end ++ ++ fetcher.legacy_platform ++ end ++ ++ @cmd.handle_options %w[-r -d] ++ ++ use_ui @ui do ++ @cmd.execute ++ end ++ ++ expected = <<-EOF ++ ++*** REMOTE GEMS *** ++ ++a (2) ++ Authors: Abraham Lincoln ., . Hirohito ++ Homepage: http://a.example.com/. ++ ++ Truncating the summary for a-2 to 100,000 characters: ++#{" This is a lot of text. This is a lot of text. This is a lot of text.\n" * 1449} This is a lot of te ++ + pl (1) + Platform: i386-linux + Author: A User +diff --git test/rubygems/test_gem_installer.rb test/rubygems/test_gem_installer.rb +index 882981d344..dd049214fb 100644 +--- ruby-2.4.1/test/rubygems/test_gem_installer.rb ++++ ruby-2.4.1/test/rubygems/test_gem_installer.rb +@@ -1448,6 +1448,26 @@ def test_pre_install_checks_wrong_rubygems_version + end + end + ++ def test_pre_install_checks_malicious_name ++ spec = util_spec '../malicious', '1' ++ def spec.full_name # so the spec is buildable ++ "malicious-1" ++ end ++ def spec.validate; end ++ ++ util_build_gem spec ++ ++ gem = File.join(@gemhome, 'cache', spec.file_name) ++ ++ use_ui @ui do ++ @installer = Gem::Installer.at gem ++ e = assert_raises Gem::InstallError do ++ @installer.pre_install_checks ++ end ++ assert_equal '#<Gem::Specification name=../malicious version=1> has an invalid name', e.message ++ end ++ end ++ + def test_shebang + util_make_exec @spec, "#!/usr/bin/ruby" + +diff --git test/rubygems/test_gem_remote_fetcher.rb test/rubygems/test_gem_remote_fetcher.rb +index cb994462cd..fbb7d89019 100644 +--- ruby-2.4.1/test/rubygems/test_gem_remote_fetcher.rb ++++ ruby-2.4.1/test/rubygems/test_gem_remote_fetcher.rb +@@ -241,6 +241,21 @@ def test_api_endpoint_ignores_trans_domain_values_that_end_with_original + dns.verify + end + ++ def test_api_endpoint_ignores_trans_domain_values_that_end_with_original_in_path ++ uri = URI.parse "http://example.com/foo" ++ target = MiniTest::Mock.new ++ target.expect :target, "evil.com/a.example.com" ++ ++ dns = MiniTest::Mock.new ++ dns.expect :getresource, target, [String, Object] ++ ++ fetch = Gem::RemoteFetcher.new nil, dns ++ assert_equal URI.parse("http://example.com/foo"), fetch.api_endpoint(uri) ++ ++ target.verify ++ dns.verify ++ end ++ + def test_api_endpoint_timeout_warning + uri = URI.parse "http://gems.example.com/foo" + +diff --git test/rubygems/test_gem_specification.rb test/rubygems/test_gem_specification.rb +index d43289d745..0fcc11e78f 100644 +--- ruby-2.4.1/test/rubygems/test_gem_specification.rb ++++ ruby-2.4.1/test/rubygems/test_gem_specification.rb +@@ -2985,7 +2985,37 @@ def test_validate_name + @a1.validate + end + +- assert_equal 'invalid value for attribute name: ":json"', e.message ++ assert_equal 'invalid value for attribute name: ":json" must be a string', e.message ++ ++ @a1.name = [] ++ e = assert_raises Gem::InvalidSpecificationException do ++ @a1.validate ++ end ++ assert_equal "invalid value for attribute name: \"[]\" must be a string", e.message ++ ++ @a1.name = "" ++ e = assert_raises Gem::InvalidSpecificationException do ++ @a1.validate ++ end ++ assert_equal "invalid value for attribute name: \"\" must include at least one letter", e.message ++ ++ @a1.name = "12345" ++ e = assert_raises Gem::InvalidSpecificationException do ++ @a1.validate ++ end ++ assert_equal "invalid value for attribute name: \"12345\" must include at least one letter", e.message ++ ++ @a1.name = "../malicious" ++ e = assert_raises Gem::InvalidSpecificationException do ++ @a1.validate ++ end ++ assert_equal "invalid value for attribute name: \"../malicious\" can only include letters, numbers, dashes, and underscores", e.message ++ ++ @a1.name = "\ba\t" ++ e = assert_raises Gem::InvalidSpecificationException do ++ @a1.validate ++ end ++ assert_equal "invalid value for attribute name: \"\\ba\\t\" can only include letters, numbers, dashes, and underscores", e.message + end + + def test_validate_non_nil +diff --git test/rubygems/test_gem_text.rb test/rubygems/test_gem_text.rb +index a6e22e04da..04f3f605e8 100644 +--- ruby-2.4.1/test/rubygems/test_gem_text.rb ++++ ruby-2.4.1/test/rubygems/test_gem_text.rb +@@ -36,6 +36,10 @@ def test_format_text_trailing # for two spaces after . + assert_equal expected, format_text(text, 78) + end + ++ def test_format_removes_nonprintable_characters ++ assert_equal "text with weird .. stuff .", format_text("text with weird \x1b\x02 stuff \x7f", 40) ++ end ++ + def test_min3 + assert_equal 1, min3(1, 1, 1) + assert_equal 1, min3(1, 1, 2) +@@ -74,4 +78,11 @@ def test_levenshtein_distance_replace + assert_equal 7, levenshtein_distance("xxxxxxx", "ZenTest") + assert_equal 7, levenshtein_distance("zentest", "xxxxxxx") + end ++ ++ def test_truncate_text ++ assert_equal "abc", truncate_text("abc", "desc") ++ assert_equal "Truncating desc to 2 characters:\nab", truncate_text("abc", "desc", 2) ++ s = "ab" * 500_001 ++ assert_equal "Truncating desc to 1,000,000 characters:\n#{s[0, 1_000_000]}", truncate_text(s, "desc", 1_000_000) ++ end + end diff --git a/gnu/packages/patches/wmfire-update-for-new-gdk-versions.patch b/gnu/packages/patches/wmfire-update-for-new-gdk-versions.patch index 51d6c3e791..fd12ba4ce1 100644 --- a/gnu/packages/patches/wmfire-update-for-new-gdk-versions.patch +++ b/gnu/packages/patches/wmfire-update-for-new-gdk-versions.patch @@ -1,4 +1,4 @@ -This patch comes from Debian and was modified by Kei Kebreau <kei@openmailbox.org>. +This patch comes from Debian and was modified by Kei Kebreau <kkebreau@posteo.net>. Link: https://anonscm.debian.org/cgit/pkg-wmaker/wmfire.git/plain/debian/patches/gdk_updates.patch?h=debian/1.2.4-2&id=a272234fc5eecdbfc469adb12133196bc62f3059 Description: Update for newer versions of GDK. diff --git a/gnu/packages/patches/wxwidgets-fix-windowGTK.patch b/gnu/packages/patches/wxwidgets-fix-windowGTK.patch deleted file mode 100644 index 1255835d01..0000000000 --- a/gnu/packages/patches/wxwidgets-fix-windowGTK.patch +++ /dev/null @@ -1,18 +0,0 @@ -This patch allow Filezilla client to resize window. -The patch was adapted from upstream source repository: -'<http://trac.wxwidgets.org/changeset/4793e5b0a4e189e492287305859b278fed780080/git-wxWidgets>' - ---- a/src/gtk/toplevel.cpp 2014-10-06 16:33:44.000000000 -0500 -+++ b/src/gtk/toplevel.cpp 2017-02-16 21:33:27.779907810 -0600 -@@ -1216,8 +1216,9 @@ - int hints_mask = GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE; - hints.min_width = 1; - hints.min_height = 1; -- hints.max_width = INT_MAX; -- hints.max_height = INT_MAX; -+ // using INT_MAX for size will lead to integer overflow with HiDPI scaling -+ hints.max_width = INT_MAX / 16; -+ hints.max_height = INT_MAX / 16; - const int decorSize_x = m_decorSize.left + m_decorSize.right; - const int decorSize_y = m_decorSize.top + m_decorSize.bottom; - if (minSize.x > decorSize_x) |