CVE-2022-1325 (published 2022-08-31T16:15Z)

A flaw was found in Clmg, where with the help of a maliciously crafted pandore or bmp file with modified dx and dy header field values it is possible to trick the application into allocating huge buffer sizes like 64 Gigabyte upon reading the file from disk or from a virtual buffer.

CVSS v3 base score: 5.5, MEDIUM (CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H)

Weakness information:
cwe_id: CWE-770
cwe_name: Allocation of Resources Without Limits or Throttling
description: The product allocates a reusable resource or group of resources on behalf of an actor without imposing any restrictions on the size or number of resources that can be allocated, in violation of the intended security policy for that actor.
extended_description: Code frequently has to work with limited resources, so programmers must be careful to ensure that resources are not consumed too quickly, or too easily.  Without use of quotas, resource limits, or other protection mechanisms, it can be easy for an attacker to consume many resources by rapidly making many requests, or causing larger resources to be used than is needed. When too many resources are allocated, or if a single resource is too large, then it can prevent the code from working correctly, possibly leading to a denial of service.
         

Fix information:
repo_url: https://github.com/GreycLab/CImg
commit_details: repo_url: https://github.com/GreycLab/CImg
author: David Tschumperle
author_date: 2022-04-07 12:43:39+02:00
msg: CImg<>::load_bmp() and CImg<>::load_pandore(): Check that dimensions encoded in file does not exceed file size.
repository: repo_url: https://github.com/GreycLab/CImg
repo_name: GreycLab/CImg
description: The CImg Library is a small and open-source C++ toolkit for image processing
repo_language: C++
owner: GreycLab
file_changes: filename: CImg.h
change_type: ModificationType.MODIFY
diff: @@ -53184,6 +53184,7 @@ namespace cimg_library_suffixed {
                                     "load_bmp(): Specified filename is (null).",
                                     cimg_instance);
 
+      const ulongT fsiz = file?cimg::type<ulongT>::max():(ulongT)cimg::fsize(filename);
       std::FILE *const nfile = file?file:cimg::fopen(filename,"rb");
       CImg<ucharT> header(54);
       cimg::fread(header._data,54,nfile);
@@ -53220,6 +53221,12 @@ namespace cimg_library_suffixed {
         cimg_iobuffer = (ulongT)24*1024*1024,
         buf_size = (ulongT)cimg::abs(dy)*(dx_bytes + align_bytes);
 
+      if (buf_size>fsiz)
+          throw CImgIOException(_cimg_instance
+                                "load_bmp(): File size %lu for filename '%s' does not match encoded image dimensions (%d,%d).",
+                                cimg_instance,
+                                (long)fsiz,filename?filename:"(FILE*)",dx,dy);
+
       CImg<intT> colormap;
       if (bpp<16) { if (!nb_colors) nb_colors = 1<<bpp; } else nb_colors = 0;
       if (nb_colors) { colormap.assign(nb_colors); cimg::fread(colormap._data,nb_colors,nfile); }
@@ -55026,6 +55033,11 @@ namespace cimg_library_suffixed {
 #define __cimg_load_pandore_case(nbdim,nwidth,nheight,ndepth,ndim,stype) \
         cimg::fread(dims,nbdim,nfile); \
         if (endian) cimg::invert_endianness(dims,nbdim); \
+        if ((ulongT)nwidth*nheight*ndepth*ndim>fsiz) \
+          throw CImgIOException(_cimg_instance \
+                                "load_pandore(): File size %lu for filename '%s' does not match encoded image dimensions (%d,%d,%d,%d).",\
+                                cimg_instance,\
+                                (long)fsiz,filename?filename:"(FILE*)",(int)nwidth,(int)nheight,(int)ndepth,(int)ndim); \
         assign(nwidth,nheight,ndepth,ndim); \
         const size_t siz = size(); \
         stype *buffer = new stype[siz]; \
@@ -55049,6 +55061,7 @@ namespace cimg_library_suffixed {
                                     "load_pandore(): Specified filename is (null).",
                                     cimg_instance);
 
+      const ulongT fsiz = file?cimg::type<ulongT>::max():(ulongT)cimg::fsize(filename);
       std::FILE *const nfile = file?file:cimg::fopen(filename,"rb");
       CImg<charT> header(32);
       cimg::fread(header._data,12,nfile);

programming_language: C++