Hello!
Upstream developers of ImageMagick6 fixed CVE-2023-34151 for mvg after all.
See more info here:
https://github.com/ImageMagick/ImageMagick/issues/6341#issuecomment-2108156142

I discovered final list of commits fixing problem:
-
https://github.com/ImageMagick/ImageMagick6/commit/75ebd9975f6ba8106ec15a6b3e6ba95f4c14e117
-
https://github.com/ImageMagick/ImageMagick6/commit/b72508c8fce196cd031856574c202490be830649
-
https://github.com/ImageMagick/ImageMagick6/commit/88789966667b748f14a904f8c9122274810e8a3e
-
https://github.com/ImageMagick/ImageMagick6/commit/bc5ac19bd93895e5c6158aad0d8e49a0c50b0ebb
-
https://github.com/ImageMagick/ImageMagick6/commit/3252d4771ff1142888ba83c439588969fcea98e4
-
https://github.com/ImageMagick/ImageMagick6/commit/be15ac962dea19536be1009d157639030fc42be9

And this is also useful to make applying of these commits to version
from Debian Buster easier:
-
https://github.com/ImageMagick/ImageMagick6/commit/be15ac962dea19536be1009d157639030fc42be9

I squoshed them, slightly adopted to make applicable to target version of
imagemagick and finally prepared this patch suitable for
imagemagick_6.9.10.23+dfsg-2.1+deb10u7 from Debian Buster:
https://pastila.nl/?001caded/fa33173a3374db4c55ab654d3e75d668#ZqwgZatwpOmWAtcWUs6QAA==

I checked, that after application of this patch to
imagemagick_6.9.10.23+dfsg-2.1+deb10u7 bug CVE-2023-34151 is not
reproducible - there is no error "runtime error: 5e+26 is outside the range
of representable values of type 'long unsigned int'" with file piechart.mvg.

Hope my patch compiled from commits from upstream will be helpful.
From 52a457fa7b6d181f030101b5719bac133fcb721c Mon Sep 17 00:00:00 2001
From: Sergei Semin <syominser...@gmail.com>
Date: Tue, 14 May 2024 01:13:36 +0300
Subject: [PATCH] fix CVE-2023-34151 for mvg

---
 coders/mvg.c           |  8 ++++----
 magick/image-private.h | 35 +++++++++++++++++++++++++----------
 2 files changed, 29 insertions(+), 14 deletions(-)

diff --git a/coders/mvg.c b/coders/mvg.c
index 18086b2..2f0f0ba 100644
--- a/coders/mvg.c
+++ b/coders/mvg.c
@@ -177,8 +177,8 @@ static Image *ReadMVGImage(const ImageInfo *image_info,ExceptionInfo *exception)
           continue;
         (void) sscanf(p,"viewbox %lf %lf %lf %lf",&bounds.x1,&bounds.y1,
           &bounds.x2,&bounds.y2);
-        image->columns=(size_t) floor((bounds.x2-bounds.x1)+0.5);
-        image->rows=(size_t) floor((bounds.y2-bounds.y1)+0.5);
+        image->columns=CastDoubleToUnsigned(floor((bounds.x2-bounds.x1)+0.5));
+        image->rows=CastDoubleToUnsigned(floor((bounds.y2-bounds.y1)+0.5));
         break;
       }
     }
@@ -191,8 +191,8 @@ static Image *ReadMVGImage(const ImageInfo *image_info,ExceptionInfo *exception)
     96.0;
   draw_info->affine.sy=image->y_resolution == 0.0 ? 1.0 : image->y_resolution/
     96.0;
-  image->columns=(size_t) (draw_info->affine.sx*image->columns);
-  image->rows=(size_t) (draw_info->affine.sy*image->rows);
+  image->columns=CastDoubleToUnsigned(draw_info->affine.sx*image->columns);
+  image->rows=CastDoubleToUnsigned(draw_info->affine.sy*image->rows);
   status=SetImageExtent(image,image->columns,image->rows);
   if (status == MagickFalse)
     {
diff --git a/magick/image-private.h b/magick/image-private.h
index 5fdbf59..d9cd46f 100644
--- a/magick/image-private.h
+++ b/magick/image-private.h
@@ -62,42 +62,57 @@ extern MagickExport const double

 static inline size_t CastDoubleToUnsigned(const double x)
 {
+  double
+    value;
+
   if (IsNaN(x) != 0)
     {
       errno=ERANGE;
       return(0);
     }
-  if (floor(x) > ((double) MAGICK_SSIZE_MAX-1))
+  value=floor(x);
+  if (value >= ((double) MAGICK_SIZE_MAX))
     {
       errno=ERANGE;
       return((size_t) MAGICK_SIZE_MAX);
     }
-  if (ceil(x) < 0.0)
+  if (value < 0.0)
     {
       errno=ERANGE;
       return(0);
     }
-  return((size_t) x);
+  return((size_t) value);
 }

 static inline ssize_t CastDoubleToLong(const double x)
 {
+  double
+    value;
+
   if (IsNaN(x) != 0)
     {
       errno=ERANGE;
       return(0);
     }
-  if (floor(x) > ((double) MAGICK_SSIZE_MAX-1))
+  if (x < 0.0)
     {
-      errno=ERANGE;
-      return((ssize_t) MAGICK_SSIZE_MAX);
+      value=ceil(x);
+      if (value < ((double) MAGICK_SSIZE_MIN))
+        {
+          errno=ERANGE;
+          return((ssize_t) MAGICK_SSIZE_MIN);
+        }
     }
-  if (ceil(x) < ((double) MAGICK_SSIZE_MIN+1))
+  else
     {
-      errno=ERANGE;
-      return((ssize_t) MAGICK_SSIZE_MIN);
+      value=floor(x);
+      if (value > ((double) MAGICK_SSIZE_MAX))
+        {
+          errno=ERANGE;
+          return((ssize_t) MAGICK_SSIZE_MAX);
+        }
     }
-  return((ssize_t) x);
+  return((ssize_t) value);
 }

 static inline double DegreesToRadians(const double degrees)
--
2.30.2

Reply via email to