Version in base suite: 7.1.1.43+dfsg1-1+deb13u8 Version in overlay suite: 7.1.1.43+dfsg1-1+deb13u9 Base version: imagemagick_7.1.1.43+dfsg1-1+deb13u9 Target version: imagemagick_7.1.1.43+dfsg1-1+deb13u10 Base file: /srv/ftp-master.debian.org/ftp/pool/main/i/imagemagick/imagemagick_7.1.1.43+dfsg1-1+deb13u9.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/i/imagemagick/imagemagick_7.1.1.43+dfsg1-1+deb13u10.dsc changelog | 34 ++ control | 2 patches/0005-Add-a-debian-policy.patch | 37 +-- patches/CVE-2026-48724.patch | 32 ++ patches/CVE-2026-48734.patch | 41 +++ patches/CVE-2026-48994.patch | 45 +++ patches/CVE-2026-49218.patch | 26 ++ patches/CVE-2026-49219.patch | 359 +++++++++++++++++++++++++++++++ patches/CVE-2026-53460.patch | 27 ++ patches/CVE-2026-53461.patch | 28 ++ patches/CVE-2026-53463.patch | 37 +++ patches/CVE-2026-53464.patch | 32 ++ patches/series | 9 rules | 5 tests.d/control.quantum.in | 4 tests.d/policy-IMVERSION.QUANTUMDEPTH.in | 38 +++ tests/control | 8 tests/policy-7.q16 | 38 +++ tests/policy-7.q16hdri | 38 +++ 19 files changed, 820 insertions(+), 20 deletions(-) dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmpqdesomn1/imagemagick_7.1.1.43+dfsg1-1+deb13u9.dsc: no acceptable signature found dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmpqdesomn1/imagemagick_7.1.1.43+dfsg1-1+deb13u10.dsc: no acceptable signature found diff -Nru imagemagick-7.1.1.43+dfsg1/debian/changelog imagemagick-7.1.1.43+dfsg1/debian/changelog --- imagemagick-7.1.1.43+dfsg1/debian/changelog 2026-05-24 16:01:44.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/changelog 2026-06-20 11:35:39.000000000 +0000 @@ -1,3 +1,37 @@ +imagemagick (8:7.1.1.43+dfsg1-1+deb13u10) trixie-security; urgency=high + + * Fix CVE-2026-48724: + When using an image with mask the Floyd-Steinberg dithering + method it will cause a negative heap buffer over-write + * Fix CVE-2026-48734: + A crafted MVG file could result in a stack overflow due to a missing depth + or visited-set check + * Fix CVE-2026-48994: + A missing check of a return value could lead to a heap buffer over-write in the MAT + decoder on 32-bit systems. + * Fix CVE-2026-49218: + A missing check in the DCM decoder could result in an image with invalid dimensions + and that could cause crashes in other operation. + * Fix CVE-2026-49219: + An incorrect parsing of the filename can result in a policy bypass and read files + disallowed by a security policy using a symlink + * Backport policy from 7.1.2.25 + * Fix CVE-2026-53460: + A missing check for maximum memory request in AcquireAlignedMemory + could trigger an out-of-Memory condition. + * Fix CVE-2026-53461: + An incorrect loop in the ICON decoder can result in an out of + bounds heap write resulting in a crash. + * Fix CVE-2026-53463: + When passing incorrect arguments in the distort operation a + null pointer deference will occur. + * Fix CVE-2026-53464: + When providing invalid options to the wand option parser + a small memory leak will occur. + * Harden debian policy in case of custom recompilation (Closes: #1140176) + + -- Bastien Roucariès Sat, 20 Jun 2026 13:35:39 +0200 + imagemagick (8:7.1.1.43+dfsg1-1+deb13u9) trixie-security; urgency=high * Fix CVE-2026-33901 regression: diff -Nru imagemagick-7.1.1.43+dfsg1/debian/control imagemagick-7.1.1.43+dfsg1/debian/control --- imagemagick-7.1.1.43+dfsg1/debian/control 2026-05-24 14:24:29.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/control 2026-06-19 21:03:56.000000000 +0000 @@ -1,4 +1,4 @@ -# Autogenerated Sun Dec 29 13:54:19 UTC 2024 from make -f debian/rules update_pkg +# Autogenerated Mon Jun 15 00:15:33 CEST 2026 from make -f debian/rules update_pkg Source: imagemagick Section: graphics Priority: optional diff -Nru imagemagick-7.1.1.43+dfsg1/debian/patches/0005-Add-a-debian-policy.patch imagemagick-7.1.1.43+dfsg1/debian/patches/0005-Add-a-debian-policy.patch --- imagemagick-7.1.1.43+dfsg1/debian/patches/0005-Add-a-debian-policy.patch 2026-05-24 14:24:29.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/patches/0005-Add-a-debian-policy.patch 2026-06-20 09:27:27.000000000 +0000 @@ -10,11 +10,11 @@ 3 files changed, 160 insertions(+), 3 deletions(-) create mode 100644 config/policy-debian.xml -diff --git a/config/Makefile.am b/config/Makefile.am -index a3c12d6..1015263 100644 ---- a/config/Makefile.am -+++ b/config/Makefile.am -@@ -62,6 +62,7 @@ CONFIG_EXTRA_DIST = \ +Index: imagemagick/config/Makefile.am +=================================================================== +--- imagemagick.orig/config/Makefile.am 2026-06-19 23:04:43.101756482 +0200 ++++ imagemagick/config/Makefile.am 2026-06-19 23:04:43.099613818 +0200 +@@ -62,6 +62,7 @@ config/locale.xml \ config/log.xml \ config/mime.xml \ @@ -22,11 +22,10 @@ config/policy-limited.xml \ config/policy-open.xml \ config/policy-secure.xml \ -diff --git a/config/policy-debian.xml b/config/policy-debian.xml -new file mode 100644 -index 0000000..4b878ce ---- /dev/null -+++ b/config/policy-debian.xml +Index: imagemagick/config/policy-debian.xml +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ imagemagick/config/policy-debian.xml 2026-06-20 11:27:04.432728492 +0200 @@ -0,0 +1,156 @@ + + + -+ -+ -+ ++ ++ ++ + -diff --git a/configure.ac b/configure.ac -index 9081009..6b12dbe 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -827,10 +827,10 @@ m4_define([_MAGICK_SECURITY_POLICY], +Index: imagemagick/configure.ac +=================================================================== +--- imagemagick.orig/configure.ac 2026-06-19 23:04:43.101756482 +0200 ++++ imagemagick/configure.ac 2026-06-19 23:04:43.100361119 +0200 +@@ -827,10 +827,10 @@ [m4_define([MAGICK_SECURITY_POLICY_DEFAULT], [m4_if($1, limited, limited, m4_if($1, secure, secure, open))])dnl AC_MSG_CHECKING([which variant of security policy to enforce]) AC_ARG_WITH([security-policy], @@ -201,7 +200,7 @@ security_policy=$withval ;; *) -@@ -844,7 +844,7 @@ m4_define([_MAGICK_SECURITY_POLICY], +@@ -844,7 +844,7 @@ AC_MSG_RESULT([$security_policy]) ]) # MAGICK_SECURITY_POLICY diff -Nru imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-48724.patch imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-48724.patch --- imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-48724.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-48724.patch 2026-06-19 21:03:56.000000000 +0000 @@ -0,0 +1,32 @@ +From: Cristy +Date: Mon, 18 May 2026 19:44:35 -0400 +Subject: + https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-2hhq-c99x-492r + +(cherry picked from commit 017c7efe4d63b953b35ab96fc0939ba3620e4739) + +when using an image with mask the Floyd-Steinberg dithering method it will cause a negative heap buffer over-write + +bug: https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-2hhq-c99x-492r +origin: https://github.com/ImageMagick/ImageMagick/commit/017c7efe4d63b953b35ab96fc0939ba3620e4739 +--- + MagickCore/attribute.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/MagickCore/attribute.c b/MagickCore/attribute.c +index 5f0ff9f..0a55a3f 100644 +--- a/MagickCore/attribute.c ++++ b/MagickCore/attribute.c +@@ -2028,7 +2028,11 @@ static MagickBooleanType FloydSteinbergImageDepth(Image *image, + channel=GetPixelChannelChannel(image,i); + traits=GetPixelChannelTraits(image,channel); + if ((traits & UpdatePixelTrait) == 0) +- continue; ++ { ++ u++; ++ v++; ++ continue; ++ } + pixel=(double) q[i]+distortion[u]; + q[i]=ScaleAnyToQuantum(ScaleQuantumToAny(ClampPixel((MagickRealType) + pixel),range),range); diff -Nru imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-48734.patch imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-48734.patch --- imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-48734.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-48734.patch 2026-06-19 21:03:56.000000000 +0000 @@ -0,0 +1,41 @@ +From: Cristy +Date: Mon, 18 May 2026 21:56:32 -0400 +Subject: + https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-h36c-3666-h489 + +(cherry picked from commit 9ee821731faee8c4cc44103cc4180854046bb13c) + +a crafted MVG file could result in a stack overflow due to a missing depth or visited-set check. + +bug: https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-h36c-3666-h489 +origin: https://github.com/ImageMagick/ImageMagick/commit/9ee821731faee8c4cc44103cc4180854046bb13c +--- + MagickCore/draw.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/MagickCore/draw.c b/MagickCore/draw.c +index e3fb634..5f4d280 100644 +--- a/MagickCore/draw.c ++++ b/MagickCore/draw.c +@@ -2549,6 +2549,7 @@ static MagickBooleanType RenderMVGContent(Image *image, + *macros; + + ssize_t ++ classDepth = 0, + defsDepth, + i, + j, +@@ -2760,6 +2761,13 @@ static MagickBooleanType RenderMVGContent(Image *image, + break; + if (i < n) + break; ++ if (classDepth++ > MagickMaxRecursionDepth) ++ { ++ (void) ThrowMagickException(exception,GetMagickModule(), ++ DrawError,"VectorGraphicsNestedTooDeeply","`%s'",token); ++ status=MagickFalse; ++ break; ++ } + mvg_class=(const char *) GetValueFromSplayTree(macros,token); + if ((graphic_context[n]->render != MagickFalse) && + (mvg_class != (const char *) NULL) && (p > primitive)) diff -Nru imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-48994.patch imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-48994.patch --- imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-48994.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-48994.patch 2026-06-19 21:03:56.000000000 +0000 @@ -0,0 +1,45 @@ +From: Dirk Lemstra +Date: Sun, 24 May 2026 10:01:48 +0200 +Subject: Added extra checks to prevent an overflow on 32-bit systems + (GHSA-4v89-6mgq-6rgc) + +(cherry picked from commit 44df3a54af31b8d33fa5e40b4dc61d051c4a5d9a) + +bug: https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-4v89-6mgq-6rgc +origin: https://github.com/ImageMagick/ImageMagick/commit/44df3a54af31b8d33fa5e40b4dc61d051c4a5d9a +--- + coders/mat.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +diff --git a/coders/mat.c b/coders/mat.c +index 34e8176..fdbfb23 100644 +--- a/coders/mat.c ++++ b/coders/mat.c +@@ -751,8 +751,15 @@ static Image *ReadMATImageV4(const ImageInfo *image_info,Image *image, + if (HDR.Type[0] != 0) + SetQuantumEndian(image,quantum_info,MSBEndian); + status=SetQuantumFormat(image,quantum_info,format_type); +- status=SetQuantumDepth(image,quantum_info,depth); +- status=SetQuantumEndian(image,quantum_info,endian); ++ if (status != MagickFalse) ++ status=SetQuantumDepth(image,quantum_info,depth); ++ if (status != MagickFalse) ++ status=SetQuantumEndian(image,quantum_info,endian); ++ if (status == MagickFalse) ++ { ++ quantum_info=DestroyQuantumInfo(quantum_info); ++ ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); ++ } + SetQuantumScale(quantum_info,1.0); + pixels=(unsigned char *) GetQuantumPixels(quantum_info); + for (y=0; y < (ssize_t) image->rows; y++) +@@ -795,8 +802,7 @@ static Image *ReadMATImageV4(const ImageInfo *image_info,Image *image, + else + InsertComplexFloatRow(image,(float *) pixels,y,0,0,exception); + } +- if (quantum_info != (QuantumInfo *) NULL) +- quantum_info=DestroyQuantumInfo(quantum_info); ++ quantum_info=DestroyQuantumInfo(quantum_info); + if (EOFBlob(image) != MagickFalse) + { + ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile", diff -Nru imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-49218.patch imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-49218.patch --- imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-49218.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-49218.patch 2026-06-19 21:03:56.000000000 +0000 @@ -0,0 +1,26 @@ +From: Dirk Lemstra +Date: Fri, 22 May 2026 17:53:08 +0200 +Subject: Added missing check for returning an image with zero columns or rows + (https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-8pj9-6897-74xc) + +(cherry picked from commit 84fbcef8a558b1da075417a89d29aa5632d57f63) + +bug: https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-8pj9-6897-74xc +origin: https://github.com/ImageMagick/ImageMagick/commit/84fbcef8a558b1da075417a89d29aa5632d57f63 +--- + coders/dcm.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/coders/dcm.c b/coders/dcm.c +index 3085bb5..f81e16b 100644 +--- a/coders/dcm.c ++++ b/coders/dcm.c +@@ -4354,6 +4354,8 @@ static Image *ReadDCMImage(const ImageInfo *image_info,ExceptionInfo *exception) + RelinquishDCMMemory(&info,&map,stream_info,stack,data); + if (image == (Image *) NULL) + return(image); ++ if ((image->rows == 0) || (image->columns == 0)) ++ ThrowReaderException(CorruptImageError,"ImproperImageHeader") + if (CloseBlob(image) == MagickFalse) + status=MagickFalse; + if (status == MagickFalse) diff -Nru imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-49219.patch imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-49219.patch --- imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-49219.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-49219.patch 2026-06-19 21:03:56.000000000 +0000 @@ -0,0 +1,359 @@ +From: Cristy +Date: Fri, 22 May 2026 18:45:19 -0400 +Subject: + https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-xcjm-wqff-m669 + +An incorrect parsing of the filename can result in a policy bypass and read files disallowed by a security policy using a symlink. + +[backport] +- backport policy from 7.1.2.25 +- drop unrelated token changes + +bug:https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-xcjm-wqff-m669 +origin: https://github.com/ImageMagick/ImageMagick/commit/d1bf6bcf357fef944280263892dadf84fbb2211d +--- + MagickCore/blob.c | 4 ++ + MagickCore/image-private.h | 4 +- + MagickCore/image.c | 10 +-- + MagickCore/policy-private.h | 10 +-- + MagickCore/policy.c | 165 ++++++++++++++++++++++++++++++++------------ + 5 files changed, 139 insertions(+), 54 deletions(-) + +diff --git a/MagickCore/blob.c b/MagickCore/blob.c +index 2dd6ee7..de7cef7 100644 +--- a/MagickCore/blob.c ++++ b/MagickCore/blob.c +@@ -82,6 +82,10 @@ + /* + Define declarations. + */ ++#define IsPathAuthorized(rights,filename) \ ++ ((IsRightsAuthorized(PathPolicyDomain,rights,filename) != MagickFalse) && \ ++ ((IsRightsAuthorizedByName(SystemPolicyDomain,"symlink",rights,"follow") != MagickFalse) || \ ++ (is_symlink_utf8(filename) == MagickFalse))) + #define MagickMaxBlobExtent (8*8192) + #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) + # define MAP_ANONYMOUS MAP_ANON +diff --git a/MagickCore/image-private.h b/MagickCore/image-private.h +index 8e0f960..dc3a8aa 100644 +--- a/MagickCore/image-private.h ++++ b/MagickCore/image-private.h +@@ -181,12 +181,12 @@ static inline ssize_t CastDoubleToSsizeT(const double x) + if (value < ((double) MAGICK_SSIZE_MIN)) + { + errno=ERANGE; +- return(MAGICK_SSIZE_MIN); ++ return((ssize_t) MAGICK_SSIZE_MIN); + } + if (value >= ((double) MAGICK_SSIZE_MAX)) + { + errno=ERANGE; +- return(MAGICK_SSIZE_MAX); ++ return((ssize_t) MAGICK_SSIZE_MAX); + } + return((ssize_t) value); + } +diff --git a/MagickCore/image.c b/MagickCore/image.c +index ed77122..1aa7a6d 100644 +--- a/MagickCore/image.c ++++ b/MagickCore/image.c +@@ -1656,7 +1656,7 @@ static inline MagickBooleanType IsValidFormatSpecifier(const char *start, + specifier = end[-1]; + + size_t +- length = end-start; ++ length = (size_t) (end-start); + + /* + Is this a valid format specifier? +@@ -1734,7 +1734,7 @@ MagickExport size_t InterpretImageFilename(const ImageInfo *image_info, + format_specifier[MagickPathExtent]; + + size_t +- length = cursor-specifier_start, ++ length = (size_t) (cursor-specifier_start), + pattern_length; + + ssize_t +@@ -1749,7 +1749,8 @@ MagickExport size_t InterpretImageFilename(const ImageInfo *image_info, + return(0); + if ((p-filename+pattern_length) >= MagickPathExtent) + return(0); +- (void) CopyMagickString(p,pattern,MagickPathExtent-(p-filename)); ++ (void) CopyMagickString(p,pattern,(size_t) (MagickPathExtent- ++ (p-filename))); + p+=pattern_length; + cursor++; + continue; +@@ -1795,7 +1796,8 @@ MagickExport size_t InterpretImageFilename(const ImageInfo *image_info, + option_length=strlen(option); + if ((p-filename+option_length) >= MagickPathExtent) + return(0); +- (void) CopyMagickString(p,option,MagickPathExtent-(p-filename)); ++ (void) CopyMagickString(p,option,(size_t) (MagickPathExtent- ++ (p-filename))); + p+=option_length; + cursor=end+1; + continue; +diff --git a/MagickCore/policy-private.h b/MagickCore/policy-private.h +index 343c34c..37916eb 100644 +--- a/MagickCore/policy-private.h ++++ b/MagickCore/policy-private.h +@@ -1,12 +1,12 @@ + /* + Copyright @ 1999 ImageMagick Studio LLC, a non-profit organization + dedicated to making software imaging solutions freely available. +- ++ + You may not use this file except in compliance with the License. You may + obtain a copy of the License at +- +- https://imagemagick.org/script/license.php +- ++ ++ https://imagemagick.org/license/ ++ + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@@ -34,6 +34,8 @@ static const char + #endif + + extern MagickPrivate MagickBooleanType ++ IsRightsAuthorizedByName(const PolicyDomain,const char *,const PolicyRights, ++ const char *), + PolicyComponentGenesis(void); + + extern MagickPrivate void +diff --git a/MagickCore/policy.c b/MagickCore/policy.c +index 0e036c0..cd13ae5 100644 +--- a/MagickCore/policy.c ++++ b/MagickCore/policy.c +@@ -22,7 +22,7 @@ + % You may not use this file except in compliance with the License. You may % + % obtain a copy of the License at % + % % +-% https://imagemagick.org/script/license.php % ++% https://imagemagick.org/license/ % + % % + % Unless required by applicable law or agreed to in writing, software % + % distributed under the License is distributed on an "AS IS" BASIS, % +@@ -413,7 +413,7 @@ MagickExport const PolicyInfo **GetPolicyInfoList(const char *pattern, + const PolicyInfo + *policy; + +- policy=(const PolicyInfo *)p->value; ++ policy=(const PolicyInfo *) p->value; + if ((policy->stealth == MagickFalse) && + (GlobExpression(policy->name,pattern,MagickFalse) != MagickFalse)) + policies[i++]=policy; +@@ -598,7 +598,7 @@ static MagickBooleanType IsPolicyCacheInstantiated(ExceptionInfo *exception) + { + if (policy_cache == (LinkedListInfo *) NULL) + { +- GetMaxMemoryRequest(); /* avoid OMP deadlock */ ++ (void) GetMaxMemoryRequest(); /* avoid OMP deadlock */ + if (policy_semaphore == (SemaphoreInfo *) NULL) + ActivateSemaphoreInfo(&policy_semaphore); + LockSemaphoreInfo(policy_semaphore); +@@ -623,6 +623,11 @@ static MagickBooleanType IsPolicyCacheInstantiated(ExceptionInfo *exception) + % IsRightsAuthorized() returns MagickTrue if the policy authorizes the + % requested rights for the specified domain. + % ++% Policy evaluation uses a “last match wins” model. Be careful when adding ++% new rules: any later policy can override earlier denies or allows. Place ++% broad deny rules first, followed by specific exceptions, and review ++% ordering to avoid accidental authorization. ++% + % The format of the IsRightsAuthorized method is: + % + % MagickBooleanType IsRightsAuthorized(const PolicyDomain domain, +@@ -634,75 +639,147 @@ static MagickBooleanType IsPolicyCacheInstantiated(ExceptionInfo *exception) + % + % o rights: the policy rights. + % +-% o pattern: the coder, delegate, filter, or path pattern. ++% o pattern: the pattern. + % + */ +-MagickExport MagickBooleanType IsRightsAuthorized(const PolicyDomain domain, +- const PolicyRights rights,const char *pattern) ++ ++MagickPrivate MagickBooleanType IsRightsAuthorizedByName( ++ const PolicyDomain domain,const char *name,const PolicyRights rights, ++ const char *pattern) + { + char +- *real_pattern = (char *) NULL; ++ *canonical_directory = (char *) NULL, ++ *canonical_path = (char *) NULL, ++ *canonical_candidate = (char *) NULL, ++ directory[MagickPathExtent], ++ filename[MagickPathExtent]; + +- const PolicyInfo +- *policy_info; ++ ElementInfo ++ *p; + + ExceptionInfo + *exception; + + MagickBooleanType +- authorized, +- match; ++ matched_any = MagickFalse, ++ paths_provisioned = MagickFalse, ++ status; + +- ElementInfo +- *p; ++ PolicyRights ++ effective_rights = AllPolicyRights; /* rights authorized unless denied */ + ++ /* ++ Load policies. ++ */ + if ((GetLogEventMask() & PolicyEvent) != 0) + (void) LogMagickEvent(PolicyEvent,GetMagickModule(), +- "Domain: %s; rights=%s; pattern=\"%s\" ...", ++ "Domain: %s; name: %s; rights=%s; pattern=\"%s\"; ...", + CommandOptionToMnemonic(MagickPolicyDomainOptions,domain), +- CommandOptionToMnemonic(MagickPolicyRightsOptions,rights),pattern); ++ name == (const char *) NULL ? "undefined" : name, ++ CommandOptionToMnemonic(MagickPolicyRightsOptions,rights), ++ pattern == (const char *) NULL ? "undefined" : pattern); + exception=AcquireExceptionInfo(); +- policy_info=GetPolicyInfo("*",exception); ++ status=IsPolicyCacheInstantiated(exception); + exception=DestroyExceptionInfo(exception); +- if (policy_info == (PolicyInfo *) NULL) +- return(MagickTrue); +- authorized=MagickTrue; ++ if (status == MagickFalse) ++ { ++ if ((GetLogEventMask() & PolicyEvent) != 0) ++ (void) LogMagickEvent(PolicyEvent,GetMagickModule(), ++ " authorized: true (no security policies found)"); ++ return(MagickTrue); ++ } ++ /* ++ Evaluate policies in order; last match wins. ++ */ + LockSemaphoreInfo(policy_semaphore); ++ ResetLinkedListIterator(policy_cache); + p=GetHeadElementInLinkedList(policy_cache); +- while (p != (ElementInfo *) NULL) ++ for ( ; p != (ElementInfo *) NULL; p=p->next) + { + const PolicyInfo +- *policy; ++ *policy = (PolicyInfo *) p->value; + +- policy=(const PolicyInfo *) p->value; +- if (policy->domain == domain) ++ MagickBooleanType ++ match = MagickFalse; ++ ++ if (policy->domain != domain) ++ continue; ++ if ((name != (char *) NULL) && (LocaleCompare(name,policy->name) != 0)) ++ continue; ++ match=GlobExpression(pattern,policy->pattern,MagickFalse); ++ if (policy->domain == PathPolicyDomain) + { +- if ((policy->domain == PathPolicyDomain) && +- (real_pattern == (const char *) NULL)) +- real_pattern=realpath_utf8(pattern); +- if (real_pattern != (char*) NULL) +- match=GlobExpression(real_pattern,policy->pattern,MagickFalse); +- else +- match=GlobExpression(pattern,policy->pattern,MagickFalse); +- if (match != MagickFalse) ++ if (paths_provisioned == MagickFalse) + { +- if ((rights & ReadPolicyRights) != 0) +- authorized=(policy->rights & ReadPolicyRights) != 0 ? MagickTrue : +- MagickFalse; +- if ((rights & WritePolicyRights) != 0) +- authorized=(policy->rights & WritePolicyRights) != 0 ? +- MagickTrue : MagickFalse; +- if ((rights & ExecutePolicyRights) != 0) +- authorized=(policy->rights & ExecutePolicyRights) != 0 ? +- MagickTrue : MagickFalse; ++ /* ++ Generate directory, basename, and canonical path. ++ */ ++ paths_provisioned=MagickTrue; ++ GetPathComponent(pattern,HeadPath,directory); ++ GetPathComponent(pattern,TailPath,filename); ++ canonical_directory=realpath_utf8(directory); ++ if ((canonical_directory != (char *) NULL) && (*filename != '\0')) ++ { ++ size_t ++ length; ++ ++ length=strlen(canonical_directory)+strlen(filename)+2; ++ canonical_candidate=(char *) AcquireCriticalMemory(length* ++ sizeof(*canonical_candidate)); ++ if (canonical_candidate != (char *) NULL) ++ (void) FormatLocaleString(canonical_candidate,length,"%s%s%s", ++ canonical_directory,DirectorySeparator,filename); ++ } ++ canonical_path=realpath_utf8(pattern); + } ++ /* ++ Match against directory, basename, and canonical path. ++ */ ++ if ((canonical_directory != (char *) NULL) && (match == MagickFalse)) ++ match=GlobExpression(canonical_directory,policy->pattern,MagickFalse); ++ if ((canonical_candidate != (char *) NULL) && (match == MagickFalse)) ++ match=GlobExpression(canonical_candidate,policy->pattern,MagickFalse); ++ if ((canonical_path != (char *) NULL) && (match == MagickFalse)) ++ match=GlobExpression(canonical_path,policy->pattern,MagickFalse); + } +- p=p->next; ++ if (match == MagickFalse) ++ continue; ++ matched_any=MagickTrue; ++ effective_rights=policy->rights; + } + UnlockSemaphoreInfo(policy_semaphore); +- if (real_pattern != (char *) NULL) +- real_pattern=DestroyString(real_pattern); +- return(authorized); ++ if (canonical_directory != (char *) NULL) ++ canonical_directory=DestroyString(canonical_directory); ++ if (canonical_candidate != (char *) NULL) ++ canonical_candidate=DestroyString(canonical_candidate); ++ if (canonical_path != (char *) NULL) ++ canonical_path=DestroyString(canonical_path); ++ /* ++ Is rights authorized? ++ */ ++ status=MagickTrue; ++ if (matched_any != MagickFalse) ++ { ++ if (((rights & ReadPolicyRights) != 0) && ++ ((effective_rights & ReadPolicyRights) == 0)) ++ status=MagickFalse; ++ if (((rights & WritePolicyRights) != 0) && ++ ((effective_rights & WritePolicyRights) == 0)) ++ status=MagickFalse; ++ if (((rights & ExecutePolicyRights) != 0) && ++ ((effective_rights & ExecutePolicyRights) == 0)) ++ status=MagickFalse; ++ } ++ if ((GetLogEventMask() & PolicyEvent) != 0) ++ (void) LogMagickEvent(PolicyEvent,GetMagickModule(), ++ " authorized: %s",status == MagickFalse ? "false" : "true"); ++ return(status); ++} ++ ++MagickExport MagickBooleanType IsRightsAuthorized(const PolicyDomain domain, ++ const PolicyRights rights,const char *pattern) ++{ ++ return(IsRightsAuthorizedByName(domain,(const char *) NULL,rights,pattern)); + } + + /* diff -Nru imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-53460.patch imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-53460.patch --- imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-53460.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-53460.patch 2026-06-19 21:03:56.000000000 +0000 @@ -0,0 +1,27 @@ +From: Cristy +Date: Thu, 28 May 2026 09:26:32 -0400 +Subject: + https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-q62c-h75r-2xhc + +A missing check for maximum memory request in AcquireAlignedMemory could trigger an out-of-Memory condition. + +bug: https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-q62c-h75r-2xhc +origin: https://github.com/ImageMagick/ImageMagick/commit/960367f3318e650ba8544c0ce3844d7897aba43b +--- + MagickCore/memory.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/MagickCore/memory.c b/MagickCore/memory.c +index 979d8b4..f986efd 100644 +--- a/MagickCore/memory.c ++++ b/MagickCore/memory.c +@@ -368,7 +368,8 @@ MagickExport void *AcquireAlignedMemory(const size_t count,const size_t quantum) + size_t + size; + +- if (HeapOverflowSanityCheckGetSize(count,quantum,&size) != MagickFalse) ++ if ((HeapOverflowSanityCheckGetSize(count,quantum,&size) != MagickFalse) || ++ (size > GetMaxMemoryRequest())) + { + errno=ENOMEM; + return(NULL); diff -Nru imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-53461.patch imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-53461.patch --- imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-53461.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-53461.patch 2026-06-19 21:03:56.000000000 +0000 @@ -0,0 +1,28 @@ +From: Cristy +Date: Fri, 29 May 2026 07:08:32 -0400 +Subject: + https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-g22q-f7gc-5jhr + +an incorrect loop in the ICON decoder can result in an out of bounds heap write resulting in a crash + +(cherry picked from commit 1db660b5c6725421c1212ecc88b4e2fa0b68703f) + +bug: https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-g22q-f7gc-5jhr +origin: https://github.com/ImageMagick/ImageMagick/commit/1db660b5c6725421c1212ecc88b4e2fa0b68703f +--- + coders/icon.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/coders/icon.c b/coders/icon.c +index c4c4729..ff60466 100644 +--- a/coders/icon.c ++++ b/coders/icon.c +@@ -220,7 +220,7 @@ static Image *Read1XImage(Image *image,ExceptionInfo *exception) + ssize_t + y; + +- for (y=0; y < (ssize_t) image->columns; y++) ++ for (y=0; y < (ssize_t) image->rows; y++) + { + Quantum + *q; diff -Nru imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-53463.patch imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-53463.patch --- imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-53463.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-53463.patch 2026-06-19 21:03:56.000000000 +0000 @@ -0,0 +1,37 @@ +From: Cristy +Date: Sun, 31 May 2026 06:54:52 -0400 +Subject: + https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-p9rq-q46c-g4x6 + +(cherry picked from commit aa288f3023da9ad9e0d85563d76ea7e1cb58abed) + +bug: https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-p9rq-q46c-g4x6 +origin: https://github.com/ImageMagick/ImageMagick/commit/aa288f3023da9ad9e0d85563d76ea7e1cb58abed +--- + MagickCore/distort.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/MagickCore/distort.c b/MagickCore/distort.c +index d81f68a..02a9dba 100644 +--- a/MagickCore/distort.c ++++ b/MagickCore/distort.c +@@ -1366,11 +1366,18 @@ static double *GenerateCoefficients(const Image *image, + Coeff 2,3 center of distortion of input image + Coefficients 4,5 Center of Distortion of dest (determined later) + */ ++ if (number_arguments < 1) { ++ coeff = (double *) RelinquishMagickMemory(coeff); ++ (void) ThrowMagickException(exception,GetMagickModule(),OptionError, ++ "InvalidArgument", "%s : 'Needs at least 1 argument'", ++ CommandOptionToMnemonic(MagickDistortOptions, *method) ); ++ return((double *) NULL); ++ } + if ( arguments[0] < MagickEpsilon || arguments[0] > 160.0 ) { ++ coeff=(double *) RelinquishMagickMemory(coeff); + (void) ThrowMagickException(exception,GetMagickModule(),OptionError, + "InvalidArgument", "%s : Invalid FOV Angle", + CommandOptionToMnemonic(MagickDistortOptions, *method) ); +- coeff=(double *) RelinquishMagickMemory(coeff); + return((double *) NULL); + } + coeff[0] = DegreesToRadians(arguments[0]); diff -Nru imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-53464.patch imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-53464.patch --- imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-53464.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-53464.patch 2026-06-19 21:03:56.000000000 +0000 @@ -0,0 +1,32 @@ +From: Cristy +Date: Sun, 31 May 2026 14:08:48 -0400 +Subject: + https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-j989-f892-2335 + +(cherry picked from commit 310e325e65f5171f35ec6305c9c21ec253d80852) + +bug; https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-j989-f892-2335 +origin: backport, https://github.com/ImageMagick/ImageMagick/commit/310e325e65f5171f35ec6305c9c21ec253d80852 +--- + MagickWand/wandcli-private.h | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/MagickWand/wandcli-private.h b/MagickWand/wandcli-private.h +index db2974a..2e13888 100644 +--- a/MagickWand/wandcli-private.h ++++ b/MagickWand/wandcli-private.h +@@ -27,8 +27,12 @@ extern "C" { + "`%s'",option) + + #define CLIWandExceptionArg(severity,tag,option,arg) \ +- (void) CLIThrowException(cli_wand,GetMagickModule(),severity,tag, \ +- "'%s' '%s'",option, arg) ++ { \ ++ char *message = GetExceptionMessage(errno); \ ++ (void) CLIThrowException(cli_wand,GetMagickModule(),severity,tag, \ ++ "'%s' '%s'",option, arg == (char *) NULL ? message : arg); \ ++ message=DestroyString(message); \ ++ } + + #define CLIWandWarnReplaced(message) \ + if ( (cli_wand->process_flags & ProcessWarnDeprecated) != 0 ) \ diff -Nru imagemagick-7.1.1.43+dfsg1/debian/patches/series imagemagick-7.1.1.43+dfsg1/debian/patches/series --- imagemagick-7.1.1.43+dfsg1/debian/patches/series 2026-05-24 14:24:29.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/patches/series 2026-06-19 21:03:56.000000000 +0000 @@ -173,3 +173,12 @@ CVE-2026-46693_2.patch CVE-2026-46693_3.patch CVE-2026-47165_CVE-2026-47166.patch +CVE-2026-48724.patch +CVE-2026-48734.patch +CVE-2026-48994.patch +CVE-2026-49218.patch +CVE-2026-49219.patch +CVE-2026-53460.patch +CVE-2026-53461.patch +CVE-2026-53463.patch +CVE-2026-53464.patch diff -Nru imagemagick-7.1.1.43+dfsg1/debian/rules imagemagick-7.1.1.43+dfsg1/debian/rules --- imagemagick-7.1.1.43+dfsg1/debian/rules 2026-05-24 14:24:29.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/rules 2026-06-19 21:03:56.000000000 +0000 @@ -279,6 +279,11 @@ UCQUANTUMDEPTH=$(call UC,$*) \ $(DH_EXEC_SUBST) $(CURDIR)/debian/tests.d/perlmagick-fonts-IMVERSION.QUANTUMDEPTH.in > $(CURDIR)/debian/tests/perlmagick-fonts-$(IMVERSION).$* chmod +x $(CURDIR)/debian/tests/perlmagick-fonts-$(IMVERSION).$* + HDRI=$(call HDRI_PART,$*) \ + QUANTUMDEPTH=$* \ + UCQUANTUMDEPTH=$(call UC,$*) \ + $(DH_EXEC_SUBST) $(CURDIR)/debian/tests.d/policy-IMVERSION.QUANTUMDEPTH.in > $(CURDIR)/debian/tests/policy-$(IMVERSION).$* + chmod +x $(CURDIR)/debian/tests/policy-$(IMVERSION).$* # clean up rm -f $(CURDIR)/debian/control.d/quantum.$* diff -Nru imagemagick-7.1.1.43+dfsg1/debian/tests/control imagemagick-7.1.1.43+dfsg1/debian/tests/control --- imagemagick-7.1.1.43+dfsg1/debian/tests/control 2026-05-22 20:45:38.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/tests/control 2026-06-17 19:42:27.000000000 +0000 @@ -14,6 +14,10 @@ Depends: libimage-magick-q16-perl, libmagickcore-7.q16-10-extra, libaliased-perl, fonts-urw-base35, libarray-compare-perl, bash Restrictions: allow-stderr +Tests: policy-7.q16 +Depends: @, curl, busybox, iproute2 +Restrictions: allow-stderr + Tests: rose-7.q16hdri Depends: imagemagick-7.q16hdri, libmagickcore-7.q16hdri-10-extra, netpbm @@ -30,6 +34,10 @@ Depends: libimage-magick-q16hdri-perl, libmagickcore-7.q16hdri-10-extra, libaliased-perl, fonts-urw-base35, libarray-compare-perl, bash Restrictions: allow-stderr +Tests: policy-7.q16hdri +Depends: @, curl, busybox, iproute2 +Restrictions: allow-stderr + Tests: rmagick-leak Depends: ruby-rmagick, fonts-urw-base35, time, bash diff -Nru imagemagick-7.1.1.43+dfsg1/debian/tests/policy-7.q16 imagemagick-7.1.1.43+dfsg1/debian/tests/policy-7.q16 --- imagemagick-7.1.1.43+dfsg1/debian/tests/policy-7.q16 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/tests/policy-7.q16 2026-06-17 19:42:27.000000000 +0000 @@ -0,0 +1,38 @@ +#!/usr/bin/sh + +CONVERT=convert-im7.q16 + +set -e + +clean() { + [ -n "$OUTDIR" ] && rm -rf "$OUTDIR" || true + [ -n "$SERVERPID" ] && kill "$SERVERPID" 2>/dev/null || true +} + +trap clean EXIT INT TERM + +OUTDIR="$(mktemp -d)" + +(cd $OUTDIR ; convert logo: logo.png) + +# Find a random free port +PORT=$(shuf -i 20000-40000 -n 1) +while ss -ltn | grep -q ":$PORT "; do + PORT=$(shuf -i 20000-40000 -n 1) +done + +echo "Using random port $PORT" + +busybox httpd -v -f -p "$PORT" -h "$OUTDIR" & +SERVERPID=$! +sleep 1 + +# should fail +"$CONVERT" -verbose "http://127.0.0.1:$PORT/logo.png" "$OUTDIR/out.jpeg" || true +if [ ! -f "$OUTDIR/out.jpeg" ] ; then + echo "✔ policy block HTTP correctly" + exit 0; +else + echo "❌ policy failure" + exit 1 +fi \ No newline at end of file diff -Nru imagemagick-7.1.1.43+dfsg1/debian/tests/policy-7.q16hdri imagemagick-7.1.1.43+dfsg1/debian/tests/policy-7.q16hdri --- imagemagick-7.1.1.43+dfsg1/debian/tests/policy-7.q16hdri 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/tests/policy-7.q16hdri 2026-06-17 19:42:27.000000000 +0000 @@ -0,0 +1,38 @@ +#!/usr/bin/sh + +CONVERT=convert-im7.q16hdri + +set -e + +clean() { + [ -n "$OUTDIR" ] && rm -rf "$OUTDIR" || true + [ -n "$SERVERPID" ] && kill "$SERVERPID" 2>/dev/null || true +} + +trap clean EXIT INT TERM + +OUTDIR="$(mktemp -d)" + +(cd $OUTDIR ; convert logo: logo.png) + +# Find a random free port +PORT=$(shuf -i 20000-40000 -n 1) +while ss -ltn | grep -q ":$PORT "; do + PORT=$(shuf -i 20000-40000 -n 1) +done + +echo "Using random port $PORT" + +busybox httpd -v -f -p "$PORT" -h "$OUTDIR" & +SERVERPID=$! +sleep 1 + +# should fail +"$CONVERT" -verbose "http://127.0.0.1:$PORT/logo.png" "$OUTDIR/out.jpeg" || true +if [ ! -f "$OUTDIR/out.jpeg" ] ; then + echo "✔ policy block HTTP correctly" + exit 0; +else + echo "❌ policy failure" + exit 1 +fi \ No newline at end of file diff -Nru imagemagick-7.1.1.43+dfsg1/debian/tests.d/control.quantum.in imagemagick-7.1.1.43+dfsg1/debian/tests.d/control.quantum.in --- imagemagick-7.1.1.43+dfsg1/debian/tests.d/control.quantum.in 2026-05-22 20:45:38.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/tests.d/control.quantum.in 2026-06-17 19:41:19.000000000 +0000 @@ -14,3 +14,7 @@ Depends: libimage-magick-${QUANTUMDEPTH}-perl, libmagickcore-${IMVERSION}.${QUANTUMDEPTH}-${CORESOVERSION}-extra, libaliased-perl, fonts-urw-base35, libarray-compare-perl, bash Restrictions: allow-stderr +Tests: policy-${IMVERSION}.${QUANTUMDEPTH} +Depends: @, curl, busybox, iproute2 +Restrictions: allow-stderr + diff -Nru imagemagick-7.1.1.43+dfsg1/debian/tests.d/policy-IMVERSION.QUANTUMDEPTH.in imagemagick-7.1.1.43+dfsg1/debian/tests.d/policy-IMVERSION.QUANTUMDEPTH.in --- imagemagick-7.1.1.43+dfsg1/debian/tests.d/policy-IMVERSION.QUANTUMDEPTH.in 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/tests.d/policy-IMVERSION.QUANTUMDEPTH.in 2026-06-15 17:48:21.000000000 +0000 @@ -0,0 +1,38 @@ +#!/usr/bin/sh + +CONVERT=convert-im${IMVERSION}.${QUANTUMDEPTH} + +set -e + +clean() { + [ -n "$OUTDIR" ] && rm -rf "$OUTDIR" || true + [ -n "$SERVERPID" ] && kill "$SERVERPID" 2>/dev/null || true +} + +trap clean EXIT INT TERM + +OUTDIR="$(mktemp -d)" + +(cd $OUTDIR ; convert logo: logo.png) + +# Find a random free port +PORT=$(shuf -i 20000-40000 -n 1) +while ss -ltn | grep -q ":$PORT "; do + PORT=$(shuf -i 20000-40000 -n 1) +done + +echo "Using random port $PORT" + +busybox httpd -v -f -p "$PORT" -h "$OUTDIR" & +SERVERPID=$! +sleep 1 + +# should fail +"$CONVERT" -verbose "http://127.0.0.1:$PORT/logo.png" "$OUTDIR/out.jpeg" || true +if [ ! -f "$OUTDIR/out.jpeg" ] ; then + echo "✔ policy block HTTP correctly" + exit 0; +else + echo "❌ policy failure" + exit 1 +fi \ No newline at end of file