Low firefox Logic Error 🔧 Commit mapped

Overview

Low
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
Impactlow
DescriptionDenial-of-service in the Graphics: ImageLib component
ComponentMedia
Bug ClassLogic Error
Tracker2039443
Fix commit20eeca1fd1d5 (firefox) +40/-38
CISA KEVNot listed
CreditedSecurin
Disclosed2026-06-16

Files Changed

  • media/libpng/apng.patch
  • media/libpng/pngpread.c
diff --git a/media/libpng/apng.patch b/media/libpng/apng.patch
index 10fc0184851..a06964f0d37 100644
--- a/media/libpng/apng.patch
+++ b/media/libpng/apng.patch
@@ -132,7 +132,7 @@ diff --git a/png.h b/png.h
 diff --git a/pngget.c b/pngget.c
 --- a/pngget.c
 +++ b/pngget.c
-@@ -1367,4 +1367,166 @@ png_get_palette_max(png_const_structp pn
+@@ -1366,4 +1366,166 @@ png_get_palette_max(png_const_structp pn
  #  endif
  #endif
  
@@ -324,7 +324,7 @@ diff --git a/pnginfo.h b/pnginfo.h
 diff --git a/pngpread.c b/pngpread.c
 --- a/pngpread.c
 +++ b/pngpread.c
-@@ -200,6 +200,89 @@ png_push_read_chunk(png_structrp png_ptr
+@@ -200,6 +200,90 @@ png_push_read_chunk(png_structrp png_ptr
  
     chunk_name = png_ptr->chunk_name;
  
@@ -346,9 +346,6 @@ diff --git a/pngpread.c b/pngpread.c
 +
 +      else if (chunk_name == png_fdAT)
 +      {
-+         PNG_PUSH_SAVE_BUFFER_IF_LT(4)
-+         png_ensure_sequence_number(png_ptr, 4);
-+
 +         if ((png_ptr->mode & PNG_HAVE_fcTL) == 0)
 +         {
 +            /* Discard trailing fdATs for frames other than the first */
@@ -356,13 +353,17 @@ diff --git a/pngpread.c b/pngpread.c
 +               png_error(png_ptr, "out of place fdAT");
 +
 +            PNG_PUSH_SAVE_BUFFER_IF_FULL
-+            png_crc_finish(png_ptr, png_ptr->push_length);
++            png_ensure_sequence_number(png_ptr, png_ptr->push_length);
++            png_crc_finish(png_ptr, png_ptr->push_length - 4);
 +            png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
 +         }
 +
 +         else
 +         {
 +            /* frame data follows */
++            PNG_PUSH_SAVE_BUFFER_IF_LT(4)
++
++            png_ensure_sequence_number(png_ptr, png_ptr->push_length);
 +            png_ptr->idat_size = png_ptr->push_length - 4;
 +            png_ptr->mode |= PNG_HAVE_IDAT;
 +            png_ptr->process_mode = PNG_READ_IDAT_MODE;
@@ -414,7 +415,7 @@ diff --git a/pngpread.c b/pngpread.c
     if (chunk_name == png_IDAT)
     {
        if ((png_ptr->mode & PNG_AFTER_IDAT) != 0)
-@@ -260,6 +343,9 @@ png_push_read_chunk(png_structrp png_ptr
+@@ -268,6 +352,9 @@ png_push_read_chunk(png_structrp png_ptr
  
     else if (chunk_name == png_IDAT)
     {
@@ -424,7 +425,7 @@ diff --git a/pngpread.c b/pngpread.c
        png_ptr->idat_size = png_ptr->push_length;
        png_ptr->process_mode = PNG_READ_IDAT_MODE;
        png_push_have_info(png_ptr, info_ptr);
-@@ -270,6 +356,20 @@ png_push_read_chunk(png_structrp png_ptr
+@@ -278,6 +365,20 @@ png_push_read_chunk(png_structrp png_ptr
        return;
     }
  
@@ -445,7 +446,7 @@ diff --git a/pngpread.c b/pngpread.c
     else
     {
        PNG_PUSH_SAVE_BUFFER_IF_FULL
-@@ -401,7 +501,11 @@ png_push_read_IDAT(png_structrp png_ptr)
+@@ -409,7 +510,11 @@ png_push_read_IDAT(png_structrp png_ptr)
        png_byte chunk_tag[4];
  
        /* TODO: this code can be commoned up with the same code in push_read */
@@ -457,7 +458,7 @@ diff --git a/pngpread.c b/pngpread.c
        png_push_fill_buffer(png_ptr, chunk_length, 4);
        png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
        png_reset_crc(png_ptr);
-@@ -409,17 +513,60 @@ png_push_read_IDAT(png_structrp png_ptr)
+@@ -417,17 +522,60 @@ png_push_read_IDAT(png_structrp png_ptr)
        png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
        png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
  
@@ -511,14 +512,14 @@ diff --git a/pngpread.c b/pngpread.c
 +#ifdef PNG_READ_APNG_SUPPORTED
 +      if (png_ptr->num_frames_read > 0)
 +      {
-+         png_ensure_sequence_number(png_ptr, 4);
++         png_ensure_sequence_number(png_ptr, png_ptr->push_length);
 +         png_ptr->idat_size -= 4;
 +      }
 +#endif
     }
  
     if (png_ptr->idat_size != 0 && png_ptr->save_buffer_size != 0)
-@@ -493,6 +640,16 @@ png_process_IDAT_data(png_structrp png_p
+@@ -501,6 +649,16 @@ png_process_IDAT_data(png_structrp png_p
     if (!(buffer_length > 0) || buffer == NULL)
        png_error(png_ptr, "No IDAT data (internal error)");
  
@@ -535,7 +536,7 @@ diff --git a/pngpread.c b/pngpread.c
     /* This routine must process all the data it has been given
      * before returning, calling the row callback as required to
      * handle the uncompressed results.
-@@ -926,6 +1083,18 @@ png_set_progressive_read_fn(png_structrp
+@@ -934,6 +1092,18 @@ png_set_progressive_read_fn(png_structrp
     png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
  }
  
@@ -557,7 +558,7 @@ diff --git a/pngpread.c b/pngpread.c
 diff --git a/pngpriv.h b/pngpriv.h
 --- a/pngpriv.h
 +++ b/pngpriv.h
-@@ -620,6 +620,10 @@
+@@ -653,6 +653,10 @@
  #define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000U /* Have another chunk after IDAT */
  #define PNG_WROTE_eXIf            0x4000U
  #define PNG_IS_READ_STRUCT        0x8000U /* Else is a write struct */
@@ -568,7 +569,7 @@ diff --git a/pngpriv.h b/pngpriv.h
  
  /* Flags for the transformations the PNG library does on the image data */
  #define PNG_BGR                 0x0001U
-@@ -884,6 +888,16 @@
+@@ -917,6 +921,16 @@
  #define png_tRNS PNG_U32(116,  82,  78,  83)
  #define png_zTXt PNG_U32(122,  84,  88, 116)
  
@@ -585,8 +586,8 @@ diff --git a/pngpriv.h b/pngpriv.h
  /* The following will work on (signed char*) strings, whereas the get_uint_32
   * macro will fail on top-bit-set values because of the sign extension.
   */
-@@ -1671,6 +1685,49 @@ PNG_INTERNAL_FUNCTION(void,png_read_push
-     PNG_EMPTY);
+@@ -1880,6 +1894,49 @@ PNG_INTERNAL_FUNCTION(void, png_read_pus
+    PNG_EMPTY);
  #endif /* PROGRESSIVE_READ */
  
 +#ifdef PNG_APNG_SUPPORTED
@@ -638,7 +639,7 @@ diff --git a/pngpriv.h b/pngpriv.h
 diff --git a/pngread.c b/pngread.c
 --- a/pngread.c
 +++ b/pngread.c
-@@ -155,16 +155,96 @@ png_read_info(png_structrp png_ptr, png_
+@@ -157,16 +157,96 @@ png_read_info(png_structrp png_ptr, png_
  
        else if (chunk_name == png_IDAT)
        {
@@ -750,7 +751,7 @@ diff --git a/pngrutil.c b/pngrutil.c
     /* Set internal variables */
     png_ptr->width = width;
     png_ptr->height = height;
-@@ -2730,6 +2735,180 @@ png_handle_iTXt(png_structrp png_ptr, pn
+@@ -2706,6 +2711,180 @@ png_handle_iTXt(png_structrp png_ptr, pn
  #  define png_handle_iTXt NULL
  #endif
  
@@ -931,7 +932,7 @@ diff --git a/pngrutil.c b/pngrutil.c
  #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
  /* Utility function for png_handle_unknown; set up png_ptr::unknown_chunk */
  static int
-@@ -4213,6 +4392,38 @@ png_read_IDAT_data(png_structrp png_ptr,
+@@ -4189,6 +4368,38 @@ png_read_IDAT_data(png_structrp png_ptr,
           uInt avail_in;
           png_bytep buffer;
  
@@ -970,7 +971,7 @@ diff --git a/pngrutil.c b/pngrutil.c
           while (png_ptr->idat_size == 0)
           {
              png_crc_finish(png_ptr, 0);
-@@ -4224,6 +4435,7 @@ png_read_IDAT_data(png_structrp png_ptr,
+@@ -4200,6 +4411,7 @@ png_read_IDAT_data(png_structrp png_ptr,
              if (png_ptr->chunk_name != png_IDAT)
                 png_error(png_ptr, "Not enough image data");
           }
@@ -978,7 +979,7 @@ diff --git a/pngrutil.c b/pngrutil.c
  
           avail_in = png_ptr->IDAT_read_size;
  
-@@ -4295,6 +4507,9 @@ png_read_IDAT_data(png_structrp png_ptr,
+@@ -4271,6 +4483,9 @@ png_read_IDAT_data(png_structrp png_ptr,
  
           png_ptr->mode |= PNG_AFTER_IDAT;
           png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
@@ -988,7 +989,7 @@ diff --git a/pngrutil.c b/pngrutil.c
  
           if (png_ptr->zstream.avail_in > 0 || png_ptr->idat_size > 0)
              png_chunk_benign_error(png_ptr, "Extra compressed data");
-@@ -4704,4 +4919,80 @@ defined(PNG_USER_TRANSFORM_PTR_SUPPORTED
+@@ -4680,4 +4895,80 @@ defined(PNG_USER_TRANSFORM_PTR_SUPPORTED
  
     png_ptr->flags |= PNG_FLAG_ROW_INIT;
  }
@@ -1072,7 +1073,7 @@ diff --git a/pngrutil.c b/pngrutil.c
 diff --git a/pngset.c b/pngset.c
 --- a/pngset.c
 +++ b/pngset.c
Loading diff…