Added check for invalid number of frames.

@@ -942,7 +942,9 @@ MATLAB_KO: ThrowReaderException(CorruptImageError,"ImproperImageHeader");
       case 16: z2=z = ReadBlobXXXLong(image2);  /* 4D matrix animation */
          if(z!=3 && z!=1)
            ThrowReaderException(CoderError, "MultidimensionalMatricesAreNotSupported");
-          Frames = ReadBlobXXXLong(image2);
+         Frames = ReadBlobXXXLong(image2);
+         if (Frames == 0)
+           ThrowReaderException(CorruptImageError,"ImproperImageHeader");
          break;
       default: ThrowReaderException(CoderError, "MultidimensionalMatricesAreNotSupported");
     }


@@ -4999,6 +4999,8 @@ static void MSLStartElement(void *context,const xmlChar *tag,
                     Image
                       *image;

+                    if (value == (char *) NULL)
+                      break;
                     (void) CopyMagickString(msl_info->image_info[n]->filename,
                       value,MaxTextExtent);
                     image=ReadImage(msl_info->image_info[n],exception);


@@ -213,7 +213,7 @@ MagickExport MagickBooleanType CloneImageProperties(Image *image,
 %
 %  DefineImageProperty() associates an assignment string of the form
 %  "key=value" with an artifact or options. It is equivelent to
-%  SetImageProperty()
+%  SetImageProperty().
 %
 %  The format of the DefineImageProperty method is:
 %
@@ -3962,7 +3962,7 @@ MagickExport MagickBooleanType SetImageProperty(Image *image,
     {
       /*
         Do not 'set' single letter properties - read only shorthand.
-       */
+      */
       (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
         "SetReadOnlyProperty","`%s'",property);
       return(MagickFalse);


Fix issue #646 (#648)

* Fix issue #646 and some edge cases with wide regexps using \b and \B

* Rename function IS_WORD_CHAR to _yr_re_is_word_char

@@ -850,6 +850,7 @@ int yr_execute_code(
           (uint8_t*) r2.re->code,
           (uint8_t*) r1.ss->c_string,
           r1.ss->length,
+          0,
           r2.re->flags | RE_FLAGS_SCAN,
           NULL,
           NULL) >= 0;


[media] cxusb: Use a dma capable buffer also for reading

Commit 17ce039b4e54 ("[media] cxusb: don't do DMA on stack")
added a kmalloc'ed bounce buffer for writes, but missed to do the same
for reads. As the read only happens after the write is finished, we can
reuse the same buffer.

As dvb_usb_generic_rw handles a read length of 0 by itself, avoid calling
it using the dvb_usb_generic_read wrapper function.

Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>

@@ -59,23 +59,24 @@ static int cxusb_ctrl_msg(struct dvb_usb_device *d,
 			  u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
 {
 	struct cxusb_state *st = d->priv;
-	int ret, wo;
+	int ret;

 	if (1 + wlen > MAX_XFER_SIZE) {
 		warn("i2c wr: len=%d is too big!\n", wlen);
 		return -EOPNOTSUPP;
 	}

-	wo = (rbuf == NULL || rlen == 0); /* write-only */
+	if (rlen > MAX_XFER_SIZE) {
+		warn("i2c rd: len=%d is too big!\n", rlen);
+		return -EOPNOTSUPP;
+	}

 	mutex_lock(&d->data_mutex);
 	st->data[0] = cmd;
 	memcpy(&st->data[1], wbuf, wlen);
-	if (wo)
-		ret = dvb_usb_generic_write(d, st->data, 1 + wlen);
-	else
-		ret = dvb_usb_generic_rw(d, st->data, 1 + wlen,
-					 rbuf, rlen, 0);
+	ret = dvb_usb_generic_rw(d, st->data, 1 + wlen, st->data, rlen, 0);
+	if (!ret && rbuf && rlen)
+		memcpy(rbuf, st->data, rlen);

 	mutex_unlock(&d->data_mutex);
 	return ret;


@@ -317,7 +317,7 @@ static void InsertRow(Image *image,unsigned char *p,ssize_t y,int bpp,
         q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
         if (q == (Quantum *) NULL)
           break;
-        for (x=0; x < ((ssize_t) image->columns-1); x+=2)
+        for (x=0; x < ((ssize_t) image->columns-1); x+=4)
         {
             index=ConstrainColormapIndex(image,(*p >> 6) & 0x3,exception);
             SetPixelIndex(image,index,q);


@@ -685,19 +685,6 @@ MagickExport MagickBooleanType BlackThresholdImage(Image *image,
 %
 */

-static inline Quantum ClampPixel(const MagickRealType value)
-{
-#if !defined(MAGICKCORE_HDRI_SUPPORT)
-  return((Quantum) value);
-#else
-  if (value < 0.0f)
-    return(0.0);
-  if (value >= (MagickRealType) QuantumRange)
-    return((Quantum) QuantumRange);
-  return(value);
-#endif
-}
-
 MagickExport MagickBooleanType ClampImage(Image *image,ExceptionInfo *exception)
 {
 #define ClampImageTag  "Clamp/Image"


Fix abort when writing to rgf format

The rgf format (LEGO MINDSTORMS EV3 images) caused a software abort because
exception == NULL. When WriteRGFImage is called from WriteImage, it is only
passed two parameters, not three. So, removed the extra parameter and use
image->exception instead as in other coders.

@@ -68,7 +68,7 @@
   Forward declarations.
 */
 static MagickBooleanType
-  WriteRGFImage(const ImageInfo *,Image *,ExceptionInfo *);
+  WriteRGFImage(const ImageInfo *,Image *);

 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -305,7 +305,7 @@ ModuleExport void UnregisterRGFImage(void)
 %  The format of the WriteRGFImage method is:
 %
 %      MagickBooleanType WriteRGFImage(const ImageInfo *image_info,
-%        Image *image,ExceptionInfo *exception)
+%        Image *image)
 %
 %  A description of each parameter follows.
 %
@@ -316,8 +316,7 @@ ModuleExport void UnregisterRGFImage(void)
 %    o exception: return any errors or warnings in this structure.
 %
 */
-static MagickBooleanType WriteRGFImage(const ImageInfo *image_info,Image *image,
-  ExceptionInfo *exception)
+static MagickBooleanType WriteRGFImage(const ImageInfo *image_info,Image *image)
 {
   MagickBooleanType
     status;
@@ -346,9 +345,7 @@ static MagickBooleanType WriteRGFImage(const ImageInfo *image_info,Image *image,
   assert(image->signature == MagickSignature);
   if (image->debug != MagickFalse)
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
-  assert(exception != (ExceptionInfo *) NULL);
-  assert(exception->signature == MagickSignature);
-  status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
+  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
   if (status == MagickFalse)
     return(status);
   (void) TransformImageColorspace(image,sRGBColorspace);
@@ -367,7 +364,7 @@ static MagickBooleanType WriteRGFImage(const ImageInfo *image_info,Image *image,
   y=0;
   for (y=0; y < (ssize_t) image->rows; y++)
   {
-    p=GetVirtualPixels(image,0,y,image->columns,1,exception);
+    p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
     if (p == (const PixelPacket *) NULL)
       break;
     bit=0;


@@ -1908,6 +1908,8 @@ static Image *ReadPSDImage(const ImageInfo *image_info,ExceptionInfo *exception)
           image->alpha_trait=UndefinedPixelTrait;
         }
     }
+  if ((image->depth == 1) && (image->storage_class != PseudoClass))
+    ThrowReaderException(CorruptImageError, "ImproperImageHeader");
   has_merged_image=MagickTrue;
   length=ReadBlobMSBLong(image);
   if (length != 0)


Added extra EOF check and some minor refactoring.

@@ -726,9 +726,9 @@ static const DDSSingleColourLookup*
 if (min > max) \
   min = max; \
 if (max - min < steps) \
-  max = Min(min + steps, 255); \
+  max = MagickMin(min + steps, 255); \
 if (max - min < steps) \
-  min = Max(min - steps, 0)
+  min = MagickMax(min - steps, 0)

 #define Dot(left, right) (left.x*right.x) + (left.y*right.y) + (left.z*right.z)

@@ -743,90 +743,30 @@ if (max - min < steps) \
   Forward declarations
 */
 static MagickBooleanType
-  ConstructOrdering(const size_t, const DDSVector4 *, const DDSVector3,
-    DDSVector4 *, DDSVector4 *, unsigned char *, size_t);
-
-static MagickBooleanType
-  ReadDDSInfo(Image *, DDSInfo *);
-
-static MagickBooleanType
-  ReadDXT1(Image *, DDSInfo *, ExceptionInfo *);
-
-static MagickBooleanType
-  ReadDXT3(Image *, DDSInfo *, ExceptionInfo *);
-
-static MagickBooleanType
-  ReadDXT5(Image *, DDSInfo *, ExceptionInfo *);
-
-static MagickBooleanType
-  ReadUncompressedRGB(Image *, DDSInfo *, ExceptionInfo *);
-
-static MagickBooleanType
-  ReadUncompressedRGBA(Image *, DDSInfo *, ExceptionInfo *);
-
-static void
-  RemapIndices(const ssize_t *, const unsigned char *, unsigned char *);
-
-static void
-  SkipDXTMipmaps(Image *, DDSInfo *, int);
-
-static void
-  SkipRGBMipmaps(Image *, DDSInfo *, int);
-
-static
-  MagickBooleanType WriteDDSImage(const ImageInfo *, Image *);
-
-static void
-  WriteDDSInfo(Image *, const size_t, const size_t, const size_t);
-
-static void
-  WriteFourCC(Image *, const size_t, const MagickBooleanType,
-    const MagickBooleanType, ExceptionInfo *);
+  ConstructOrdering(const size_t,const DDSVector4 *,const DDSVector3,
+    DDSVector4 *,DDSVector4 *,unsigned char *,size_t),
+  ReadDDSInfo(Image *,DDSInfo *),
+  ReadDXT1(Image *,DDSInfo *,ExceptionInfo *),
+  ReadDXT3(Image *,DDSInfo *,ExceptionInfo *),
+  ReadDXT5(Image *,DDSInfo *,ExceptionInfo *),
+  ReadUncompressedRGB(Image *,DDSInfo *,ExceptionInfo *),
+  ReadUncompressedRGBA(Image *,DDSInfo *,ExceptionInfo *),
+  SkipDXTMipmaps(Image *,DDSInfo *,int,ExceptionInfo *),
+  SkipRGBMipmaps(Image *,DDSInfo *,int,ExceptionInfo *),
+  WriteDDSImage(const ImageInfo *,Image *),
+  WriteMipmaps(Image *,const size_t,const size_t,const size_t,
+    const MagickBooleanType,const MagickBooleanType,ExceptionInfo *);

 static void
-  WriteImageData(Image *, const size_t, const size_t, const MagickBooleanType,
-    const MagickBooleanType, ExceptionInfo *);
-
-static void
-  WriteIndices(Image *, const DDSVector3, const DDSVector3, unsigned char *);
-
-static MagickBooleanType
-  WriteMipmaps(Image *, const size_t, const size_t, const size_t,
-    const MagickBooleanType, const MagickBooleanType, ExceptionInfo *);
-
-static void
-  WriteSingleColorFit(Image *, const DDSVector4 *, const ssize_t *);
-
-static void
-  WriteUncompressed(Image *, ExceptionInfo *);
-
-static inline size_t Max(size_t one, size_t two)
-{
-  if (one > two)
-    return one;
-  return two;
-}
-
-static inline float MaxF(float one, float two)
-{
-  if (one > two)
-    return one;
-  return two;
-}
-
-static inline size_t Min(size_t one, size_t two)
-{
-  if (one < two)
-    return one;
-  return two;
-}
-
-static inline float MinF(float one, float two)
-{
-  if (one < two)
-    return one;
-  return two;
-}
+  RemapIndices(const ssize_t *,const unsigned char *,unsigned char *),
+  WriteDDSInfo(Image *,const size_t,const size_t,const size_t),
+  WriteFourCC(Image *,const size_t,const MagickBooleanType,
+    const MagickBooleanType,ExceptionInfo *),
+  WriteImageData(Image *,const size_t,const size_t,const MagickBooleanType,
+    const MagickBooleanType,ExceptionInfo *),
+  WriteIndices(Image *,const DDSVector3,const DDSVector3, unsigned char *),
+  WriteSingleColorFit(Image *,const DDSVector4 *,const ssize_t *),
+  WriteUncompressed(Image *,ExceptionInfo *);

 static inline void VectorAdd(const DDSVector4 left, const DDSVector4 right,
   DDSVector4 *destination)
@@ -839,17 +779,17 @@ static inline void VectorAdd(const DDSVector4 left, const DDSVector4 right,

 static inline void VectorClamp(DDSVector4 *value)
 {
-  value->x = MinF(1.0f,MaxF(0.0f,value->x));
-  value->y = MinF(1.0f,MaxF(0.0f,value->y));
-  value->z = MinF(1.0f,MaxF(0.0f,value->z));
-  value->w = MinF(1.0f,MaxF(0.0f,value->w));
+  value->x = MagickMin(1.0f,MagickMax(0.0f,value->x));
+  value->y = MagickMin(1.0f,MagickMax(0.0f,value->y));
+  value->z = MagickMin(1.0f,MagickMax(0.0f,value->z));
+  value->w = MagickMin(1.0f,MagickMax(0.0f,value->w));
 }

 static inline void VectorClamp3(DDSVector3 *value)
 {
-  value->x = MinF(1.0f,MaxF(0.0f,value->x));
-  value->y = MinF(1.0f,MaxF(0.0f,value->y));
-  value->z = MinF(1.0f,MaxF(0.0f,value->z));
+  value->x = MagickMin(1.0f,MagickMax(0.0f,value->x));
+  value->y = MagickMin(1.0f,MagickMax(0.0f,value->y));
+  value->z = MagickMin(1.0f,MagickMax(0.0f,value->z));
 }

 static inline void VectorCopy43(const DDSVector4 source,
@@ -1474,7 +1414,7 @@ static void ComputePrincipleComponent(const float *covariance,
     w.z = (row2.z * v.z) + w.z;
     w.w = (row2.w * v.z) + w.w;

-    a = 1.0f / MaxF(w.x,MaxF(w.y,w.z));
+    a = 1.0f / MagickMax(w.x,MagickMax(w.y,w.z));

     v.x = w.x * a;
     v.y = w.y * a;
@@ -1961,8 +1901,8 @@ static MagickBooleanType ReadDXT1(Image *image, DDSInfo *dds_info,
     for (x = 0; x < (ssize_t) dds_info->width; x += 4)
     {
       /* Get 4x4 patch of pixels to write on */
-      q = QueueAuthenticPixels(image, x, y, Min(4, dds_info->width - x),
-        Min(4, dds_info->height - y),exception);
+      q = QueueAuthenticPixels(image, x, y, MagickMin(4, dds_info->width - x),
+        MagickMin(4, dds_info->height - y),exception);

       if (q == (PixelPacket *) NULL)
         return MagickFalse;
@@ -1999,9 +1939,7 @@ static MagickBooleanType ReadDXT1(Image *image, DDSInfo *dds_info,
     }
   }

-  SkipDXTMipmaps(image, dds_info, 8);
-
-  return MagickTrue;
+  return(SkipDXTMipmaps(image,dds_info,8,exception));
 }

 static MagickBooleanType ReadDXT3(Image *image, DDSInfo *dds_info,
@@ -2039,8 +1977,8 @@ static MagickBooleanType ReadDXT3(Image *image, DDSInfo *dds_info,
     for (x = 0; x < (ssize_t) dds_info->width; x += 4)
     {
       /* Get 4x4 patch of pixels to write on */
-      q = QueueAuthenticPixels(image, x, y, Min(4, dds_info->width - x),
-                         Min(4, dds_info->height - y),exception);
+      q = QueueAuthenticPixels(image, x, y, MagickMin(4, dds_info->width - x),
+                         MagickMin(4, dds_info->height - y),exception);

       if (q == (PixelPacket *) NULL)
         return MagickFalse;
@@ -2086,9 +2024,7 @@ static MagickBooleanType ReadDXT3(Image *image, DDSInfo *dds_info,
     }
   }

-  SkipDXTMipmaps(image, dds_info, 16);
-
-  return MagickTrue;
+  return(SkipDXTMipmaps(image,dds_info,16,exception));
 }

 static MagickBooleanType ReadDXT5(Image *image, DDSInfo *dds_info,
@@ -2130,8 +2066,8 @@ static MagickBooleanType ReadDXT5(Image *image, DDSInfo *dds_info,
     for (x = 0; x < (ssize_t) dds_info->width; x += 4)
     {
       /* Get 4x4 patch of pixels to write on */
-      q = QueueAuthenticPixels(image, x, y, Min(4, dds_info->width - x),
-                         Min(4, dds_info->height - y),exception);
+      q = QueueAuthenticPixels(image, x, y, MagickMin(4, dds_info->width - x),
+                         MagickMin(4, dds_info->height - y),exception);

       if (q == (PixelPacket *) NULL)
         return MagickFalse;
@@ -2187,9 +2123,7 @@ static MagickBooleanType ReadDXT5(Image *image, DDSInfo *dds_info,
     }
   }

-  SkipDXTMipmaps(image, dds_info, 16);
-
-  return MagickTrue;
+  return(SkipDXTMipmaps(image,dds_info,16,exception));
 }

 static MagickBooleanType ReadUncompressedRGB(Image *image, DDSInfo *dds_info,
@@ -2251,9 +2185,7 @@ static MagickBooleanType ReadUncompressedRGB(Image *image, DDSInfo *dds_info,
       return MagickFalse;
   }

-  SkipRGBMipmaps(image, dds_info, 3);
-
-  return MagickTrue;
+  return(SkipRGBMipmaps(image,dds_info,3,exception));
 }

 static MagickBooleanType ReadUncompressedRGBA(Image *image, DDSInfo *dds_info,
@@ -2345,9 +2277,7 @@ static MagickBooleanType ReadUncompressedRGBA(Image *image, DDSInfo *dds_info,
       return MagickFalse;
   }

-  SkipRGBMipmaps(image, dds_info, 4);
-
-  return MagickTrue;
+  return(SkipRGBMipmaps(image,dds_info,4,exception));
 }

 /*
@@ -2423,7 +2353,8 @@ static void RemapIndices(const ssize_t *map, const unsigned char *source,
 /*
   Skip the mipmap images for compressed (DXTn) dds files
 */
-static void SkipDXTMipmaps(Image *image, DDSInfo *dds_info, int texel_size)
+static MagickBooleanType SkipDXTMipmaps(Image *image,DDSInfo *dds_info,
+  int texel_size,ExceptionInfo *exception)
 {
   register ssize_t
     i;
@@ -2442,6 +2373,12 @@ static void SkipDXTMipmaps(Image *image, DDSInfo *dds_info, int texel_size)
       && (dds_info->ddscaps1 & DDSCAPS_TEXTURE
           || dds_info->ddscaps2 & DDSCAPS2_CUBEMAP))
     {
+      if (EOFBlob(image) != MagickFalse)
+        {
+          ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
+            image->filename);
+          return(MagickFalse);
+        }
       w = DIV2(dds_info->width);
       h = DIV2(dds_info->height);

@@ -2457,12 +2394,14 @@ static void SkipDXTMipmaps(Image *image, DDSInfo *dds_info, int texel_size)
         h = DIV2(h);
       }
     }
+  return(MagickTrue);
 }

 /*
   Skip the mipmap images for uncompressed (RGB or RGBA) dds files
 */
-static void SkipRGBMipmaps(Image *image, DDSInfo *dds_info, int pixel_size)
+static MagickBooleanType SkipRGBMipmaps(Image *image,DDSInfo *dds_info,
+  int pixel_size,ExceptionInfo *exception)
 {
   MagickOffsetType
     offset;
@@ -2481,6 +2420,12 @@ static void SkipRGBMipmaps(Image *image, DDSInfo *dds_info, int pixel_size)
       && (dds_info->ddscaps1 & DDSCAPS_TEXTURE
           || dds_info->ddscaps2 & DDSCAPS2_CUBEMAP))
     {
+      if (EOFBlob(image) != MagickFalse)
+        {
+          ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
+            image->filename);
+          return(MagickFalse);
+        }
       w = DIV2(dds_info->width);
       h = DIV2(dds_info->height);

@@ -2496,6 +2441,7 @@ static void SkipRGBMipmaps(Image *image, DDSInfo *dds_info, int pixel_size)
         h = DIV2(h);
       }
     }
+  return(MagickTrue);
 }

 /*
@@ -2779,10 +2725,10 @@ static void WriteDDSInfo(Image *image, const size_t pixelFormat,

   if (compression == FOURCC_DXT1)
     (void) WriteBlobLSBLong(image,
-             (unsigned int) (Max(1,(image->columns+3)/4) * 8));
+             (unsigned int) (MagickMax(1,(image->columns+3)/4) * 8));
   else
     (void) WriteBlobLSBLong(image,
-             (unsigned int) (Max(1,(image->columns+3)/4) * 16));
+             (unsigned int) (MagickMax(1,(image->columns+3)/4) * 16));

   (void) WriteBlobLSBLong(image,0x00);
   (void) WriteBlobLSBLong(image,(unsigned int) mipmaps+1);


avcodec/utils: correct align value for interplay

Fixes out of array access
Fixes: 452/fuzz-1-ffmpeg_VIDEO_AV_CODEC_ID_INTERPLAY_VIDEO_fuzzer

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>

@@ -376,6 +376,10 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height,
             w_align = 4;
             h_align = 4;
         }
+        if (s->codec_id == AV_CODEC_ID_INTERPLAY_VIDEO) {
+            w_align = 8;
+            h_align = 8;
+        }
         break;
     case AV_PIX_FMT_PAL8:
     case AV_PIX_FMT_BGR8:
@@ -385,7 +389,8 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height,
             w_align = 4;
             h_align = 4;
         }
-        if (s->codec_id == AV_CODEC_ID_JV) {
+        if (s->codec_id == AV_CODEC_ID_JV ||
+            s->codec_id == AV_CODEC_ID_INTERPLAY_VIDEO) {
             w_align = 8;
             h_align = 8;
         }


ping: implement proper locking

We got a report of yet another bug in ping

http://www.openwall.com/lists/oss-security/2017/03/24/6

->disconnect() is not called with socket lock held.

Fix this by acquiring ping rwlock earlier.

Thanks to Daniel, Alexander and Andrey for letting us know this problem.

Fixes: c319b4d76b9e ("net: ipv4: add IPPROTO_ICMP socket kind")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reported-by: Daniel Jiang <danieljiang0415@gmail.com>
Reported-by: Solar Designer <solar@openwall.com>
Reported-by: Andrey Konovalov <andreyknvl@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

@@ -156,17 +156,18 @@ int ping_hash(struct sock *sk)
 void ping_unhash(struct sock *sk)
 {
 	struct inet_sock *isk = inet_sk(sk);
+
 	pr_debug("ping_unhash(isk=%p,isk->num=%u)\n", isk, isk->inet_num);
+	write_lock_bh(&ping_table.lock);
 	if (sk_hashed(sk)) {
-		write_lock_bh(&ping_table.lock);
 		hlist_nulls_del(&sk->sk_nulls_node);
 		sk_nulls_node_init(&sk->sk_nulls_node);
 		sock_put(sk);
 		isk->inet_num = 0;
 		isk->inet_sport = 0;
 		sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
-		write_unlock_bh(&ping_table.lock);
 	}
+	write_unlock_bh(&ping_table.lock);
 }
 EXPORT_SYMBOL_GPL(ping_unhash);


re_lexer: Make reading escape sequences more robust (#586)

* Add test for issue #503

* re_lexer: Make reading escape sequences more robust

This commit fixes parsing incomplete escape sequences at the end of a
regular expression and parsing things like \xxy (invalid hex digits)
which before were silently turned into (char)255.

Close #503

* Update re_lexer.c

@@ -190,7 +190,7 @@ typedef size_t yy_size_t;

     /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires
      *       access to the local variable yy_act. Since yyless() is a macro, it would break
-     *       existing scanners that call yyless() from OUTSIDE re_yylex.
+     *       existing scanners that call yyless() from OUTSIDE re_yylex.
      *       One obvious solution it to make yy_act a global. I tried that, and saw
      *       a 5% performance hit in a non-yylineno scanner, because yy_act is
      *       normally declared as a register variable-- so it is not worth it.
@@ -266,7 +266,7 @@ struct yy_buffer_state

     int yy_bs_lineno; /**< The line count. */
     int yy_bs_column; /**< The column count. */
-
+
 	/* Whether to try to fill the input buffer when we reach the
 	 * end of it.
 	 */
@@ -906,7 +906,7 @@ YY_DECL
 			yy_size_t yyl;
 			for ( yyl = 0; yyl < yyleng; ++yyl )
 				if ( yytext[yyl] == '\n' )
-
+
     do{ yylineno++;
         yycolumn=0;
     }while(0)
@@ -1125,7 +1125,7 @@ YY_RULE_SETUP
   }
   else
   {
-    yyerror(yyscanner, lex_env, "unexpected end of buffer");
+    yyerror(yyscanner, lex_env, "illegal escape sequence");
     yyterminate();
   }
 }
@@ -1180,7 +1180,7 @@ YY_RULE_SETUP
   {
     if (!read_escaped_char(yyscanner, &end))
     {
-      yyerror(yyscanner, lex_env, "unexpected end of buffer");
+      yyerror(yyscanner, lex_env, "illegal escape sequence");
       yyterminate();
     }
   }
@@ -1292,7 +1292,7 @@ YY_RULE_SETUP
   }
   else
   {
-    yyerror(yyscanner, lex_env, "unexpected end of buffer");
+    yyerror(yyscanner, lex_env, "illegal escape sequence");
     yyterminate();
   }
 }
@@ -1763,7 +1763,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
 	yyg->yy_hold_char = *++yyg->yy_c_buf_p;

 	if ( c == '\n' )
-
+
     do{ yylineno++;
         yycolumn=0;
     }while(0)
@@ -2018,9 +2018,9 @@ static void re_yyensure_buffer_stack (yyscan_t yyscanner)
 								, yyscanner);
 		if ( ! yyg->yy_buffer_stack )
 			YY_FATAL_ERROR( "out of dynamic memory in re_yyensure_buffer_stack()" );
-
+
 		memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));
-
+
 		yyg->yy_buffer_stack_max = num_to_alloc;
 		yyg->yy_buffer_stack_top = 0;
 		return;
@@ -2049,7 +2049,7 @@ static void re_yyensure_buffer_stack (yyscan_t yyscanner)
  * @param base the character buffer
  * @param size the size in bytes of the character buffer
  * @param yyscanner The scanner object.
- * @return the newly allocated buffer state object.
+ * @return the newly allocated buffer state object.
  */
 YY_BUFFER_STATE re_yy_scan_buffer  (char * base, yy_size_t  size , yyscan_t yyscanner)
 {
@@ -2177,7 +2177,7 @@ YY_EXTRA_TYPE re_yyget_extra  (yyscan_t yyscanner)
 int re_yyget_lineno  (yyscan_t yyscanner)
 {
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
+
         if (! YY_CURRENT_BUFFER)
             return 0;

@@ -2190,7 +2190,7 @@ int re_yyget_lineno  (yyscan_t yyscanner)
 int re_yyget_column  (yyscan_t yyscanner)
 {
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
+
         if (! YY_CURRENT_BUFFER)
             return 0;

@@ -2365,20 +2365,20 @@ int re_yylex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals )
         errno = EINVAL;
         return 1;
     }
-
+
     *ptr_yy_globals = (yyscan_t) re_yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
-
+
     if (*ptr_yy_globals == NULL){
         errno = ENOMEM;
         return 1;
     }
-
+
     /* By setting to 0xAA, we expose bugs in
     yy_init_globals. Leave at 0x00 for releases. */
     memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
-
+
     re_yyset_extra (yy_user_defined, *ptr_yy_globals);
-
+
     return yy_init_globals ( *ptr_yy_globals );
 }

@@ -2568,19 +2568,19 @@ int read_escaped_char(
   text[0] = '\\';
   text[1] = RE_YY_INPUT(yyscanner);

-  if (text[1] == EOF)
+  if (text[1] == EOF || text[1] == 0)
     return 0;

   if (text[1] == 'x')
   {
     text[2] = RE_YY_INPUT(yyscanner);

-    if (text[2] == EOF)
+    if (!isxdigit(text[2]))
       return 0;

     text[3] = RE_YY_INPUT(yyscanner);

-    if (text[3] == EOF)
+    if (!isxdigit(text[3]))
       return 0;
   }


Do not use "/bin/sh" to run external commands.

Picocom no longer uses /bin/sh to run external commands for
file-transfer operations. Parsing the command line and spliting it into
arguments is now performed internally by picocom, using quoting rules
very similar to those of the Unix shell. Hopefully, this makes it
impossible to inject shell-commands when supplying filenames or
extra arguments to the send- and receive-file commands.

@@ -48,6 +48,7 @@
 #define _GNU_SOURCE
 #include <getopt.h>

+#include "split.h"
 #include "term.h"
 #ifdef LINENOISE
 #include "linenoise-1.0/linenoise.h"
@@ -721,6 +722,9 @@ show_status (int dtr_up)

 /**********************************************************************/

+#define RUNCMD_ARGS_MAX 32
+#define RUNCMD_EXEC_FAIL 126
+
 void
 establish_child_signal_handlers (void)
 {
@@ -735,10 +739,8 @@ establish_child_signal_handlers (void)
 	sigaction (SIGTERM, &dfl_action, NULL);
 }

-#define EXEC "exec "
-
 int
-run_cmd(int fd, ...)
+run_cmd(int fd, const char *cmd, const char *args_extra)
 {
 	pid_t pid;
 	sigset_t sigm, sigm_old;
@@ -781,8 +783,10 @@ run_cmd(int fd, ...)
 	} else {
 		/* child: external program */
 		long fl;
-		char cmd[512];
-
+		int argc;
+		char *argv[RUNCMD_ARGS_MAX + 1];
+		int r;
+
 		/* unmanage terminal, and reset it to canonical mode */
 		term_remove(STI);
 		/* unmanage serial port fd, without reset */
@@ -796,37 +800,36 @@ run_cmd(int fd, ...)
 		close(STO);
 		dup2(fd, STI);
 		dup2(fd, STO);
-		{
-			/* build command-line */
-			char *c, *ce;
-			const char *s;
-			int n;
-			va_list vls;
-
-			strcpy(cmd, EXEC);
-			c = &cmd[sizeof(EXEC)- 1];
-			ce = cmd + sizeof(cmd) - 1;
-			va_start(vls, fd);
-			while ( (s = va_arg(vls, const char *)) ) {
-				n = strlen(s);
-				if ( c + n + 1 >= ce ) break;
-				memcpy(c, s, n); c += n;
-				*c++ = ' ';
-			}
-			va_end(vls);
-			*c = '\0';
+
+		/* build command arguments vector */
+		argc = 0;
+		r = split_quoted(cmd, &argc, argv, RUNCMD_ARGS_MAX);
+		if ( r < 0 ) {
+			fd_printf(STDERR_FILENO, "Cannot parse command\n");
+			exit(RUNCMD_EXEC_FAIL);
+		}
+		r = split_quoted(args_extra, &argc, argv, RUNCMD_ARGS_MAX);
+		if ( r < 0 ) {
+			fd_printf(STDERR_FILENO, "Cannot parse extra args\n");
+			exit(RUNCMD_EXEC_FAIL);
 		}
+		if ( argc < 1 ) {
+			fd_printf(STDERR_FILENO, "No command given\n");
+			exit(RUNCMD_EXEC_FAIL);
+		}
+		argv[argc] = NULL;
+
 		/* run extenral command */
-		fd_printf(STDERR_FILENO, "%s\n", &cmd[sizeof(EXEC) - 1]);
+		fd_printf(STDERR_FILENO, "$ %s %s\n", cmd, args_extra);
 		establish_child_signal_handlers();
 		sigprocmask(SIG_SETMASK, &sigm_old, NULL);
-		execl("/bin/sh", "sh", "-c", cmd, NULL);
-		exit(42);
+		execvp(argv[0], argv);
+
+		fd_printf(STDERR_FILENO, "exec: %s\n", strerror(errno));
+		exit(RUNCMD_EXEC_FAIL);
 	}
 }

-#undef EXEC
-
 /**********************************************************************/

 /* Process command key. Returns non-zero if command results in picocom
@@ -944,7 +947,7 @@ do_command (unsigned char c)
 			fd_printf(STO, "*** cannot read filename ***\r\n");
 			break;
 		}
-		run_cmd(tty_fd, xfr_cmd, fname, NULL);
+		run_cmd(tty_fd, xfr_cmd, fname);
 		free(fname);
 		break;
 	case KEY_BREAK:


Avoid pre-decrement of pointer in big-endian CRC calculation.

There was a small optimization for PowerPCs to pre-increment a
pointer when accessing a word, instead of post-incrementing. This
required prefacing the loop with a decrement of the pointer,
possibly pointing before the object passed. This is not compliant
with the C standard, for which decrementing a pointer before its
allocated memory is undefined. When tested on a modern PowerPC
with a modern compiler, the optimization no longer has any effect.
Due to all that, and per the recommendation of a security audit of
the zlib code by Trail of Bits and TrustInSoft, in support of the
Mozilla Foundation, this "optimization" was removed, in order to
avoid the possibility of undefined behavior.

@@ -278,7 +278,7 @@ local unsigned long crc32_little(crc, buf, len)
 }

 /* ========================================================================= */
-#define DOBIG4 c ^= *++buf4; \
+#define DOBIG4 c ^= *buf4++; \
         c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
             crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
 #define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
@@ -300,7 +300,6 @@ local unsigned long crc32_big(crc, buf, len)
     }

     buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
-    buf4--;
     while (len >= 32) {
         DOBIG32;
         len -= 32;
@@ -309,7 +308,6 @@ local unsigned long crc32_big(crc, buf, len)
         DOBIG4;
         len -= 4;
     }
-    buf4++;
     buf = (const unsigned char FAR *)buf4;

     if (len) do {


Added check to prevent image being 0x0 (reported in #489).

@@ -1677,16 +1677,15 @@ static Image *ReadDDSImage(const ImageInfo *image_info,ExceptionInfo *exception)
   /*
     Initialize image structure.
   */
-  if (ReadDDSInfo(image, &dds_info) != MagickTrue) {
+  if (ReadDDSInfo(image, &dds_info) != MagickTrue)
     ThrowReaderException(CorruptImageError,"ImproperImageHeader");
-  }
-
+
   if (dds_info.ddscaps2 & DDSCAPS2_CUBEMAP)
     cubemap = MagickTrue;
-
+
   if (dds_info.ddscaps2 & DDSCAPS2_VOLUME && dds_info.depth > 0)
     volume = MagickTrue;
-
+
   (void) SeekBlob(image, 128, SEEK_SET);

   /*
@@ -1775,7 +1774,10 @@ static Image *ReadDDSImage(const ImageInfo *image_info,ExceptionInfo *exception)

   if (volume)
     num_images = dds_info.depth;
-
+
+  if (num_images < 1)
+    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
+
   for (n = 0; n < num_images; n++)
   {
     if (n != 0)


ipv6/dccp: do not inherit ipv6_mc_list from parent

Like commit 657831ffc38e ("dccp/tcp: do not inherit mc_list from parent")
we should clear ipv6_mc_list etc. for IPv6 sockets too.

Cc: Eric Dumazet <edumazet@google.com>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Acked-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

@@ -426,6 +426,9 @@ static struct sock *dccp_v6_request_recv_sock(const struct sock *sk,
 		newsk->sk_backlog_rcv = dccp_v4_do_rcv;
 		newnp->pktoptions  = NULL;
 		newnp->opt	   = NULL;
+		newnp->ipv6_mc_list = NULL;
+		newnp->ipv6_ac_list = NULL;
+		newnp->ipv6_fl_list = NULL;
 		newnp->mcast_oif   = inet6_iif(skb);
 		newnp->mcast_hops  = ipv6_hdr(skb)->hop_limit;

@@ -490,6 +493,9 @@ static struct sock *dccp_v6_request_recv_sock(const struct sock *sk,
 	/* Clone RX bits */
 	newnp->rxopt.all = np->rxopt.all;

+	newnp->ipv6_mc_list = NULL;
+	newnp->ipv6_ac_list = NULL;
+	newnp->ipv6_fl_list = NULL;
 	newnp->pktoptions = NULL;
 	newnp->opt	  = NULL;
 	newnp->mcast_oif  = inet6_iif(skb);


Merge tag 'nfsd-4.12' of git://linux-nfs.org/~bfields/linux

Pull nfsd updates from Bruce Fields:
 "Another RDMA update from Chuck Lever, and a bunch of miscellaneous
  bugfixes"

* tag 'nfsd-4.12' of git://linux-nfs.org/~bfields/linux: (26 commits)
  nfsd: Fix up the "supattr_exclcreat" attributes
  nfsd: encoders mustn't use unitialized values in error cases
  nfsd: fix undefined behavior in nfsd4_layout_verify
  lockd: fix lockd shutdown race
  NFSv4: Fix callback server shutdown
  SUNRPC: Refactor svc_set_num_threads()
  NFSv4.x/callback: Create the callback service through svc_create_pooled
  lockd: remove redundant check on block
  svcrdma: Clean out old XDR encoders
  svcrdma: Remove the req_map cache
  svcrdma: Remove unused RDMA Write completion handler
  svcrdma: Reduce size of sge array in struct svc_rdma_op_ctxt
  svcrdma: Clean up RPC-over-RDMA backchannel reply processing
  svcrdma: Report Write/Reply chunk overruns
  svcrdma: Clean up RDMA_ERROR path
  svcrdma: Use rdma_rw API in RPC reply path
  svcrdma: Introduce local rdma_rw API helpers
  svcrdma: Clean up svc_rdma_get_inv_rkey()
  svcrdma: Add helper to save pages under I/O
  svcrdma: Eliminate RPCRDMA_SQ_DEPTH_MULT
  ...

@@ -257,6 +257,9 @@ nfssvc_decode_readargs(struct svc_rqst *rqstp, __be32 *p,
 	len = args->count     = ntohl(*p++);
 	p++; /* totalcount - unused */

+	if (!xdr_argsize_check(rqstp, p))
+		return 0;
+
 	len = min_t(unsigned int, len, NFSSVC_MAXBLKSIZE_V2);

 	/* set up somewhere to store response.
@@ -272,7 +275,7 @@ nfssvc_decode_readargs(struct svc_rqst *rqstp, __be32 *p,
 		v++;
 	}
 	args->vlen = v;
-	return xdr_argsize_check(rqstp, p);
+	return 1;
 }

 int
@@ -362,9 +365,11 @@ nfssvc_decode_readlinkargs(struct svc_rqst *rqstp, __be32 *p, struct nfsd_readli
 	p = decode_fh(p, &args->fh);
 	if (!p)
 		return 0;
+	if (!xdr_argsize_check(rqstp, p))
+		return 0;
 	args->buffer = page_address(*(rqstp->rq_next_page++));

-	return xdr_argsize_check(rqstp, p);
+	return 1;
 }

 int
@@ -402,9 +407,11 @@ nfssvc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p,
 	args->cookie = ntohl(*p++);
 	args->count  = ntohl(*p++);
 	args->count  = min_t(u32, args->count, PAGE_SIZE);
+	if (!xdr_argsize_check(rqstp, p))
+		return 0;
 	args->buffer = page_address(*(rqstp->rq_next_page++));

-	return xdr_argsize_check(rqstp, p);
+	return 1;
 }

 /*


@@ -558,33 +558,85 @@ static void rdma_read_complete(struct svc_rqst *rqstp,
 	rqstp->rq_arg.buflen = head->arg.buflen;
 }

+static void svc_rdma_send_error(struct svcxprt_rdma *xprt,
+				__be32 *rdma_argp, int status)
+{
+	struct svc_rdma_op_ctxt *ctxt;
+	__be32 *p, *err_msgp;
+	unsigned int length;
+	struct page *page;
+	int ret;
+
+	ret = svc_rdma_repost_recv(xprt, GFP_KERNEL);
+	if (ret)
+		return;
+
+	page = alloc_page(GFP_KERNEL);
+	if (!page)
+		return;
+	err_msgp = page_address(page);
+
+	p = err_msgp;
+	*p++ = *rdma_argp;
+	*p++ = *(rdma_argp + 1);
+	*p++ = xprt->sc_fc_credits;
+	*p++ = rdma_error;
+	if (status == -EPROTONOSUPPORT) {
+		*p++ = err_vers;
+		*p++ = rpcrdma_version;
+		*p++ = rpcrdma_version;
+	} else {
+		*p++ = err_chunk;
+	}
+	length = (unsigned long)p - (unsigned long)err_msgp;
+
+	/* Map transport header; no RPC message payload */
+	ctxt = svc_rdma_get_context(xprt);
+	ret = svc_rdma_map_reply_hdr(xprt, ctxt, err_msgp, length);
+	if (ret) {
+		dprintk("svcrdma: Error %d mapping send for protocol error\n",
+			ret);
+		return;
+	}
+
+	ret = svc_rdma_post_send_wr(xprt, ctxt, 1, 0);
+	if (ret) {
+		dprintk("svcrdma: Error %d posting send for protocol error\n",
+			ret);
+		svc_rdma_unmap_dma(ctxt);
+		svc_rdma_put_context(ctxt, 1);
+	}
+}
+
 /* By convention, backchannel calls arrive via rdma_msg type
  * messages, and never populate the chunk lists. This makes
  * the RPC/RDMA header small and fixed in size, so it is
  * straightforward to check the RPC header's direction field.
  */
-static bool
-svc_rdma_is_backchannel_reply(struct svc_xprt *xprt, struct rpcrdma_msg *rmsgp)
+static bool svc_rdma_is_backchannel_reply(struct svc_xprt *xprt,
+					  __be32 *rdma_resp)
 {
-	__be32 *p = (__be32 *)rmsgp;
+	__be32 *p;

 	if (!xprt->xpt_bc_xprt)
 		return false;

-	if (rmsgp->rm_type != rdma_msg)
+	p = rdma_resp + 3;
+	if (*p++ != rdma_msg)
 		return false;
-	if (rmsgp->rm_body.rm_chunks[0] != xdr_zero)
+
+	if (*p++ != xdr_zero)
 		return false;
-	if (rmsgp->rm_body.rm_chunks[1] != xdr_zero)
+	if (*p++ != xdr_zero)
 		return false;
-	if (rmsgp->rm_body.rm_chunks[2] != xdr_zero)
+	if (*p++ != xdr_zero)
 		return false;

-	/* sanity */
-	if (p[7] != rmsgp->rm_xid)
+	/* XID sanity */
+	if (*p++ != *rdma_resp)
 		return false;
 	/* call direction */
-	if (p[8] == cpu_to_be32(RPC_CALL))
+	if (*p == cpu_to_be32(RPC_CALL))
 		return false;

 	return true;
@@ -650,8 +702,9 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp)
 		goto out_drop;
 	rqstp->rq_xprt_hlen = ret;

-	if (svc_rdma_is_backchannel_reply(xprt, rmsgp)) {
-		ret = svc_rdma_handle_bc_reply(xprt->xpt_bc_xprt, rmsgp,
+	if (svc_rdma_is_backchannel_reply(xprt, &rmsgp->rm_xid)) {
+		ret = svc_rdma_handle_bc_reply(xprt->xpt_bc_xprt,
+					       &rmsgp->rm_xid,
 					       &rqstp->rq_arg);
 		svc_rdma_put_context(ctxt, 0);
 		if (ret)
@@ -686,7 +739,7 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp)
 	return ret;

 out_err:
-	svc_rdma_send_error(rdma_xprt, rmsgp, ret);
+	svc_rdma_send_error(rdma_xprt, &rmsgp->rm_xid, ret);
 	svc_rdma_put_context(ctxt, 0);
 	return 0;


USB: serial: omninet: fix reference leaks at open

This driver needlessly took another reference to the tty on open, a
reference which was then never released on close. This lead to not just
a leak of the tty, but also a driver reference leak that prevented the
driver from being unloaded after a port had once been opened.

Fixes: 4a90f09b20f4 ("tty: usb-serial krefs")
Cc: stable <stable@vger.kernel.org>	# 2.6.28
Signed-off-by: Johan Hovold <johan@kernel.org>

@@ -142,12 +142,6 @@ static int omninet_port_remove(struct usb_serial_port *port)

 static int omninet_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
-	struct usb_serial	*serial = port->serial;
-	struct usb_serial_port	*wport;
-
-	wport = serial->port[1];
-	tty_port_tty_set(&wport->port, tty);
-
 	return usb_serial_generic_open(tty, port);
 }


ALSA: msnd: Optimize / harden DSP and MIDI loops

The ISA msnd drivers have loops fetching the ring-buffer head, tail
and size values inside the loops.  Such codes are inefficient and
fragile.

This patch optimizes it, and also adds the sanity check to avoid the
endless loops.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=196131
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=196133
Signed-off-by: Takashi Iwai <tiwai@suse.de>

@@ -170,23 +170,24 @@ static irqreturn_t snd_msnd_interrupt(int irq, void *dev_id)
 {
 	struct snd_msnd *chip = dev_id;
 	void *pwDSPQData = chip->mappedbase + DSPQ_DATA_BUFF;
+	u16 head, tail, size;

 	/* Send ack to DSP */
 	/* inb(chip->io + HP_RXL); */

 	/* Evaluate queued DSP messages */
-	while (readw(chip->DSPQ + JQS_wTail) != readw(chip->DSPQ + JQS_wHead)) {
-		u16 wTmp;
-
-		snd_msnd_eval_dsp_msg(chip,
-			readw(pwDSPQData + 2 * readw(chip->DSPQ + JQS_wHead)));
-
-		wTmp = readw(chip->DSPQ + JQS_wHead) + 1;
-		if (wTmp > readw(chip->DSPQ + JQS_wSize))
-			writew(0, chip->DSPQ + JQS_wHead);
-		else
-			writew(wTmp, chip->DSPQ + JQS_wHead);
+	head = readw(chip->DSPQ + JQS_wHead);
+	tail = readw(chip->DSPQ + JQS_wTail);
+	size = readw(chip->DSPQ + JQS_wSize);
+	if (head > size || tail > size)
+		goto out;
+	while (head != tail) {
+		snd_msnd_eval_dsp_msg(chip, readw(pwDSPQData + 2 * head));
+		if (++head > size)
+			head = 0;
+		writew(head, chip->DSPQ + JQS_wHead);
 	}
+ out:
 	/* Send ack to DSP */
 	inb(chip->io + HP_RXL);
 	return IRQ_HANDLED;


avcodec/webp: Always set pix_fmt

Fixes: out of array access
Fixes: 1434/clusterfuzz-testcase-minimized-6314998085189632
Fixes: 1435/clusterfuzz-testcase-minimized-6483783723253760

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg
Reviewed-by: "Ronald S. Bultje" <rsbultje@gmail.com>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>

@@ -1334,9 +1334,8 @@ static int vp8_lossy_decode_frame(AVCodecContext *avctx, AVFrame *p,
     if (!s->initialized) {
         ff_vp8_decode_init(avctx);
         s->initialized = 1;
-        if (s->has_alpha)
-            avctx->pix_fmt = AV_PIX_FMT_YUVA420P;
     }
+    avctx->pix_fmt = s->has_alpha ? AV_PIX_FMT_YUVA420P : AV_PIX_FMT_YUV420P;
     s->lossless = 0;

     if (data_size > INT_MAX) {


NetKVM: BZ#1169718: Checking the length only on read

Signed-off-by: Joseph Hindin <yhindin@rehat.com>

@@ -866,7 +866,7 @@ tPacketIndicationType ParaNdis_PrepareReceivedPacket(
                     pHeader->flags,
                     &pBuffersDesc->PhysicalPages[PARANDIS_FIRST_RX_DATA_PAGE],
                     pPacketInfo->dataLength,
-                    nBytesStripped);
+                    nBytesStripped, TRUE);
                 if (csRes.value)
                 {
                     NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO qCSInfo;


make the dump directories owned by root by default

It was discovered that the abrt event scripts create a user-readable
copy of a sosreport file in abrt problem directories, and include
excerpts of /var/log/messages selected by the user-controlled process
name, leading to an information disclosure.

This issue was discovered by Florian Weimer of Red Hat Product Security.

Related: #1212868

Signed-off-by: Jakub Filak <jfilak@redhat.com>

@@ -189,6 +189,14 @@ static unsigned create_oops_dump_dirs(GList *oops_list, unsigned oops_cnt)
         mode = DEFAULT_DUMP_DIR_MODE;
         my_euid = geteuid();
     }
+    if (g_settings_privatereports)
+    {
+        if (world_readable_dump)
+            log("Not going to make dump directories world readable because PrivateReports is on");
+
+        mode = DEFAULT_DUMP_DIR_MODE;
+        my_euid = 0;
+    }

     pid_t my_pid = getpid();
     unsigned idx = 0;


Bug 1347760 - CVE-2016-4992 389-ds-base: Information disclosure via repeated use of LDAP ADD operation, etc.

Description: If a bind user has no rights, it should not disclose
any information including the existence of the entry.

Fix description:
1) ALREADY_EXISTS in add -- If to be added entry is found existing
   in ldbm_back_add, it checks the ACI and if there is no rights,
   it returns INSUFFICIENT_ACCESS instead of ALREADY_EXISTS.
2) NO_SUCH_OBJECT in other update operations -- If the target entry
   is found not existing, it checks the ancestor entry's access
   rights in find_entry.  If it is not allowed to access the subtree,
   it returns INSUFFICIENT_ACCESS instead of NO_SUC_OBJECT.  Plus,
   it supresses the "Matched" ancestor message.
3) NO_SUCH_OBJECT in search -- If a bind entry has no rights to read
   a subtree, it returns no search results with SUCCESS.  It should
   be applied to the no existing subtree if the bind entry has no
   rights to the super tree.
4) If bind fails because of the non-existence of the bind user or
   the parent nodes, the bind returns LDAP_INVALID_CREDENTIALS to
   the client with no other information.
   The detailed cause is logged in the access log as follows:
	 RESULT err=49 .. etime=0 - No such suffix (<given suffix>)
	 RESULT err=49 .. etime=0 - Invalid credentials
	 RESULT err=49 .. etime=0 - No such entry

https://bugzilla.redhat.com/show_bug.cgi?id=1347760

Reviewed by lkrispen@redhat.com, mreynolds@redhat.com, and tbordaz@redhat.com.
Thank you!!!

@@ -16,8 +16,8 @@
 #include "back-ldbm.h"

-static struct backentry *find_entry_internal_dn(Slapi_PBlock *pb, backend *be, const Slapi_DN *sdn, int lock, back_txn *txn, int flags);
-static struct backentry * find_entry_internal(Slapi_PBlock *pb, Slapi_Backend *be, const entry_address *addr, int lock, back_txn *txn, int flags);
+static struct backentry *find_entry_internal_dn(Slapi_PBlock *pb, backend *be, const Slapi_DN *sdn, int lock, back_txn *txn, int flags, int *rc);
+static struct backentry * find_entry_internal(Slapi_PBlock *pb, Slapi_Backend *be, const entry_address *addr, int lock, back_txn *txn, int flags, int *rc);
 /* The flags take these values */
 #define FE_TOMBSTONE_INCLUDED TOMBSTONE_INCLUDED /* :1 defined in back-ldbm.h */
 #define FE_REALLY_INTERNAL 0x2
@@ -27,7 +27,7 @@ check_entry_for_referral(Slapi_PBlock *pb, Slapi_Entry *entry, char *matched, co
 {
 	int rc=0, i=0, numValues=0;
 	Slapi_Attr *attr;
-	Slapi_Value *val=NULL;
+	Slapi_Value *val=NULL;
 	struct berval **refscopy=NULL;
 	struct berval **url=NULL;

@@ -80,22 +80,28 @@ check_entry_for_referral(Slapi_PBlock *pb, Slapi_Entry *entry, char *matched, co

 static struct backentry *
 find_entry_internal_dn(
-	Slapi_PBlock	*pb,
+    Slapi_PBlock	*pb,
     backend			*be,
     const Slapi_DN *sdn,
     int				lock,
-	back_txn		*txn,
-	int				flags
+    back_txn		*txn,
+    int				flags,
+    int				*rc /* return code */
 )
 {
 	struct backentry *e;
 	int	managedsait = 0;
 	int	err;
 	ldbm_instance *inst = (ldbm_instance *) be->be_instance_info;
 	size_t tries = 0;
+	int isroot = 0;
+	int op_type;
+	char *errbuf = NULL;

 	/* get the managedsait ldap message control */
-	slapi_pblock_get( pb, SLAPI_MANAGEDSAIT, &managedsait );
+	slapi_pblock_get(pb, SLAPI_MANAGEDSAIT, &managedsait);
+	slapi_pblock_get(pb, SLAPI_REQUESTOR_ISROOT, &isroot);
+	slapi_pblock_get(pb, SLAPI_OPERATION_TYPE, &op_type);

 	while ( (tries < LDBM_CACHE_RETRY_COUNT) &&
 	        (e = dn2entry_ext( be, sdn, txn, flags & TOMBSTONE_INCLUDED, &err ))
@@ -113,6 +119,9 @@ find_entry_internal_dn(
 			if(check_entry_for_referral(pb, e->ep_entry, NULL, "find_entry_internal_dn"))
 			{
 				CACHE_RETURN( &inst->inst_cache, &e );
+				if (rc) { /* if check_entry_for_referral returns non-zero, result is sent. */
+					*rc = FE_RC_SENT_RESULT;
+				}
 				return( NULL );
 			}
 		}
@@ -151,27 +160,89 @@ find_entry_internal_dn(
 		struct backentry *me;
 		Slapi_DN ancestorsdn;
 		slapi_sdn_init(&ancestorsdn);
-		me= dn2ancestor(pb->pb_backend,sdn,&ancestorsdn,txn,&err);
+		me = dn2ancestor(pb->pb_backend, sdn, &ancestorsdn, txn, &err, 1 /* allow_suffix */);
 		if ( !managedsait && me != NULL ) {
 			/* if the entry is a referral send the referral */
 			if(check_entry_for_referral(pb, me->ep_entry, (char*)slapi_sdn_get_dn(&ancestorsdn), "find_entry_internal_dn"))
 			{
 				CACHE_RETURN( &inst->inst_cache, &me );
 				slapi_sdn_done(&ancestorsdn);
+				if (rc) { /* if check_entry_for_referral returns non-zero, result is sent. */
+					*rc = FE_RC_SENT_RESULT;
+				}
 				return( NULL );
 			}
 			/* else fall through to no such object */
 		}

 		/* entry not found */
-		slapi_send_ldap_result( pb, ( 0 == err || DB_NOTFOUND == err ) ?
-			LDAP_NO_SUCH_OBJECT : ( LDAP_INVALID_DN_SYNTAX == err ) ?
-			LDAP_INVALID_DN_SYNTAX : LDAP_OPERATIONS_ERROR,
-			(char*)slapi_sdn_get_dn(&ancestorsdn), NULL, 0, NULL );
+		if ((0 == err) || (DB_NOTFOUND == err)) {
+			if (me && !isroot) {
+				/* If not root, you may not want to reveal it. */
+				int acl_type = -1;
+				int return_err = LDAP_NO_SUCH_OBJECT;
+				err = LDAP_SUCCESS;
+				switch (op_type) {
+				case SLAPI_OPERATION_ADD:
+					acl_type = SLAPI_ACL_ADD;
+					return_err = LDAP_INSUFFICIENT_ACCESS;
+					break;
+				case SLAPI_OPERATION_DELETE:
+					acl_type = SLAPI_ACL_DELETE;
+					return_err = LDAP_INSUFFICIENT_ACCESS;
+					break;
+				case SLAPI_OPERATION_MODDN:
+					acl_type = SLAPI_ACL_MODDN;
+					return_err = LDAP_INSUFFICIENT_ACCESS;
+					break;
+				case SLAPI_OPERATION_MODIFY:
+					acl_type = SLAPI_ACL_WRITE;
+					return_err = LDAP_INSUFFICIENT_ACCESS;
+					break;
+				case SLAPI_OPERATION_SEARCH:
+				case SLAPI_OPERATION_COMPARE:
+					return_err = LDAP_SUCCESS;
+					acl_type = SLAPI_ACL_READ;
+					break;
+				case SLAPI_OPERATION_BIND:
+					acl_type = -1; /* skip acl check. acl is not set up for bind. */
+					return_err = LDAP_INVALID_CREDENTIALS;
+					slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, "No such entry");
+					break;
+				}
+				if (acl_type > 0) {
+					err = plugin_call_acl_plugin(pb, me->ep_entry, NULL, NULL, acl_type,
+					                             ACLPLUGIN_ACCESS_DEFAULT, &errbuf);
+				}
+				if (((acl_type > 0) && err) || (op_type == SLAPI_OPERATION_BIND)) {
+					/*
+					 * Operations to be checked && ACL returns disallow.
+					 * Not to disclose the info about the entry's existence,
+					 * do not return the "matched" DN.
+					 * Plus, the bind case returns LDAP_INAPPROPRIATE_AUTH.
+					 */
+					slapi_send_ldap_result(pb, return_err, NULL, NULL, 0, NULL);
+				} else {
+					slapi_send_ldap_result(pb, LDAP_NO_SUCH_OBJECT,
+						(char*)slapi_sdn_get_dn(&ancestorsdn), NULL, 0, NULL);
+				}
+			} else {
+				slapi_send_ldap_result( pb, LDAP_NO_SUCH_OBJECT,
+					(char*)slapi_sdn_get_dn(&ancestorsdn), NULL, 0, NULL);
+			}
+		} else {
+			slapi_send_ldap_result( pb, ( LDAP_INVALID_DN_SYNTAX == err ) ?
+				LDAP_INVALID_DN_SYNTAX : LDAP_OPERATIONS_ERROR,
+				(char*)slapi_sdn_get_dn(&ancestorsdn), NULL, 0, NULL );
+		}
+		if (rc) {
+			*rc = FE_RC_SENT_RESULT;
+		}
 		slapi_sdn_done(&ancestorsdn);
 		CACHE_RETURN( &inst->inst_cache, &me );
 	}

+	slapi_ch_free_string(&errbuf);
 	LDAPDebug( LDAP_DEBUG_TRACE, "<= find_entry_internal_dn not found (%s)\n",
 	    slapi_sdn_get_dn(sdn), 0, 0 );
 	return( NULL );
@@ -183,11 +254,11 @@ find_entry_internal_dn(
  */
 static struct backentry *
 find_entry_internal_uniqueid(
-	Slapi_PBlock	*pb,
+    Slapi_PBlock	*pb,
     backend *be,
-	const char 			*uniqueid,
+    const char 			*uniqueid,
     int				lock,
-	back_txn		*txn
+    back_txn		*txn
 )
 {
 	ldbm_instance *inst = (ldbm_instance *) be->be_instance_info;
@@ -243,8 +314,9 @@ find_entry_internal(
     Slapi_Backend *be,
     const entry_address *addr,
     int			lock,
-	back_txn *txn,
-	int flags
+    back_txn *txn,
+    int flags,
+    int *rc
 )
 {
 	/* check if we should search based on uniqueid or dn */
@@ -261,11 +333,9 @@ find_entry_internal(
 		LDAPDebug( LDAP_DEBUG_TRACE, "=> find_entry_internal (dn=%s) lock %d\n",
 		           slapi_sdn_get_dn(addr->sdn), lock, 0 );
 		if (addr->sdn) {
-			entry = find_entry_internal_dn (pb, be, addr->sdn,
-			                                lock, txn, flags);
+			entry = find_entry_internal_dn (pb, be, addr->sdn, lock, txn, flags, rc);
 		} else {
-			LDAPDebug0Args( LDAP_DEBUG_ANY,
-			                "find_entry_internal: Null target dn\n" );
+			LDAPDebug0Args( LDAP_DEBUG_ANY, "find_entry_internal: Null target dn\n" );
 		}

 		LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= find_entry_internal\n" );
@@ -278,21 +348,23 @@ find_entry(
     Slapi_PBlock		*pb,
     Slapi_Backend *be,
     const entry_address *addr,
-	back_txn *txn
+    back_txn *txn,
+    int *rc
 )
 {
-	return( find_entry_internal( pb, be, addr, 0/*!lock*/, txn, 0/*flags*/ ) );
+	return(find_entry_internal(pb, be, addr, 0/*!lock*/, txn, 0/*flags*/, rc));
 }

 struct backentry *
 find_entry2modify(
     Slapi_PBlock		*pb,
     Slapi_Backend *be,
     const entry_address *addr,
-	back_txn *txn
+    back_txn *txn,
+    int *rc
 )
 {
-	return( find_entry_internal( pb, be, addr, 1/*lock*/, txn, 0/*flags*/ ) );
+	return(find_entry_internal(pb, be, addr, 1/*lock*/, txn, 0/*flags*/, rc));
 }

 /* New routines which do not do any referral stuff.
@@ -304,21 +376,23 @@ find_entry_only(
     Slapi_PBlock		*pb,
     Slapi_Backend *be,
     const entry_address *addr,
-	back_txn *txn
+    back_txn *txn,
+    int *rc
 )
 {
-	return( find_entry_internal( pb, be, addr, 0/*!lock*/, txn, FE_REALLY_INTERNAL ) );
+	return(find_entry_internal(pb, be, addr, 0/*!lock*/, txn, FE_REALLY_INTERNAL, rc));
 }

 struct backentry *
 find_entry2modify_only(
     Slapi_PBlock		*pb,
     Slapi_Backend *be,
     const entry_address *addr,
-    back_txn *txn
+    back_txn *txn,
+    int *rc
 )
 {
-	return( find_entry_internal( pb, be, addr, 1/*lock*/, txn, FE_REALLY_INTERNAL ) );
+	return(find_entry_internal(pb, be, addr, 1/*lock*/, txn, 0 /* to check aci, disable INTERNAL */, rc));
 }

 struct backentry *
@@ -327,10 +401,9 @@ find_entry2modify_only_ext(
     Slapi_Backend *be,
     const entry_address *addr,
     int flags,
-    back_txn *txn
-
+    back_txn *txn,
+    int *rc
 )
 {
-	return( find_entry_internal( pb, be, addr, 1/*lock*/, txn,
-		                         FE_REALLY_INTERNAL | flags ));
+	return(find_entry_internal(pb, be, addr, 1/*lock*/, txn, FE_REALLY_INTERNAL | flags, rc));
 }


@@ -162,7 +162,7 @@ vlvSearch_init(struct vlvSearch* p, Slapi_PBlock *pb, const Slapi_Entry *e, ldbm

             addr.sdn = p->vlv_base;
             addr.uniqueid = NULL;
-            e = find_entry( pb, inst->inst_be, &addr, &txn );
+            e = find_entry(pb, inst->inst_be, &addr, &txn, NULL);
             /* Check to see if the entry is absent. If it is, mark this search
              * as not initialized */
             if (NULL == e) {


avcodec/dnxhddec: Move mb height check out of non hr branch

Fixes: out of array access
Fixes: poc.dnxhd

Found-by: Bingchang, Liu@VARAS of IIE
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit 296debd213bd6dce7647cedd34eb64e5b94cdc92)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>

@@ -278,14 +278,18 @@ static int dnxhd_decode_header(DNXHDContext *ctx, AVFrame *frame,
     if (header_prefix == DNXHD_HEADER_HR2) {
         ctx->data_offset = 0x170 + (ctx->mb_height << 2);
     } else {
-        if (ctx->mb_height > 68 ||
-            (ctx->mb_height << frame->interlaced_frame) > (ctx->height + 15) >> 4) {
+        if (ctx->mb_height > 68) {
             av_log(ctx->avctx, AV_LOG_ERROR,
                    "mb height too big: %d\n", ctx->mb_height);
             return AVERROR_INVALIDDATA;
         }
         ctx->data_offset = 0x280;
     }
+    if ((ctx->mb_height << frame->interlaced_frame) > (ctx->height + 15) >> 4) {
+        av_log(ctx->avctx, AV_LOG_ERROR,
+                "mb height too big: %d\n", ctx->mb_height);
+        return AVERROR_INVALIDDATA;
+    }

     if (buf_size < ctx->data_offset) {
         av_log(ctx->avctx, AV_LOG_ERROR,


[Bug 2382] Implement LOGTOD using ldexp() instead of shifting

@@ -156,10 +156,9 @@ typedef char s_char;
 #define SQUARE(x) ((x) * (x))
 #define SQRT(x) (sqrt(x))
 #define DIFF(x, y) (SQUARE((x) - (y)))
-#define LOGTOD(a)	((a) < 0 ? 1. / (1L << -(a)) : \
-			    1L << (int)(a)) /* log2 to double */
+#define LOGTOD(a)	ldexp(1., (int)(a)) /* log2 to double */
 #define UNIVAR(x)	(SQUARE(.28867513 * LOGTOD(x))) /* std uniform distr */
-#define ULOGTOD(a)	(1L << (int)(a)) /* ulog2 to double */
+#define ULOGTOD(a)	ldexp(1., (int)(a)) /* ulog2 to double */

 #define	EVENT_TIMEOUT	0	/* one second, that is */


avcodec/apedec: Fix integer overflow

Fixes: out of array access
Fixes: PoC.ape and others

Found-by: Bingchang, Liu@VARAS of IIE
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>

@@ -1412,6 +1412,7 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data,
     int32_t *sample24;
     int i, ch, ret;
     int blockstodecode;
+    uint64_t decoded_buffer_size;

     /* this should never be negative, but bad things will happen if it is, so
        check it just to make sure. */
@@ -1467,7 +1468,7 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data,
                 skip_bits_long(&s->gb, offset);
         }

-        if (!nblocks || nblocks > INT_MAX) {
+        if (!nblocks || nblocks > INT_MAX / 2 / sizeof(*s->decoded_buffer) - 8) {
             av_log(avctx, AV_LOG_ERROR, "Invalid sample count: %"PRIu32".\n",
                    nblocks);
             return AVERROR_INVALIDDATA;
@@ -1493,8 +1494,9 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data,
         blockstodecode = s->samples;

     /* reallocate decoded sample buffer if needed */
-    av_fast_malloc(&s->decoded_buffer, &s->decoded_size,
-                   2 * FFALIGN(blockstodecode, 8) * sizeof(*s->decoded_buffer));
+    decoded_buffer_size = 2LL * FFALIGN(blockstodecode, 8) * sizeof(*s->decoded_buffer);
+    av_assert0(decoded_buffer_size <= INT_MAX);
+    av_fast_malloc(&s->decoded_buffer, &s->decoded_size, decoded_buffer_size);
     if (!s->decoded_buffer)
         return AVERROR(ENOMEM);
     memset(s->decoded_buffer, 0, s->decoded_size);


Merge branch 'security' into 'master'

Security

Closes #10

See merge request !17

@@ -54,23 +54,26 @@ static void nick_hash_add(CHANNEL_REC *channel, NICK_REC *nick)

 static void nick_hash_remove(CHANNEL_REC *channel, NICK_REC *nick)
 {
-	NICK_REC *list;
+	NICK_REC *list, *newlist;

 	list = g_hash_table_lookup(channel->nicks, nick->nick);
 	if (list == NULL)
 		return;

-	if (list == nick || list->next == NULL) {
-		g_hash_table_remove(channel->nicks, nick->nick);
-		if (list->next != NULL) {
-			g_hash_table_insert(channel->nicks, nick->next->nick,
-					    nick->next);
-		}
+	if (list == nick) {
+		newlist = nick->next;
 	} else {
+		newlist = list;
 		while (list->next != nick)
 			list = list->next;
 		list->next = nick->next;
 	}
+
+	g_hash_table_remove(channel->nicks, nick->nick);
+	if (newlist != NULL) {
+		g_hash_table_insert(channel->nicks, newlist->nick,
+				    newlist);
+	}
 }

 /* Add new nick to list */


@@ -308,7 +308,7 @@ static char *fstrndup(const char *ptr, unsigned long len) {
   char *result;
   if (len <= 0) return NULL;
   result = ALLOC_N(char, len);
-  memccpy(result, ptr, 0, len);
+  memcpy(result, ptr, len);
   return result;
 }

@@ -1062,7 +1062,7 @@ static VALUE cState_indent_set(VALUE self, VALUE indent)
         }
     } else {
         if (state->indent) ruby_xfree(state->indent);
-        state->indent = strdup(RSTRING_PTR(indent));
+        state->indent = fstrndup(RSTRING_PTR(indent), len);
         state->indent_len = len;
     }
     return Qnil;
@@ -1100,7 +1100,7 @@ static VALUE cState_space_set(VALUE self, VALUE space)
         }
     } else {
         if (state->space) ruby_xfree(state->space);
-        state->space = strdup(RSTRING_PTR(space));
+        state->space = fstrndup(RSTRING_PTR(space), len);
         state->space_len = len;
     }
     return Qnil;
@@ -1136,7 +1136,7 @@ static VALUE cState_space_before_set(VALUE self, VALUE space_before)
         }
     } else {
         if (state->space_before) ruby_xfree(state->space_before);
-        state->space_before = strdup(RSTRING_PTR(space_before));
+        state->space_before = fstrndup(RSTRING_PTR(space_before), len);
         state->space_before_len = len;
     }
     return Qnil;
@@ -1173,7 +1173,7 @@ static VALUE cState_object_nl_set(VALUE self, VALUE object_nl)
         }
     } else {
         if (state->object_nl) ruby_xfree(state->object_nl);
-        state->object_nl = strdup(RSTRING_PTR(object_nl));
+        state->object_nl = fstrndup(RSTRING_PTR(object_nl), len);
         state->object_nl_len = len;
     }
     return Qnil;
@@ -1208,7 +1208,7 @@ static VALUE cState_array_nl_set(VALUE self, VALUE array_nl)
         }
     } else {
         if (state->array_nl) ruby_xfree(state->array_nl);
-        state->array_nl = strdup(RSTRING_PTR(array_nl));
+        state->array_nl = fstrndup(RSTRING_PTR(array_nl), len);
         state->array_nl_len = len;
     }
     return Qnil;


opj_t2_encode_packet(): fix potential write heap buffer overflow (#992)

@@ -629,6 +629,15 @@ static OPJ_BOOL opj_t2_encode_packet(OPJ_UINT32 tileno,

     /* <SOP 0xff91> */
     if (tcp->csty & J2K_CP_CSTY_SOP) {
+        if (length < 6) {
+            if (p_t2_mode == FINAL_PASS) {
+                opj_event_msg(p_manager, EVT_ERROR,
+                              "opj_t2_encode_packet(): only %u bytes remaining in "
+                              "output buffer. %u needed.\n",
+                              length, 6);
+            }
+            return OPJ_FALSE;
+        }
         c[0] = 255;
         c[1] = 145;
         c[2] = 0;
@@ -817,6 +826,15 @@ static OPJ_BOOL opj_t2_encode_packet(OPJ_UINT32 tileno,

     /* <EPH 0xff92> */
     if (tcp->csty & J2K_CP_CSTY_EPH) {
+        if (length < 2) {
+            if (p_t2_mode == FINAL_PASS) {
+                opj_event_msg(p_manager, EVT_ERROR,
+                              "opj_t2_encode_packet(): only %u bytes remaining in "
+                              "output buffer. %u needed.\n",
+                              length, 2);
+            }
+            return OPJ_FALSE;
+        }
         c[0] = 255;
         c[1] = 146;
         c += 2;


@@ -937,7 +937,8 @@ static Image *ReadMATImage(const ImageInfo *image_info,ExceptionInfo *exception)
   if (strncmp(MATLAB_HDR.identific, "MATLAB", 6))
     {
 MATLAB_KO:
-      clone_info=DestroyImageInfo(clone_info);
+      if (clone_info != (ImageInfo *) NULL)
+        clone_info=DestroyImageInfo(clone_info);
       ThrowReaderException(CorruptImageError,"ImproperImageHeader");
     }


imapd: check for isadmin BEFORE parsing sync lines

@@ -2062,6 +2062,8 @@ static void cmdloop(void)
                 snmp_increment(SCAN_COUNT, 1);
             }
             else if (!strcmp(cmd.s, "Syncapply")) {
+                if (!imapd_userisadmin) goto badcmd;
+
                 struct dlist *kl = sync_parseline(imapd_in);

                 if (kl) {
@@ -2071,6 +2073,8 @@ static void cmdloop(void)
                 else goto extraargs;
             }
             else if (!strcmp(cmd.s, "Syncget")) {
+                if (!imapd_userisadmin) goto badcmd;
+
                 struct dlist *kl = sync_parseline(imapd_in);

                 if (kl) {
@@ -2080,13 +2084,17 @@ static void cmdloop(void)
                 else goto extraargs;
             }
             else if (!strcmp(cmd.s, "Syncrestart")) {
+                if (!imapd_userisadmin) goto badcmd;
+
                 if (c == '\r') c = prot_getc(imapd_in);
                 if (c != '\n') goto extraargs;

                 /* just clear the GUID cache */
                 cmd_syncrestart(tag.s, &reserve_list, 1);
             }
             else if (!strcmp(cmd.s, "Syncrestore")) {
+                if (!imapd_userisadmin) goto badcmd;
+
                 struct dlist *kl = sync_parseline(imapd_in);

                 if (kl) {


Fix bug #175:

CVE-2017-11661, CVE-2017-11662, CVE-2017-11663, CVE-2017-11664:
Add a new size parameter to _WM_SetupMidiEvent() so that it
knows where to stop reading, and adjust its clients properly.

@@ -42,10 +42,10 @@ struct _mdi *
 _WM_ParseNewHmi(uint8_t *hmi_data, uint32_t hmi_size) {
     uint32_t hmi_tmp = 0;
     uint8_t *hmi_base = hmi_data;
+    uint32_t data_siz;
     uint16_t hmi_bpm = 0;
     uint16_t hmi_division = 0;

-//  uint32_t hmi_duration_secs = 0;
     uint32_t hmi_track_cnt = 0;
     uint32_t *hmi_track_offset = NULL;
     uint32_t i = 0;
@@ -74,8 +74,6 @@ _WM_ParseNewHmi(uint8_t *hmi_data, uint32_t hmi_size) {
         uint8_t channel;
     } *note;

-    //FIXME: This needs to be used for sanity check.
-    UNUSED(hmi_size);

     if (memcmp(hmi_data, "HMI-MIDISONG061595", 18)) {
         _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_HMI, NULL, 0);
@@ -216,21 +214,35 @@ _WM_ParseNewHmi(uint8_t *hmi_data, uint32_t hmi_size) {
             do {
                 hmi_data = hmi_base + hmi_track_offset[i];
                 hmi_delta[i] = 0;
+                if (hmi_track_offset[i] >= hmi_size) {
+                    _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_HMI, "file too short", 0);
+                    goto _hmi_end;
+                }
+                data_siz = hmi_size - hmi_track_offset[i];

                 if (hmi_data[0] == 0xfe) {
                     // HMI only event of some sort.
                     if (hmi_data[1] == 0x10) {
                         hmi_tmp = (hmi_data[4] + 5);
                         hmi_data += hmi_tmp;
                         hmi_track_offset[i] += hmi_tmp;
+                        hmi_tmp += 4;
                     } else if (hmi_data[1] == 0x15) {
                         hmi_data += 4;
                         hmi_track_offset[i] += 4;
+                        hmi_tmp = 8;
+                    } else {
+                        hmi_tmp = 4;
                     }
                     hmi_data += 4;
                     hmi_track_offset[i] += 4;
+                    if (hmi_tmp > data_siz) {
+                        _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_HMI, "file too short", 0);
+                        goto _hmi_end;
+                    }
+                    data_siz -= hmi_tmp;
                 } else {
-                    if ((setup_ret = _WM_SetupMidiEvent(hmi_mdi,hmi_data,hmi_running_event[i])) == 0) {
+                    if ((setup_ret = _WM_SetupMidiEvent(hmi_mdi,hmi_data,data_siz,hmi_running_event[i])) == 0) {
                         goto _hmi_end;
                     }
                     if ((hmi_data[0] == 0xff) && (hmi_data[1] == 0x2f) && (hmi_data[2] == 0x00)) {
@@ -269,17 +281,25 @@ _WM_ParseNewHmi(uint8_t *hmi_data, uint32_t hmi_size) {

                         hmi_data += setup_ret;
                         hmi_track_offset[i] += setup_ret;
+                        data_siz -= setup_ret;

                         note[hmi_tmp].length = 0;
-                        if (*hmi_data > 0x7f) {
+                        if (data_siz && *hmi_data > 0x7f) {
                             do {
+                                if (!data_siz) break;
                                 note[hmi_tmp].length = (note[hmi_tmp].length << 7) | (*hmi_data & 0x7F);
                                 hmi_data++;
+                                data_siz--;
                                 hmi_track_offset[i]++;
                             } while (*hmi_data > 0x7F);
                         }
+                        if (!data_siz) {
+                            _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_HMI, "file too short", 0);
+                            goto _hmi_end;
+                        }
                         note[hmi_tmp].length = (note[hmi_tmp].length << 7) | (*hmi_data & 0x7F);
                         hmi_data++;
+                        data_siz--;
                         hmi_track_offset[i]++;

                         if (note[hmi_tmp].length) {
@@ -293,20 +313,28 @@ _WM_ParseNewHmi(uint8_t *hmi_data, uint32_t hmi_size) {
                     } else {
                         hmi_data += setup_ret;
                         hmi_track_offset[i] += setup_ret;
+                        data_siz -= setup_ret;
                     }
                 }

                 // get track delta
                 // hmi_delta[i] = 0; // set at start of loop
-                if (*hmi_data > 0x7f) {
+                if (data_siz && *hmi_data > 0x7f) {
                     do {
+                        if (!data_siz) break;
                         hmi_delta[i] = (hmi_delta[i] << 7) | (*hmi_data & 0x7F);
                         hmi_data++;
+                        data_siz--;
                         hmi_track_offset[i]++;
                     } while (*hmi_data > 0x7F);
                 }
+                if (!data_siz) {
+                    _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_HMI, "file too short", 0);
+                    goto _hmi_end;
+                }
                 hmi_delta[i] = (hmi_delta[i] << 7) | (*hmi_data & 0x7F);
                 hmi_data++;
+                data_siz--;
                 hmi_track_offset[i]++;
             } while (!hmi_delta[i]);
             if ((!smallest_delta) || (smallest_delta > hmi_delta[i])) {


SECURITY: CPU usage amplification attack.

Details: https://github.com/sandstorm-io/capnproto/tree/master/security-advisories/2014-03-02-0-all-cpu-amplification.md

@@ -1410,6 +1410,36 @@ TEST(Encoding, Has) {
   EXPECT_TRUE(root.asReader().hasInt32List());
 }

+TEST(Encoding, VoidListAmplification) {
+  MallocMessageBuilder builder;
+  builder.initRoot<test::TestAnyPointer>().getAnyPointerField().initAs<List<Void>>(1u << 28);
+
+  auto segments = builder.getSegmentsForOutput();
+  EXPECT_EQ(1, segments.size());
+  EXPECT_LT(segments[0].size(), 16);  // quite small for such a big list!
+
+  SegmentArrayMessageReader reader(builder.getSegmentsForOutput());
+  auto root = reader.getRoot<test::TestAnyPointer>().getAnyPointerField();
+  EXPECT_NONFATAL_FAILURE(root.getAs<List<TestAllTypes>>());
+
+  MallocMessageBuilder copy;
+  EXPECT_NONFATAL_FAILURE(copy.setRoot(reader.getRoot<AnyPointer>()));
+}
+
+TEST(Encoding, EmptyStructListAmplification) {
+  MallocMessageBuilder builder;
+  builder.initRoot<test::TestAnyPointer>().getAnyPointerField()
+      .initAs<List<test::TestEmptyStruct>>(1u << 28);
+
+  auto segments = builder.getSegmentsForOutput();
+  EXPECT_EQ(1, segments.size());
+  EXPECT_LT(segments[0].size(), 16);  // quite small for such a big list!
+
+  SegmentArrayMessageReader reader(builder.getSegmentsForOutput());
+  auto root = reader.getRoot<test::TestAnyPointer>().getAnyPointerField();
+  EXPECT_NONFATAL_FAILURE(root.getAs<List<TestAllTypes>>());
+}
+
 TEST(Encoding, Constants) {
   EXPECT_EQ(VOID, test::TestConstants::VOID_CONST);
   EXPECT_EQ(true, test::TestConstants::BOOL_CONST);


@@ -1007,7 +1007,10 @@ static MagickBooleanType WritePCXImage(const ImageInfo *image_info,Image *image,
     length=(size_t) pcx_info.bytes_per_line;
     pixel_info=AcquireVirtualMemory(length,pcx_info.planes*sizeof(*pixels));
     if (pixel_info == (MemoryInfo *) NULL)
-      ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
+      {
+        pcx_colormap=(unsigned char *) RelinquishMagickMemory(pcx_colormap);
+        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
+      }
     pixels=(unsigned char *) GetVirtualMemoryBlob(pixel_info);
     q=pixels;
     if ((image->storage_class == DirectClass) || (image->colors > 256))


[IA64] Workaround for RSE issue

Problem: An application violating the architectural rules regarding
operation dependencies and having specific Register Stack Engine (RSE)
state at the time of the violation, may result in an illegal operation
fault and invalid RSE state.  Such faults may initiate a cascade of
repeated illegal operation faults within OS interruption handlers.
The specific behavior is OS dependent.

Implication: An application causing an illegal operation fault with
specific RSE state may result in a series of illegal operation faults
and an eventual OS stack overflow condition.

Workaround: OS interruption handlers that switch to kernel backing
store implement a check for invalid RSE state to avoid the series
of illegal operation faults.

The core of the workaround is the RSE_WORKAROUND code sequence
inserted into each invocation of the SAVE_MIN_WITH_COVER and
SAVE_MIN_WITH_COVER_R19 macros.  This sequence includes hard-coded
constants that depend on the number of stacked physical registers
being 96.  The rest of this patch consists of code to disable this
workaround should this not be the case (with the presumption that
if a future Itanium processor increases the number of registers, it
would also remove the need for this patch).

Move the start of the RBS up to a mod32 boundary to avoid some
corner cases.

The dispatch_illegal_op_fault code outgrew the spot it was
squatting in when built with this patch and CONFIG_VIRT_CPU_ACCOUNTING=y
Move it out to the end of the ivt.

Signed-off-by: Tony Luck <tony.luck@intel.com>

@@ -76,7 +76,7 @@
 # define KERNEL_STACK_SIZE_ORDER		0
 #endif

-#define IA64_RBS_OFFSET			((IA64_TASK_SIZE + IA64_THREAD_INFO_SIZE + 15) & ~15)
+#define IA64_RBS_OFFSET			((IA64_TASK_SIZE + IA64_THREAD_INFO_SIZE + 31) & ~31)
 #define IA64_STK_OFFSET			((1 << KERNEL_STACK_SIZE_ORDER)*PAGE_SIZE)

 #define KERNEL_STACK_SIZE		IA64_STK_OFFSET


Fix buffer overflow if NULL line is present in db.

If ptr->line == NULL for an entry, the first cycle will exit,
but the second one will happily write past entries buffer.
We actually do not want to exit the first cycle prematurely
on ptr->line == NULL.
Signed-off-by: Tomas Mraz <tmraz@fedoraproject.org>

@@ -751,16 +751,16 @@ commonio_sort (struct commonio_db *db, int (*cmp) (const void *, const void *))
 	for (ptr = db->head;
 	        (NULL != ptr)
 #if KEEP_NIS_AT_END
-	     && (NULL != ptr->line)
-	     && (   ('+' != ptr->line[0])
-	         && ('-' != ptr->line[0]))
+	     && ((NULL == ptr->line)
+	         || (('+' != ptr->line[0])
+	             && ('-' != ptr->line[0])))
 #endif
 	     ;
 	     ptr = ptr->next) {
 		n++;
 	}
 #if KEEP_NIS_AT_END
-	if ((NULL != ptr) && (NULL != ptr->line)) {
+	if (NULL != ptr) {
 		nis = ptr;
 	}
 #endif


nss-mymachines: do not allow overlong machine names

https://github.com/systemd/systemd/issues/2002

@@ -416,6 +416,9 @@ enum nss_status _nss_mymachines_getpwnam_r(
         if (!e || e == p)
                 goto not_found;

+        if (e - p > HOST_NAME_MAX - 1) /* -1 for the last dash */
+                goto not_found;
+
         r = parse_uid(e + 1, &uid);
         if (r < 0)
                 goto not_found;
@@ -573,6 +576,9 @@ enum nss_status _nss_mymachines_getgrnam_r(
         if (!e || e == p)
                 goto not_found;

+        if (e - p > HOST_NAME_MAX - 1)  /* -1 for the last dash */
+                goto not_found;
+
         r = parse_gid(e + 1, &gid);
         if (r < 0)
                 goto not_found;


kexec/uefi: copy secure_boot flag in boot params across kexec reboot

Kexec reboot in case secure boot being enabled does not keep the secure
boot mode in new kernel, so later one can load unsigned kernel via legacy
kexec_load.  In this state, the system is missing the protections provided
by secure boot. Adding a patch to fix this by retain the secure_boot flag
in original kernel.

secure_boot flag in boot_params is set in EFI stub, but kexec bypasses the
stub. Fixing this issue by copying secure_boot flag across kexec reboot.

Signed-off-by: Dave Young <dyoung@redhat.com>

@@ -180,6 +180,7 @@ setup_efi_state(struct boot_params *params, unsigned long params_load_addr,
 	if (efi_enabled(EFI_OLD_MEMMAP))
 		return 0;

+	params->secure_boot = boot_params.secure_boot;
 	ei->efi_loader_signature = current_ei->efi_loader_signature;
 	ei->efi_systab = current_ei->efi_systab;
 	ei->efi_systab_hi = current_ei->efi_systab_hi;


CVE-2017-13725/IPv6 R.H.: Check for the existence of all fields before fetching them.

Don't fetch the length field from the header until after we've checked
for the existence of a field at or after that field.

(Found by code inspection, not by a capture.)

@@ -45,13 +45,13 @@ rt6_print(netdissect_options *ndo, register const u_char *bp, const u_char *bp2
 	register const struct in6_addr *addr;

 	dp = (const struct ip6_rthdr *)bp;
-	len = dp->ip6r_len;

 	/* 'ep' points to the end of available data. */
 	ep = ndo->ndo_snapend;

 	ND_TCHECK(dp->ip6r_segleft);

+	len = dp->ip6r_len;
 	ND_PRINT((ndo, "srcrt (len=%d", dp->ip6r_len));	/*)*/
 	ND_PRINT((ndo, ", type=%d", dp->ip6r_type));
 	ND_PRINT((ndo, ", segleft=%d", dp->ip6r_segleft));


CVE-2017-12993/Juniper: Add more bounds checks.

This fixes a buffer over-read discovered by Kamil Frankowicz.

Add tests using the capture files supplied by the reporter(s).

@@ -472,6 +472,7 @@ juniper_ggsn_print(netdissect_options *ndo,
         p+=l2info.header_len;
         gh = (struct juniper_ggsn_header *)&l2info.cookie;

+        ND_TCHECK(*gh);
         if (ndo->ndo_eflag) {
             ND_PRINT((ndo, "proto %s (%u), vlan %u: ",
                    tok2str(juniper_protocol_values,"Unknown",gh->proto),
@@ -492,6 +493,10 @@ juniper_ggsn_print(netdissect_options *ndo,
         }

         return l2info.header_len;
+
+trunc:
+	ND_PRINT((ndo, "[|juniper_services]"));
+	return l2info.header_len;
 }
 #endif

@@ -519,6 +524,7 @@ juniper_es_print(netdissect_options *ndo,
         p+=l2info.header_len;
         ih = (const struct juniper_ipsec_header *)p;

+        ND_TCHECK(*ih);
         switch (ih->type) {
         case JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE:
         case JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE:
@@ -564,6 +570,10 @@ juniper_es_print(netdissect_options *ndo,

         ip_print(ndo, p, l2info.length);
         return l2info.header_len;
+
+trunc:
+	ND_PRINT((ndo, "[|juniper_services]"));
+	return l2info.header_len;
 }
 #endif

@@ -588,6 +598,7 @@ juniper_monitor_print(netdissect_options *ndo,
         p+=l2info.header_len;
         mh = (const struct juniper_monitor_header *)p;

+        ND_TCHECK(*mh);
         if (ndo->ndo_eflag)
             ND_PRINT((ndo, "service-id %u, iif %u, pkt-type %u: ",
                    EXTRACT_32BITS(&mh->service_id),
@@ -598,6 +609,10 @@ juniper_monitor_print(netdissect_options *ndo,
         ip_heuristic_guess (ndo, p, l2info.length);

         return l2info.header_len;
+
+trunc:
+	ND_PRINT((ndo, "[|juniper_services]"));
+	return l2info.header_len;
 }
 #endif

@@ -622,6 +637,7 @@ juniper_services_print(netdissect_options *ndo,
         p+=l2info.header_len;
         sh = (const struct juniper_services_header *)p;

+        ND_TCHECK(*sh);
         if (ndo->ndo_eflag)
             ND_PRINT((ndo, "service-id %u flags 0x%02x service-set-id 0x%04x iif %u: ",
                    sh->svc_id,
@@ -633,6 +649,10 @@ juniper_services_print(netdissect_options *ndo,
         ip_heuristic_guess (ndo, p, l2info.length);

         return l2info.header_len;
+
+trunc:
+	ND_PRINT((ndo, "[|juniper_services]"));
+	return l2info.header_len;
 }
 #endif

@@ -740,6 +760,7 @@ juniper_pppoe_atm_print(netdissect_options *ndo,

         p+=l2info.header_len;

+        ND_TCHECK2(p[0], 2);
         extracted_ethertype = EXTRACT_16BITS(p);
         /* this DLT contains nothing but raw PPPoE frames,
          * prepended with a type field*/
@@ -752,6 +773,10 @@ juniper_pppoe_atm_print(netdissect_options *ndo,
             ND_PRINT((ndo, "unknown ethertype 0x%04x", extracted_ethertype));

         return l2info.header_len;
+
+trunc:
+	ND_PRINT((ndo, "[|juniper_pppoe_atm]"));
+	return l2info.header_len;
 }
 #endif

@@ -940,6 +965,7 @@ juniper_atm1_print(netdissect_options *ndo,
             return l2info.header_len;
         }

+        ND_TCHECK2(p[0], 3);
         if (EXTRACT_24BITS(p) == 0xfefe03 || /* NLPID encaps ? */
             EXTRACT_24BITS(p) == 0xaaaa03) { /* SNAP encaps ? */

@@ -958,6 +984,10 @@ juniper_atm1_print(netdissect_options *ndo,
             return l2info.header_len;

 	return l2info.header_len;
+
+trunc:
+	ND_PRINT((ndo, "[|juniper_atm1]"));
+	return l2info.header_len;
 }
 #endif

@@ -989,6 +1019,7 @@ juniper_atm2_print(netdissect_options *ndo,
             return l2info.header_len;
         }

+        ND_TCHECK2(p[0], 3);
         if (EXTRACT_24BITS(p) == 0xfefe03 || /* NLPID encaps ? */
             EXTRACT_24BITS(p) == 0xaaaa03) { /* SNAP encaps ? */

@@ -1016,6 +1047,10 @@ juniper_atm2_print(netdissect_options *ndo,
             return l2info.header_len;

 	return l2info.header_len;
+
+trunc:
+	ND_PRINT((ndo, "[|juniper_atm2]"));
+	return l2info.header_len;
 }
 #endif

@@ -1280,6 +1315,7 @@ juniper_parse_header(netdissect_options *ndo,
     l2info->caplen -= l2info->header_len;

     /* search through the cookie table and copy values matching for our PIC type */
+    ND_TCHECK(p[0]);
     while (lp->s != NULL) {
         if (lp->pictype == l2info->pictype) {

@@ -1360,6 +1396,7 @@ juniper_parse_header(netdissect_options *ndo,
     case DLT_JUNIPER_MLFR:
         switch (l2info->cookie_type) {
         case LS_COOKIE_ID:
+            ND_TCHECK2(p[0], 2);
             l2info->bundle = l2info->cookie[1];
             l2info->proto = EXTRACT_16BITS(p);
             l2info->header_len += 2;
@@ -1383,6 +1420,7 @@ juniper_parse_header(netdissect_options *ndo,
     case DLT_JUNIPER_MFR:
         switch (l2info->cookie_type) {
         case LS_COOKIE_ID:
+            ND_TCHECK2(p[0], 2);
             l2info->bundle = l2info->cookie[1];
             l2info->proto = EXTRACT_16BITS(p);
             l2info->header_len += 2;


CVE-2017-12897/ISO CLNS: Use ND_TTEST() for the bounds checks in isoclns_print().

This fixes a buffer over-read discovered by Kamil Frankowicz.

Don't pass the remaining caplen - that's too hard to get right, and we
were getting it wrong in at least one case; just use ND_TTEST().

Add a test using the capture file supplied by the reporter(s).

@@ -227,7 +227,7 @@ gre_print_0(netdissect_options *ndo, const u_char *bp, u_int length)
 		atalk_print(ndo, bp, len);
 		break;
 	case ETHERTYPE_GRE_ISO:
-		isoclns_print(ndo, bp, len, ndo->ndo_snapend - bp);
+		isoclns_print(ndo, bp, len);
 		break;
 	case ETHERTYPE_TEB:
 		ether_print(ndo, bp, len, ndo->ndo_snapend - bp, NULL, NULL);


CVE-2017-12900/Properly terminate all struct tok arrays.

This fixes a buffer over-read discovered by Forcepoint's security
researchers Otto Airamo & Antti Levomäki.

Add tests using the capture files supplied by the reporter(s).

@@ -76,7 +76,8 @@ static const struct tok z_types[] = {
     { Z_PACKET_SERVACK,		"serv-ack" },
     { Z_PACKET_SERVNAK,		"serv-nak" },
     { Z_PACKET_CLIENTACK,	"client-ack" },
-    { Z_PACKET_STAT,		"stat" }
+    { Z_PACKET_STAT,		"stat" },
+    { 0,			NULL }
 };

 static char z_buf[256];


CVE-2017-13007/PKTAP: Pass a properly updated struct pcap_pkthdr to the sub-dissector.

The sub-dissector expects that the length and captured length will
reflect the actual remaining data in the packet, not the raw amount
including the PKTAP header; pass an updated header, just as we do for
PPI.

This fixes a buffer over-read discovered by Yannick Formaggio.

Add a test using the capture file supplied by the reporter(s).

@@ -104,6 +104,7 @@ pktap_if_print(netdissect_options *ndo,
 	u_int length = h->len;
 	if_printer printer;
 	const pktap_header_t *hdr;
+	struct pcap_pkthdr nhdr;

 	if (caplen < sizeof(pktap_header_t) || length < sizeof(pktap_header_t)) {
 		ND_PRINT((ndo, "[|pktap]"));
@@ -144,7 +145,10 @@ pktap_if_print(netdissect_options *ndo,

 	case PKT_REC_PACKET:
 		if ((printer = lookup_printer(dlt)) != NULL) {
-			hdrlen += printer(ndo, h, p);
+			nhdr = *h;
+			nhdr.caplen = caplen;
+			nhdr.len = length;
+			hdrlen += printer(ndo, &nhdr, p);
 		} else {
 			if (!ndo->ndo_eflag)
 				pktap_header_print(ndo, (const u_char *)hdr,


CVE-2017-13029/PPP: Fix a bounds check, and clean up other bounds checks.

For configuration protocol options, use ND_TCHECK() and
ND_TCHECK_nBITS() macros, passing them the appropriate pointer argument.
This fixes one case where the ND_TCHECK2() call they replace was not
checking enough bytes.

This fixes a buffer over-read discovered by Bhargava Shastry,
SecT/TU Berlin.

Add a test using the capture file supplied by the reporter(s), modified
so the capture file won't be rejected as an invalid capture.

@@ -611,7 +611,7 @@ print_lcp_config_options(netdissect_options *ndo,
 			ND_PRINT((ndo, " (length bogus, should be >= 6)"));
 			return len;
 		}
-		ND_TCHECK2(*(p + 2), 3);
+		ND_TCHECK_24BITS(p + 2);
 		ND_PRINT((ndo, ": Vendor: %s (%u)",
 			tok2str(oui_values,"Unknown",EXTRACT_24BITS(p+2)),
 			EXTRACT_24BITS(p + 2)));
@@ -630,23 +630,23 @@ print_lcp_config_options(netdissect_options *ndo,
 			ND_PRINT((ndo, " (length bogus, should be = 4)"));
 			return len;
 		}
-		ND_TCHECK2(*(p + 2), 2);
+		ND_TCHECK_16BITS(p + 2);
 		ND_PRINT((ndo, ": %u", EXTRACT_16BITS(p + 2)));
 		break;
 	case LCPOPT_ACCM:
 		if (len != 6) {
 			ND_PRINT((ndo, " (length bogus, should be = 6)"));
 			return len;
 		}
-		ND_TCHECK2(*(p + 2), 4);
+		ND_TCHECK_32BITS(p + 2);
 		ND_PRINT((ndo, ": 0x%08x", EXTRACT_32BITS(p + 2)));
 		break;
 	case LCPOPT_AP:
 		if (len < 4) {
 			ND_PRINT((ndo, " (length bogus, should be >= 4)"));
 			return len;
 		}
-		ND_TCHECK2(*(p + 2), 2);
+		ND_TCHECK_16BITS(p + 2);
 		ND_PRINT((ndo, ": %s", tok2str(ppptype2str, "Unknown Auth Proto (0x04x)", EXTRACT_16BITS(p + 2))));

 		switch (EXTRACT_16BITS(p+2)) {
@@ -668,7 +668,7 @@ print_lcp_config_options(netdissect_options *ndo,
 			ND_PRINT((ndo, " (length bogus, should be >= 4)"));
 			return 0;
 		}
-		ND_TCHECK2(*(p + 2), 2);
+		ND_TCHECK_16BITS(p+2);
 		if (EXTRACT_16BITS(p+2) == PPP_LQM)
 			ND_PRINT((ndo, ": LQR"));
 		else
@@ -679,7 +679,7 @@ print_lcp_config_options(netdissect_options *ndo,
 			ND_PRINT((ndo, " (length bogus, should be = 6)"));
 			return 0;
 		}
-		ND_TCHECK2(*(p + 2), 4);
+		ND_TCHECK_32BITS(p + 2);
 		ND_PRINT((ndo, ": 0x%08x", EXTRACT_32BITS(p + 2)));
 		break;
 	case LCPOPT_PFC:
@@ -691,7 +691,7 @@ print_lcp_config_options(netdissect_options *ndo,
 			ND_PRINT((ndo, " (length bogus, should be = 4)"));
 			return 0;
 		}
-		ND_TCHECK2(*(p + 2), 2);
+		ND_TCHECK_16BITS(p + 2);
 		ND_PRINT((ndo, ": 0x%04x", EXTRACT_16BITS(p + 2)));
 		break;
 	case LCPOPT_CBACK:
@@ -710,7 +710,7 @@ print_lcp_config_options(netdissect_options *ndo,
 			ND_PRINT((ndo, " (length bogus, should be = 4)"));
 			return 0;
 		}
-		ND_TCHECK2(*(p + 2), 2);
+		ND_TCHECK_16BITS(p + 2);
 		ND_PRINT((ndo, ": %u", EXTRACT_16BITS(p + 2)));
 		break;
 	case LCPOPT_MLED:
@@ -1055,7 +1055,7 @@ print_ipcp_config_options(netdissect_options *ndo,
 			ND_PRINT((ndo, " (length bogus, should be >= 4)"));
 			return 0;
 		}
-		ND_TCHECK2(*(p + 2), 2);
+		ND_TCHECK_16BITS(p+2);
 		compproto = EXTRACT_16BITS(p+2);

 		ND_PRINT((ndo, ": %s (0x%02x):",
@@ -1241,7 +1241,7 @@ print_ccp_config_options(netdissect_options *ndo,
 			ND_PRINT((ndo, " (length bogus, should be >= 3)"));
 			return len;
 		}
-		ND_TCHECK2(*(p + 2), 1);
+		ND_TCHECK(p[2]);
 		ND_PRINT((ndo, ": Version: %u, Dictionary Bits: %u",
 			p[2] >> 5, p[2] & 0x1f));
 		break;
@@ -1250,7 +1250,7 @@ print_ccp_config_options(netdissect_options *ndo,
 			ND_PRINT((ndo, " (length bogus, should be >= 4)"));
 			return len;
 		}
-		ND_TCHECK2(*(p + 2), 1);
+		ND_TCHECK(p[3]);
 		ND_PRINT((ndo, ": Features: %u, PxP: %s, History: %u, #CTX-ID: %u",
 				(p[2] & 0xc0) >> 6,
 				(p[2] & 0x20) ? "Enabled" : "Disabled",
@@ -1261,7 +1261,7 @@ print_ccp_config_options(netdissect_options *ndo,
 			ND_PRINT((ndo, " (length bogus, should be >= 4)"));
 			return len;
 		}
-		ND_TCHECK2(*(p + 2), 1);
+		ND_TCHECK(p[3]);
 		ND_PRINT((ndo, ": Window: %uK, Method: %s (0x%x), MBZ: %u, CHK: %u",
 			(p[2] & 0xf0) >> 4,
 			((p[2] & 0x0f) == 8) ? "zlib" : "unknown",
@@ -1336,7 +1336,7 @@ print_bacp_config_options(netdissect_options *ndo,
 			ND_PRINT((ndo, " (length bogus, should be = 6)"));
 			return len;
 		}
-		ND_TCHECK2(*(p + 2), 4);
+		ND_TCHECK_32BITS(p + 2);
 		ND_PRINT((ndo, ": Magic-Num 0x%08x", EXTRACT_32BITS(p + 2)));
 		break;
 	default:


CVE-2017-13048/RSVP: fix decoding of Fast Reroute objects

In rsvp_obj_print() the case block for Class-Num 205 (FAST_REROUTE) from
RFC 4090 Section 4.1 could over-read accessing the buffer contents before
making the bounds check. Rearrange those steps the correct way around.

This fixes a buffer over-read discovered by Bhargava Shastry,
SecT/TU Berlin.

Add a test using the capture file supplied by the reporter(s).

@@ -1472,12 +1472,12 @@ rsvp_obj_print(netdissect_options *ndo,
         case RSVP_OBJ_FASTREROUTE:
             /* the differences between c-type 1 and 7 are minor */
             obj_ptr.rsvp_obj_frr = (const struct rsvp_obj_frr_t *)obj_tptr;
-            bw.i = EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->bandwidth);

             switch(rsvp_obj_ctype) {
             case RSVP_CTYPE_1: /* new style */
                 if (obj_tlen < sizeof(struct rsvp_obj_frr_t))
                     return-1;
+                bw.i = EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->bandwidth);
                 ND_PRINT((ndo, "%s  Setup Priority: %u, Holding Priority: %u, Hop-limit: %u, Bandwidth: %.10g Mbps",
                        ident,
                        (int)obj_ptr.rsvp_obj_frr->setup_prio,
@@ -1496,6 +1496,7 @@ rsvp_obj_print(netdissect_options *ndo,
             case RSVP_CTYPE_TUNNEL_IPV4: /* old style */
                 if (obj_tlen < 16)
                     return-1;
+                bw.i = EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->bandwidth);
                 ND_PRINT((ndo, "%s  Setup Priority: %u, Holding Priority: %u, Hop-limit: %u, Bandwidth: %.10g Mbps",
                        ident,
                        (int)obj_ptr.rsvp_obj_frr->setup_prio,


CVE-2017-12898/NFS: Fix bounds checking.

Fix the bounds checking for the NFSv3 WRITE procedure to check whether the
length of the opaque data being written is present in the captured data,
not just whether the byte count is present in the captured data.
furthest forward in the packet, not the item before it.  (This also lets
us eliminate the check for the "stable" argument being present in the
captured data; rewrite the code to print that to make it a bit clearer.)

Check that the entire ar_stat field is present in the capture.

Note that parse_wcc_attr() is called after we've already checked whether
the wcc_data is present.

Check before fetching the "access" part of the NFSv3 ACCESS results.
This fixes a buffer over-read discovered by Kamil Frankowicz.

Include a test for the "check before fetching the "access" part..." fix,
using the capture supplied by the reporter(s).

@@ -628,17 +628,15 @@ nfsreq_print_noaddr(netdissect_options *ndo,
 		if ((dp = parsereq(ndo, rp, length)) != NULL &&
 		    (dp = parsefh(ndo, dp, v3)) != NULL) {
 			if (v3) {
-				ND_TCHECK(dp[2]);
+				ND_TCHECK(dp[4]);
 				ND_PRINT((ndo, " %u (%u) bytes @ %" PRIu64,
 						EXTRACT_32BITS(&dp[4]),
 						EXTRACT_32BITS(&dp[2]),
 						EXTRACT_64BITS(&dp[0])));
 				if (ndo->ndo_vflag) {
-					dp += 3;
-					ND_TCHECK(dp[0]);
 					ND_PRINT((ndo, " <%s>",
 						tok2str(nfsv3_writemodes,
-							NULL, EXTRACT_32BITS(dp))));
+							NULL, EXTRACT_32BITS(&dp[3]))));
 				}
 			} else {
 				ND_TCHECK(dp[3]);
@@ -1002,11 +1000,11 @@ parserep(netdissect_options *ndo,
 	 * skip past the ar_verf credentials.
 	 */
 	dp += (len + (2*sizeof(uint32_t) + 3)) / sizeof(uint32_t);
-	ND_TCHECK2(dp[0], 0);

 	/*
 	 * now we can check the ar_stat field
 	 */
+	ND_TCHECK(dp[0]);
 	astat = (enum sunrpc_accept_stat) EXTRACT_32BITS(dp);
 	if (astat != SUNRPC_SUCCESS) {
 		ND_PRINT((ndo, " %s", tok2str(sunrpc_str, "ar_stat %d", astat)));
@@ -1243,6 +1241,7 @@ static const uint32_t *
 parse_wcc_attr(netdissect_options *ndo,
                const uint32_t *dp)
 {
+	/* Our caller has already checked this */
 	ND_PRINT((ndo, " sz %" PRIu64, EXTRACT_64BITS(&dp[0])));
 	ND_PRINT((ndo, " mtime %u.%06u ctime %u.%06u",
 	       EXTRACT_32BITS(&dp[2]), EXTRACT_32BITS(&dp[3]),
@@ -1511,8 +1510,10 @@ interp_reply(netdissect_options *ndo,
 			ND_PRINT((ndo, " attr:"));
 		if (!(dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag)))
 			break;
-		if (!er)
+		if (!er) {
+			ND_TCHECK(dp[0]);
 			ND_PRINT((ndo, " c %04x", EXTRACT_32BITS(&dp[0])));
+		}
 		return;

 	case NFSPROC_READLINK:


CVE-2017-13010/BEEP: Do bounds checking when comparing strings.

This fixes a buffer over-read discovered by Brian 'geeknik' Carpenter.

Add a test using the capture file supplied by the reporter(s).

@@ -28,9 +28,17 @@
  */

 static int
-l_strnstart(const char *tstr1, u_int tl1, const char *str2, u_int l2)
+l_strnstart(netdissect_options *ndo, const char *tstr1, u_int tl1,
+    const char *str2, u_int l2)
 {
-
+	if (!ND_TTEST2(*str2, tl1)) {
+		/*
+		 * We don't have tl1 bytes worth of captured data
+		 * for the string, so we can't check for this
+		 * string.
+		 */
+		return 0;
+	}
 	if (tl1 > l2)
 		return 0;

@@ -41,19 +49,19 @@ void
 beep_print(netdissect_options *ndo, const u_char *bp, u_int length)
 {

-	if (l_strnstart("MSG", 4, (const char *)bp, length)) /* A REQuest */
+	if (l_strnstart(ndo, "MSG", 4, (const char *)bp, length)) /* A REQuest */
 		ND_PRINT((ndo, " BEEP MSG"));
-	else if (l_strnstart("RPY ", 4, (const char *)bp, length))
+	else if (l_strnstart(ndo, "RPY ", 4, (const char *)bp, length))
 		ND_PRINT((ndo, " BEEP RPY"));
-	else if (l_strnstart("ERR ", 4, (const char *)bp, length))
+	else if (l_strnstart(ndo, "ERR ", 4, (const char *)bp, length))
 		ND_PRINT((ndo, " BEEP ERR"));
-	else if (l_strnstart("ANS ", 4, (const char *)bp, length))
+	else if (l_strnstart(ndo, "ANS ", 4, (const char *)bp, length))
 		ND_PRINT((ndo, " BEEP ANS"));
-	else if (l_strnstart("NUL ", 4, (const char *)bp, length))
+	else if (l_strnstart(ndo, "NUL ", 4, (const char *)bp, length))
 		ND_PRINT((ndo, " BEEP NUL"));
-	else if (l_strnstart("SEQ ", 4, (const char *)bp, length))
+	else if (l_strnstart(ndo, "SEQ ", 4, (const char *)bp, length))
 		ND_PRINT((ndo, " BEEP SEQ"));
-	else if (l_strnstart("END", 4, (const char *)bp, length))
+	else if (l_strnstart(ndo, "END", 4, (const char *)bp, length))
 		ND_PRINT((ndo, " BEEP END"));
 	else
 		ND_PRINT((ndo, " BEEP (payload or undecoded)"));


CVE-2017-13042/HNCP: add DHCPv6-Data bounds checks

hncp_print_rec() validates each HNCP TLV to be within the declared as
well as the on-the-wire packet space. However, dhcpv6_print() in the same
file didn't do the same for the DHCPv6 options within the HNCP
DHCPv6-Data TLV value, which could cause an out-of-bounds read when
decoding an invalid packet. Add missing checks to dhcpv6_print().

This fixes a buffer over-read discovered by Bhargava Shastry,
SecT/TU Berlin.

Add a test using the capture file supplied by the reporter(s).

@@ -318,6 +318,8 @@ dhcpv6_print(netdissect_options *ndo,

     i = 0;
     while (i < length) {
+        if (i + 4 > length)
+            return -1;
         tlv = cp + i;
         type = EXTRACT_16BITS(tlv);
         optlen = EXTRACT_16BITS(tlv + 2);
@@ -329,6 +331,8 @@ dhcpv6_print(netdissect_options *ndo,

         ND_PRINT((ndo, "%s", tok2str(dh6opt_str, "Unknown", type)));
         ND_PRINT((ndo," (%u)", optlen + 4 ));
+        if (i + 4 + optlen > length)
+            return -1;

         switch (type) {
             case DH6OPT_DNS_SERVERS:


CVE-2017-13016/ES-IS: Fix printing of addresses in RD PDUs.

Always print the SNPA, and flag it as such; only print it as a MAC
address if it's 6 bytes long.

Identify the NET as such.

This fixes a buffer over-read discovered by Bhargava Shastry,
SecT/TU Berlin.

Add tests using the capture files supplied by the reporter(s), modified
so the capture files won't be rejected as an invalid capture.

@@ -33,7 +33,8 @@ enum {
     LINKADDR_ETHER,
     LINKADDR_FRELAY,
     LINKADDR_IEEE1394,
-    LINKADDR_ATM
+    LINKADDR_ATM,
+    LINKADDR_OTHER
 };

 #define BUFSIZE 128


Preserve GSS context on init/accept failure

After gss_init_sec_context() or gss_accept_sec_context() has created a
context, don't delete the mechglue context on failures from subsequent
calls, even if the mechanism deletes the mech-specific context (which
is allowed by RFC 2744 but not preferred).  Check for union contexts
with no mechanism context in each GSS function which accepts a
gss_ctx_id_t.

CVE-2017-11462:

RFC 2744 permits a GSS-API implementation to delete an existing
security context on a second or subsequent call to
gss_init_sec_context() or gss_accept_sec_context() if the call results
in an error.  This API behavior has been found to be dangerous,
leading to the possibility of memory errors in some callers.  For
safety, GSS-API implementations should instead preserve existing
security contexts on error until the caller deletes them.

All versions of MIT krb5 prior to this change may delete acceptor
contexts on error.  Versions 1.13.4 through 1.13.7, 1.14.1 through
1.14.5, and 1.15 through 1.15.1 may also delete initiator contexts on
error.

ticket: 8598 (new)
target_version: 1.15-next
target_version: 1.14-next
tags: pullup

@@ -61,6 +61,8 @@ gss_buffer_t		token_buffer;
      */

     ctx = (gss_union_ctx_id_t) context_handle;
+    if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT)
+	return (GSS_S_NO_CONTEXT);
     mech = gssint_get_mechanism (ctx->mech_type);

     if (mech) {