Version in base suite: 6.9.11.60+dfsg-1.6+deb12u9 Base version: imagemagick_6.9.11.60+dfsg-1.6+deb12u9 Target version: imagemagick_6.9.11.60+dfsg-1.6+deb12u10 Base file: /srv/ftp-master.debian.org/ftp/pool/main/i/imagemagick/imagemagick_6.9.11.60+dfsg-1.6+deb12u9.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/i/imagemagick/imagemagick_6.9.11.60+dfsg-1.6+deb12u10.dsc changelog | 98 + patches/CVE-2026-33901_bug420_1.patch | 27 patches/CVE-2026-33901_bug420_2.patch | 40 patches/CVE-2026-42050.patch | 36 patches/CVE-2026-42326.patch | 28 patches/CVE-2026-45031.patch | 29 patches/CVE-2026-45358.patch | 37 patches/CVE-2026-45359.patch | 37 patches/CVE-2026-45624.patch | 32 patches/CVE-2026-45664_1.patch | 47 patches/CVE-2026-45664_2.patch | 116 + patches/CVE-2026-46520.patch | 37 patches/CVE-2026-46521.patch | 41 patches/CVE-2026-46522.patch | 56 patches/CVE-2026-46523.patch | 28 patches/CVE-2026-46559.patch | 57 patches/distribute-cache-backport.patch | 33 patches/port-distribute-cache-to-6.9.13-48.patch | 1405 +++++++++++++++++++++++ patches/series | 17 19 files changed, 2201 insertions(+) dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmp0cm77fed/imagemagick_6.9.11.60+dfsg-1.6+deb12u9.dsc: no acceptable signature found dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmp0cm77fed/imagemagick_6.9.11.60+dfsg-1.6+deb12u10.dsc: no acceptable signature found diff -Nru imagemagick-6.9.11.60+dfsg/debian/changelog imagemagick-6.9.11.60+dfsg/debian/changelog --- imagemagick-6.9.11.60+dfsg/debian/changelog 2026-04-25 14:03:16.000000000 +0000 +++ imagemagick-6.9.11.60+dfsg/debian/changelog 2026-05-27 20:36:03.000000000 +0000 @@ -1,3 +1,82 @@ +imagemagick (8:6.9.11.60+dfsg-1.6+deb12u10) bookworm-security; urgency=high + + * Fix CVE-2026-33901 regression: + Previous fix breaks rendering of some MVG files. + * Fix CVE-2026-42050: + A malicious MIFF file could trigger an overflow when a user opens it + in the he display tool and right-clicks a tile to invoke the + Load/Update menu item. + * Fix CVE-2026-42326: + Heap Buffer Over-Read in IPTC encoder + * Fix CVE-2026-45031: + Policy Bypass in PSD decoder + Due to a missing check in the PSD decoder it would be + possible to bypass the list-length resource policy when + decoding a PSD image. Other security limits would still apply. + * Fix CVE-2026-45359: + Heap Buffer Over-Read in connected components when the user + supplies an invalid keep-top define. + An invalid connected-components:keep-top value could result + in a heap buffer over-read when performing the connected components + operation. + * Fix CVE-2026-45359: + Heap Buffer Over-Read in connected components when the user + supplies an invalid keep-top define. + An invalid connected-components:keep-top value could result + in a heap buffer over-read when performing the connected components + operation. + * Fix CVE-2026-45624: + Heap Buffer Over-Read of 24 bytes in distort operation. + When performing a polynomial distortion an out of bounds over-read of + 24 bytes can occur when specifying specific arguments. + * Fix CVE-2026-45664: + Policy Bypass in MNG decoder + Because of a missing check in the MNG coder it would be possible + to read more images than the list limit policy would allow + resulting in excessive resource use. + * Fix CVE-2026-46520: + Heap Buffer Over-Write in IPL decoder when reading multiple + images of different dimensions + When reading multiple images with different dimensions an out of + bounds heap write can occur. + * Fix CVE-2026-46521: + Heap Buffer Over-Write in MIFF encoder when using LZMA compression. + When using LZMA compression in the MIFF encoder an out of bounds + write can occur due to a missing check. + * Fix CVE-2026-46522: + Infinite Loop in the MIFF decoder can lead to CPU exhaustion. + Due to a missing check in the MIFF decoder a crafted file could + cause an infinite loop resulting in CPU exhaustion. + * Fix CVE-2026-46523: + Use-After-Free in MSL decoder. + A crafted MSL image can trigger a heap-use-after-free. + * Fix CVE-2026-46559: + Heap Buffer Over-Write of a single byte in the JP2 encoder. + An incorrect check in the JP2 will result in an heap buffer over + write of a single byte when specifying certain options. + * backport distribute cache from 6.9.13-48 + * Fix CVE-2026-46692: + Heap Buffer Over-Write in distributed pixel cache server + An attacker who can connect to a magick -distribute-cache + service can cause a heap buffer over-write in the server process. + * Fix CVE-2026-46693: + Race Condition in distributed pixel cache server can result + in file descriptor hijacking + An attacker who can connect to a magick -distribute-cache service can + hijack a file descriptor in the server process when a race condition is met. + * Fix CVE-2026-47165: + Information Disclosure in distributed pixel cache server because it is + not using a challenge–response authentication model. + The distributed pixel cache was originally designed to operate without a + challenge–response authentication model. However, given today’s heightened + security expectations, we have changed our implementation. + * Fix CVE-2026-47166: + Heap Buffer Over-Read in distributed pixel cache server. + An attacker who can connect to a magick -distribute-cache service + can cause a heap buffer over-read in the server processs. + + -- Bastien Roucariès Wed, 27 May 2026 22:36:03 +0200 + imagemagick (8:6.9.11.60+dfsg-1.6+deb12u9) bookworm-security; urgency=medium * Fix CVE-2026-25971: @@ -31,6 +110,25 @@ * Fix CVE-2026-40311 (Closes: #1134627): A heap use-after-free vulnerability that can cause a crash when reading and printing values from an invalid XMP profile. + * Fix CVE-2026-46692: + Heap Buffer Over-Write in distributed pixel cache server + An attacker who can connect to a magick -distribute-cache + service can cause a heap buffer over-write in the server process. + * Fix CVE-2026-46693: + Race Condition in distributed pixel cache server can result + in file descriptor hijacking + An attacker who can connect to a magick -distribute-cache service can + hijack a file descriptor in the server process when a race condition is met. + * Fix CVE-2026-47165: + Information Disclosure in distributed pixel cache server because it is + not using a challenge–response authentication model. + The distributed pixel cache was originally designed to operate without a + challenge–response authentication model. However, given today’s heightened + security expectations, we have changed our implementation. + * Fix CVE-2026-47166: + Heap Buffer Over-Read in distributed pixel cache server. + An attacker who can connect to a magick -distribute-cache service + can cause a heap buffer over-read in the server process. -- Bastien Roucariès Sat, 25 Apr 2026 16:03:16 +0200 diff -Nru imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-33901_bug420_1.patch imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-33901_bug420_1.patch --- imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-33901_bug420_1.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-33901_bug420_1.patch 2026-05-27 20:34:21.000000000 +0000 @@ -0,0 +1,27 @@ +From: Cristy +Date: Sat, 25 Apr 2026 16:32:21 -0400 +Subject: https://github.com/ImageMagick/ImageMagick6/issues/420 + +CVE-2026-33901 patch breaks rendering + +origin: https://github.com/ImageMagick/ImageMagick6/commit/a86cd0fbc863b1ddb24ffa9168f68baebf02baa4 +bug: https://github.com/ImageMagick/ImageMagick6/issues/420 +--- + magick/draw.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/magick/draw.c b/magick/draw.c +index e190d9b..2945007 100644 +--- a/magick/draw.c ++++ b/magick/draw.c +@@ -3490,8 +3490,8 @@ static MagickBooleanType RenderMVGContent(Image *image, + continue; + break; + } +- if ((q == (char *) NULL) || (p == (char *) NULL) || ((q-4) < p) || +- ((q-p+4+1) > MagickPathExtent)) ++ if ((q == (char *) NULL) || (p == (char *) NULL) || ++ ((q-4) < p) || ((size_t) (q-p+4+1) > extent)) + { + status=MagickFalse; + break; diff -Nru imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-33901_bug420_2.patch imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-33901_bug420_2.patch --- imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-33901_bug420_2.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-33901_bug420_2.patch 2026-05-27 20:34:21.000000000 +0000 @@ -0,0 +1,40 @@ +From: Cristy +Date: Mon, 27 Apr 2026 19:25:46 -0400 +Subject: https://github.com/ImageMagick/ImageMagick6/issues/420 + +(cherry picked from commit 8173c210fc1ea0221150be44459878acd56391cc) + +CVE-2026-33901 patch breaks rendering + +origin: https://github.com/ImageMagick/ImageMagick6/commit/8173c210fc1ea0221150be44459878acd56391cc +bug: https://github.com/ImageMagick/ImageMagick6/issues/420 +--- + magick/draw.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/magick/draw.c b/magick/draw.c +index 2945007..be9d4aa 100644 +--- a/magick/draw.c ++++ b/magick/draw.c +@@ -3380,7 +3380,7 @@ static MagickBooleanType RenderMVGContent(Image *image, + } + if ((q == (char *) NULL) || (*q == '\0') || + (p == (char *) NULL) || ((q-4) < p) || +- ((q-p+4+1) > MagickPathExtent)) ++ ((q-p+4+1) > extent)) + { + status=MagickFalse; + break; +@@ -3435,9 +3435,9 @@ static MagickBooleanType RenderMVGContent(Image *image, + if (n > MagickMaxRecursionDepth) + { + (void) ThrowMagickException(&image->exception, +- GetMagickModule(),DrawError,"VectorGraphicsNestedTooDeeply", +- "`%s'",image->filename); +- status=MagickFalse; ++ GetMagickModule(),DrawError, ++ "VectorGraphicsNestedTooDeeply","`%s'",image->filename); ++ status=MagickFalse; + } + break; + } diff -Nru imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-42050.patch imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-42050.patch --- imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-42050.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-42050.patch 2026-05-27 20:34:21.000000000 +0000 @@ -0,0 +1,36 @@ +From: Cristy +Date: Sat, 18 Apr 2026 11:47:21 -0400 +Subject: + https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-7mxf-ff4f-jj7p + +(cherry picked from commit 2b4a06cdb9b5b4b8e51247be8b38ea4cbfdfb07c) +origin: https://github.com/ImageMagick/ImageMagick6/commit/2b4a06cdb9b5b4b8e51247be8b38ea4cbfdfb07c +bug: https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-7mxf-ff4f-jj7p +--- + magick/display.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/magick/display.c b/magick/display.c +index 54bc39f..290bd0d 100644 +--- a/magick/display.c ++++ b/magick/display.c +@@ -13042,7 +13042,8 @@ static Image *XTileImage(Display *display,XResourceInfo *resource_info, + if (id < 0) + return((Image *) NULL); + q=p; +- while ((*q != '\xff') && (*q != '\0')) ++ while ((*q != '\xff') && (*q != '\0') && ++ ((size_t) (q-p) < sizeof(filename))) + q++; + (void) CopyMagickString(filename,p,(size_t) (q-p+1)); + /* +@@ -13135,7 +13136,8 @@ static Image *XTileImage(Display *display,XResourceInfo *resource_info, + *image_view; + + q=p; +- while ((*q != '\xff') && (*q != '\0')) ++ while ((*q != '\xff') && (*q != '\0') && ++ ((size_t) (q-p) < sizeof(filename))) + q++; + (void) CopyMagickString(filename,p,(size_t) (q-p+1)); + p=q; diff -Nru imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-42326.patch imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-42326.patch --- imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-42326.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-42326.patch 2026-05-27 20:34:21.000000000 +0000 @@ -0,0 +1,28 @@ +From: Cristy +Date: Sat, 25 Apr 2026 22:26:59 -0400 +Subject: + https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-7wff-wpr6-vmhm + +(cherry picked from commit 4bbc9cf334ec0c136d4aa8c28afab17120cc954c) + +Heap Buffer Over-Read in IPTC encoder + +bug: https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-7wff-wpr6-vmhm +origin: https://github.com/ImageMagick/ImageMagick6/commit/4bbc9cf334ec0c136d4aa8c28afab17120cc954c +--- + coders/meta.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/coders/meta.c b/coders/meta.c +index de494b5..e6c94b3 100644 +--- a/coders/meta.c ++++ b/coders/meta.c +@@ -1798,7 +1798,7 @@ iptc_find: + info_length++; + tag_length|=(long) c; + } +- if (tag_length > (length+1)) ++ if (tag_length > length) + break; + p+=tag_length; + length-=tag_length; diff -Nru imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-45031.patch imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-45031.patch --- imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-45031.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-45031.patch 2026-05-27 20:34:21.000000000 +0000 @@ -0,0 +1,29 @@ +From: =?utf-8?q?Bastien_Roucari=C3=A8s?= +Date: Mon, 25 May 2026 21:56:58 +0200 +Subject: Added missing check for the list length limit in the PSD decoder + (https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-cwpj-h54c-xjpx) + +Policy Bypass in PSD decoder + +Due to a missing check in the PSD decoder it would be possible to bypass the list-length resource policy when decoding a PSD image. Other security limits would still apply. + +origin: backport, https://github.com/ImageMagick/ImageMagick6/commit/de0f3f1ee15c783d139135e93cff212ee37e89af +bug: https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-cwpj-h54c-xjpx +--- + coders/psd.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/coders/psd.c b/coders/psd.c +index e6ed6d7..88d766b 100644 +--- a/coders/psd.c ++++ b/coders/psd.c +@@ -1679,6 +1679,9 @@ static MagickBooleanType ReadPSDLayersInternal(Image *image, + image->matte=MagickTrue; + } + ++ if (AcquireMagickResource(ListLengthResource,number_layers) == MagickFalse) ++ ThrowBinaryException(ResourceLimitError,"ListLengthExceedsLimit", ++ image->filename); + /* + We only need to know if the image has an alpha channel + */ diff -Nru imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-45358.patch imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-45358.patch --- imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-45358.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-45358.patch 2026-05-27 20:34:21.000000000 +0000 @@ -0,0 +1,37 @@ +From: Cristy +Date: Sat, 9 May 2026 18:46:44 -0400 +Subject: + https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-cr6r-hmj8-pr7r + +CVE-2026-45358: +Heap Buffer Over-Read of a single byte in meta encoder. +An of by one in the meta encoder could result in an out +of bounds read of a single byte in the meta encoder. + +(cherry picked from commit 1b962d30cc7ad94d18c5f24c8dbc6d48f534b99d) + +bug: https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-cr6r-hmj8-pr7r +origin: backport, https://github.com/ImageMagick/ImageMagick6/commit/1b962d30cc7ad94d18c5f24c8dbc6d48f534b99d +--- + coders/meta.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/coders/meta.c b/coders/meta.c +index e6c94b3..b13a508 100644 +--- a/coders/meta.c ++++ b/coders/meta.c +@@ -1702,8 +1702,12 @@ static size_t GetIPTCStream(unsigned char **info,size_t length) + return(tag_length); + } + if ((tag_length & 0x01) != 0) +- tag_length++; +- p+=tag_length; ++ { ++ tag_length++; ++ if (tag_length > extent) ++ break; ++ } ++ p+=(ptrdiff_t) tag_length; + extent-=tag_length; + } + /* diff -Nru imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-45359.patch imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-45359.patch --- imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-45359.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-45359.patch 2026-05-27 20:34:21.000000000 +0000 @@ -0,0 +1,37 @@ +From: Dirk Lemstra +Date: Sun, 24 May 2026 15:05:08 +0200 +Subject: + https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-vhrh-72hq-w8m7 + +Fix CVE-2026-45359: +Heap Buffer Over-Read in connected components when the user +supplies an invalid keep-top define. +An invalid connected-components:keep-top value could result +in a heap buffer over-read when performing the connected components +operation. + +(cherry picked from commit c590530d406e7628e6f1a8d0e7429b592bfadce8) + +bug: https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-vhrh-72hq-w8m7 +origin: backport, https://github.com/ImageMagick/ImageMagick6/commit/c590530d406e7628e6f1a8d0e7429b592bfadce8 +--- + magick/vision.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/magick/vision.c b/magick/vision.c +index 17109b5..c3f5e29 100644 +--- a/magick/vision.c ++++ b/magick/vision.c +@@ -557,7 +557,11 @@ MagickExport Image *ConnectedComponentsImage(const Image *image, + /* + Keep top objects. + */ +- top_ids=(ssize_t) StringToDouble(artifact,(char **) NULL); ++ top_ids=(ssize_t) StringToLong(artifact); ++ if (top_ids < 0) ++ top_ids=0; ++ if (top_ids >= (ssize_t) component_image->colors) ++ top_ids=(ssize_t) component_image->colors-1; + top_objects=(CCObjectInfo *) AcquireQuantumMemory(component_image->colors, + sizeof(*top_objects)); + if (top_objects == (CCObjectInfo *) NULL) diff -Nru imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-45624.patch imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-45624.patch --- imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-45624.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-45624.patch 2026-05-27 20:34:21.000000000 +0000 @@ -0,0 +1,32 @@ +From: Cristy +Date: Sun, 10 May 2026 20:28:55 -0400 +Subject: + https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-pfvh-m9xv-8966 + +Fix CVE-2026-45624: +Heap Buffer Over-Read of 24 bytes in distort operation. +When performing a polynomial distortion an out of bounds over-read of +24 bytes can occur when specifying specific arguments. + +(cherry picked from commit 7736b7c458d0c694e26023ad4bd3436fc2f951ff) + +bug: https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-pfvh-m9xv-8966 +origin: backport, https://github.com/ImageMagick/ImageMagick6/commit/7736b7c458d0c694e26023ad4bd3436fc2f951ff +--- + magick/distort.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/magick/distort.c b/magick/distort.c +index 15d1a58..4719180 100644 +--- a/magick/distort.c ++++ b/magick/distort.c +@@ -432,7 +432,8 @@ static double *GenerateCoefficients(const Image *image, + "Invalid order, should be interger 1 to 5, or 1.5"); + return((double *) NULL); + } +- if ( number_arguments < 1+i*cp_size ) { ++ if ((number_arguments < (1+i*cp_size)) || ++ (((number_arguments-1) % cp_size) != 0)) { + (void) ThrowMagickException(exception,GetMagickModule(),OptionError, + "InvalidArgument", "%s : 'require at least %.20g CPs'", + "Polynomial", (double) i); diff -Nru imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-45664_1.patch imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-45664_1.patch --- imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-45664_1.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-45664_1.patch 2026-05-27 20:34:21.000000000 +0000 @@ -0,0 +1,47 @@ +From: Cristy +Date: Mon, 11 May 2026 14:22:08 -0400 +Subject: [PATCH] + https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-g5mf-wqq5-vwg6 + +Fix CVE-2026-45664: + +Policy Bypass in MNG decoder +Because of a missing check in the MNG coder it would be possible +of read more images than the list limit policy would allow +resulting in excessive resource use. + +bug: https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-g5mf-wqq5-vwg6 +origin: backport, https://github.com/ImageMagick/ImageMagick6/commit/11ac03e5485a94a8c1ef06e79e8d77ded1d18d46 +--- + coders/png.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/coders/png.c b/coders/png.c +index 1c6e5b1..1b67a3c 100644 +--- a/coders/png.c ++++ b/coders/png.c +@@ -5206,6 +5206,7 @@ static Image *ReadOneMNGImage(MngInfo* mng_info, const ImageInfo *image_info, + #if defined(MNG_INSERT_LAYERS) + insert_layers, + #endif ++ number_loops=0, + mng_iterations=1, + simplicity=0, + subframe_height=0, +@@ -6062,12 +6063,14 @@ static Image *ReadOneMNGImage(MngInfo* mng_info, const ImageInfo *image_info, + + else + { +- if ((MagickSizeType) loop_iters > GetMagickResourceLimit(ListLengthResource)) +- loop_iters=GetMagickResourceLimit(ListLengthResource); ++ if ((MagickSizeType) number_loops+loop_iters > GetMagickResourceLimit(ListLengthResource)) ++ ThrowReaderException(ResourceLimitError, ++ "ListLengthExceedsLimit"); + if (loop_iters >= 2147483647L) + loop_iters=2147483647L; + mng_info->loop_jump[loop_level]=TellBlob(image); + mng_info->loop_count[loop_level]=loop_iters; ++ number_loops+=loop_iters; + } + + mng_info->loop_iteration[loop_level]=0; diff -Nru imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-45664_2.patch imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-45664_2.patch --- imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-45664_2.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-45664_2.patch 2026-05-27 20:34:21.000000000 +0000 @@ -0,0 +1,116 @@ +From: Cristy +Date: Mon, 11 May 2026 19:14:34 -0400 +Subject: + https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-g5mf-wqq5-vwg6 + +Fix CVE-2026-45664: + +Policy Bypass in MNG decoder +Because of a missing check in the MNG coder it would be possible +of read more images than the list limit policy would allow +resulting in excessive resource use. + +(cherry picked from commit 3d57d37907857d19b026760c47f1ac9c8c091c0d) + +bug; https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-g5mf-wqq5-vwg6 +origin: backport, https://github.com/ImageMagick/ImageMagick6/commit/3d57d37907857d19b026760c47f1ac9c8c091c0d +--- + coders/png.c | 25 +++++++++++++++---------- + 1 file changed, 15 insertions(+), 10 deletions(-) + +diff --git a/coders/png.c b/coders/png.c +index 1b67a3c..3ba14f2 100644 +--- a/coders/png.c ++++ b/coders/png.c +@@ -481,6 +481,9 @@ static SemaphoreInfo + waste more memory. + */ + #define MNG_MAX_OBJECTS 256 ++#define MNG_MAX_LOOP_COUNT 1000 ++#define MNG_MAX_LOOP_NESTING 256 ++#define MNG_MAX_LOOP_OPS 50000 + + /* + If this not defined, spec is interpreted strictly. If it is +@@ -681,8 +684,8 @@ typedef struct _MngInfo + + ssize_t + image_found, +- loop_count[256], +- loop_iteration[256], ++ loop_count[MNG_MAX_LOOP_NESTING], ++ loop_iteration[MNG_MAX_LOOP_NESTING], + scenes_found, + x_off[MNG_MAX_OBJECTS], + y_off[MNG_MAX_OBJECTS]; +@@ -697,12 +700,12 @@ typedef struct _MngInfo + /* These flags could be combined into one byte */ + exists[MNG_MAX_OBJECTS], + frozen[MNG_MAX_OBJECTS], +- loop_active[256], ++ loop_active[MNG_MAX_LOOP_NESTING], + invisible[MNG_MAX_OBJECTS], + viewable[MNG_MAX_OBJECTS]; + + MagickOffsetType +- loop_jump[256]; ++ loop_jump[MNG_MAX_LOOP_NESTING]; + + png_colorp + global_plte; +@@ -5206,7 +5209,7 @@ static Image *ReadOneMNGImage(MngInfo* mng_info, const ImageInfo *image_info, + #if defined(MNG_INSERT_LAYERS) + insert_layers, + #endif +- number_loops=0, ++ number_loop_ops=0, + mng_iterations=1, + simplicity=0, + subframe_height=0, +@@ -6045,9 +6048,12 @@ static Image *ReadOneMNGImage(MngInfo* mng_info, const ImageInfo *image_info, + if (memcmp(type,mng_LOOP,4) == 0) + { + ssize_t loop_iters=1; ++ if (number_loop_ops++ > MNG_MAX_LOOP_OPS) ++ ThrowReaderException(ResourceLimitError,"too many LOOP/ENDL ops"); + if (length > 4) + { + loop_level=chunk[0]; ++ + mng_info->loop_active[loop_level]=1; /* mark loop active */ + + /* Record starting point. */ +@@ -6063,14 +6069,11 @@ static Image *ReadOneMNGImage(MngInfo* mng_info, const ImageInfo *image_info, + + else + { +- if ((MagickSizeType) number_loops+loop_iters > GetMagickResourceLimit(ListLengthResource)) +- ThrowReaderException(ResourceLimitError, +- "ListLengthExceedsLimit"); + if (loop_iters >= 2147483647L) + loop_iters=2147483647L; + mng_info->loop_jump[loop_level]=TellBlob(image); + mng_info->loop_count[loop_level]=loop_iters; +- number_loops+=loop_iters; ++ number_loop_ops+=loop_iters; + } + + mng_info->loop_iteration[loop_level]=0; +@@ -6081,6 +6084,8 @@ static Image *ReadOneMNGImage(MngInfo* mng_info, const ImageInfo *image_info, + + if (memcmp(type,mng_ENDL,4) == 0) + { ++ if (number_loop_ops++ > MNG_MAX_LOOP_OPS) ++ ThrowReaderException(ResourceLimitError,"too many LOOP/ENDL ops"); + if (length > 0) + { + loop_level=chunk[0]; +@@ -6113,7 +6118,7 @@ static Image *ReadOneMNGImage(MngInfo* mng_info, const ImageInfo *image_info, + if (mng_info->loop_count[loop_level] > 0) + { + offset=SeekBlob(image, +- mng_info->loop_jump[loop_level], SEEK_SET); ++ mng_info->loop_jump[loop_level],SEEK_SET); + + if (offset < 0) + { diff -Nru imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-46520.patch imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-46520.patch --- imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-46520.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-46520.patch 2026-05-27 20:34:21.000000000 +0000 @@ -0,0 +1,37 @@ +From: Cristy +Date: Tue, 12 May 2026 12:27:55 -0400 +Subject: + https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-36wm-hprc-mcf5 + +Fix CVE-2026-46520: +Heap Buffer Over-Write in IPL decoder when reading multiple +images of different dimensions +When reading multiple images with different dimensions an out of +bounds heap write can occur. + +(cherry picked from commit 4095aa6144646ec6f04d254f050d7cbb04af293f) + +bug: https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-36wm-hprc-mcf5 +origin: https://github.com/ImageMagick/ImageMagick6/commit/4095aa6144646ec6f04d254f050d7cbb04af293f +--- + coders/ipl.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/coders/ipl.c b/coders/ipl.c +index 211210f..b1287a8 100644 +--- a/coders/ipl.c ++++ b/coders/ipl.c +@@ -639,6 +639,13 @@ static MagickBooleanType WriteIPLImage(const ImageInfo *image_info,Image *image) + /* + Convert MIFF to IPL raster pixels. + */ ++ if (SetQuantumDepth(image,quantum_info,quantum_info->depth) == MagickFalse) ++ { ++ (void) ThrowMagickException(&image->exception,GetMagickModule(), ++ CorruptImageError,"AnErrorHasOccurredWritingToFile","`%s'", ++ image->filename); ++ break; ++ } + pixels=GetQuantumPixels(quantum_info); + if(ipl_info.colors == 1){ + /* Red frame */ diff -Nru imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-46521.patch imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-46521.patch --- imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-46521.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-46521.patch 2026-05-27 20:34:21.000000000 +0000 @@ -0,0 +1,41 @@ +From: Cristy +Date: Tue, 12 May 2026 12:38:31 -0400 +Subject: + https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-jcqp-6r6f-3mfx + +(cherry picked from commit 61adf32771284186f2fbaea220062226123ac394) + +Fix CVE-2026-46521: +Heap Buffer Over-Write in MIFF encoder when using LZMA compression. +When using LZMA compression in the MIFF encoder an out of bounds +bug: https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-jcqp-6r6f-3mfx +origin: backport, https://github.com/ImageMagick/ImageMagick6/commit/61adf32771284186f2fbaea220062226123ac394 +--- + coders/miff.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/coders/miff.c b/coders/miff.c +index 0703d48..fb99eeb 100644 +--- a/coders/miff.c ++++ b/coders/miff.c +@@ -2134,8 +2134,9 @@ static MagickBooleanType WriteMIFFImage(const ImageInfo *image_info, + packet_size+=quantum_info->depth/8; + if (compression == RLECompression) + packet_size++; +- length=MagickMax(BZipMaxExtent(packet_size*image->columns),ZipMaxExtent( +- packet_size*image->columns)); ++ length=MagickMax(MagickMax(BZipMaxExtent(packet_size* ++ image->columns),LZMAMaxExtent(packet_size*image->columns)), ++ ZipMaxExtent(packet_size*image->columns)); + if ((compression == BZipCompression) || (compression == ZipCompression)) + if (length != (size_t) ((unsigned int) length)) + compression=NoCompression; +@@ -2520,7 +2521,7 @@ static MagickBooleanType WriteMIFFImage(const ImageInfo *image_info, + lzma_info.allocator=&allocator; + code=lzma_easy_encoder(&lzma_info,image->quality/10,LZMA_CHECK_SHA256); + if (code != LZMA_OK) +- status=MagickTrue; ++ status=MagickFalse; + break; + } + #endif diff -Nru imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-46522.patch imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-46522.patch --- imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-46522.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-46522.patch 2026-05-27 20:34:21.000000000 +0000 @@ -0,0 +1,56 @@ +From: Cristy +Date: Wed, 13 May 2026 15:50:50 -0400 +Subject: + https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-7gg8-qqx7-92g5 + +Fix CVE-2026-46522: + Infinite Loop in the MIFF decoder can lead to CPU exhaustion. + Due to a missing check in the MIFF decoder a crafted file could + cause an infinite loop resulting in CPU exhaustion. + +bug: https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-7gg8-qqx7-92g5 +origin: https://github.com/ImageMagick/ImageMagick6/commit/466237e1116b46abde8af0f1794b42f1110e04b5 +--- + coders/miff.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/coders/miff.c b/coders/miff.c +index fb99eeb..dadc115 100644 +--- a/coders/miff.c ++++ b/coders/miff.c +@@ -1478,6 +1478,11 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, + ThrowMIFFException(CorruptImageError, + "UnableToReadImageData"); + } ++ if (length == 0) ++ { ++ (void) BZ2_bzDecompressEnd(&bzip_info); ++ ThrowMIFFException(CorruptImageError,"UnexpectedEndOfFile"); ++ } + } + code=BZ2_bzDecompress(&bzip_info); + if ((code != BZ_OK) && (code != BZ_STREAM_END)) +@@ -1517,6 +1522,11 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, + ThrowMIFFException(CorruptImageError, + "UnableToReadImageData"); + } ++ if (length == 0) ++ { ++ lzma_end(&lzma_info); ++ ThrowMIFFException(CorruptImageError,"UnexpectedEndOfFile"); ++ } + } + code=lzma_code(&lzma_info,LZMA_RUN); + if ((code != LZMA_OK) && (code != LZMA_STREAM_END)) +@@ -1559,6 +1569,11 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, + ThrowMIFFException(CorruptImageError, + "UnableToReadImageData"); + } ++ if (length == 0) ++ { ++ (void) inflateEnd(&zip_info); ++ ThrowMIFFException(CorruptImageError,"UnexpectedEndOfFile"); ++ } + } + code=inflate(&zip_info,Z_SYNC_FLUSH); + if ((code != Z_OK) && (code != Z_STREAM_END)) diff -Nru imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-46523.patch imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-46523.patch --- imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-46523.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-46523.patch 2026-05-27 20:34:21.000000000 +0000 @@ -0,0 +1,28 @@ +From: Cristy +Date: Wed, 13 May 2026 19:08:20 -0400 +Subject: + https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-5r4x-w6p5-222q + +Fix CVE-2026-46523: + Use-After-Free in MSL decoder. + A crafted MSL image can trigger a heap-use-after-free. + +(cherry picked from commit 5ad5fdcc45871bdeeca414a883acb880532accce) +bug: https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-5r4x-w6p5-222q +origin: https://github.com/ImageMagick/ImageMagick6/commit/5ad5fdcc45871bdeeca414a883acb880532accce +--- + coders/msl.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/coders/msl.c b/coders/msl.c +index 27f24a9..18a7904 100644 +--- a/coders/msl.c ++++ b/coders/msl.c +@@ -8072,6 +8072,7 @@ ModuleExport size_t RegisterMSLImage(void) + entry->decoder=(DecodeImageHandler *) ReadMSLImage; + #endif + entry->format_type=ImplicitFormatType; ++ entry->blob_support=MagickFalse; + entry->description=ConstantString("Magick Scripting Language"); + entry->magick_module=ConstantString("MSL"); + (void) RegisterMagickInfo(entry); diff -Nru imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-46559.patch imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-46559.patch --- imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-46559.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-6.9.11.60+dfsg/debian/patches/CVE-2026-46559.patch 2026-05-27 20:34:21.000000000 +0000 @@ -0,0 +1,57 @@ +From: Cristy +Date: Wed, 13 May 2026 16:45:26 -0400 +Subject: + https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-533m-3wf6-c33v + +Fix CVE-2026-46559: + Heap Buffer Over-Write of a single byte in the JP2 encoder. + An incorrect check in the JP2 will result in an heap buffer over + write of a single byte when specifying certain options. + +(cherry picked from commit 7d68aec1d02aaaeb513a1778e9702fa0d9ba9dcd) + +bug: https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-533m-3wf6-c33v +origin: https://github.com/ImageMagick/ImageMagick6/commit/7d68aec1d02aaaeb513a1778e9702fa0d9ba9dcd +--- + coders/jp2.c | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +diff --git a/coders/jp2.c b/coders/jp2.c +index e29ae31..d903b9a 100644 +--- a/coders/jp2.c ++++ b/coders/jp2.c +@@ -918,11 +918,16 @@ static MagickBooleanType WriteJP2Image(const ImageInfo *image_info,Image *image) + const char + *p; + ++ size_t ++ extent = sizeof(parameters->tcp_distoratio)/ ++ sizeof(*parameters->tcp_distoratio); ++ + /* + Set quality PSNR. + */ + p=option; +- for (i=0; sscanf(p,"%f",¶meters->tcp_distoratio[i]) == 1; i++) ++ for (i=0; (i < (ssize_t) (extent-1)) && ++ (sscanf(p,"%f",¶meters->tcp_distoratio[i]) == 1); i++) + { + if (i >= 100) + break; +@@ -956,11 +961,15 @@ static MagickBooleanType WriteJP2Image(const ImageInfo *image_info,Image *image) + const char + *p; + ++ size_t ++ extent = sizeof(parameters->tcp_rates)/sizeof(*parameters->tcp_rates); ++ + /* + Set compression rate. + */ + p=option; +- for (i=0; sscanf(p,"%f",¶meters->tcp_rates[i]) == 1; i++) ++ for (i=0; (i < (ssize_t) (extent-1)) && ++ (sscanf(p,"%f",¶meters->tcp_rates[i]) == 1); i++) + { + if (i > 100) + break; diff -Nru imagemagick-6.9.11.60+dfsg/debian/patches/distribute-cache-backport.patch imagemagick-6.9.11.60+dfsg/debian/patches/distribute-cache-backport.patch --- imagemagick-6.9.11.60+dfsg/debian/patches/distribute-cache-backport.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-6.9.11.60+dfsg/debian/patches/distribute-cache-backport.patch 2026-05-27 20:34:21.000000000 +0000 @@ -0,0 +1,33 @@ +From: =?utf-8?q?Bastien_Roucari=C3=A8s?= +Date: Tue, 26 May 2026 18:01:06 +0200 +Subject: Fix backport of distribute cache + +forwarded: not-needed +--- + magick/distribute-cache.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/magick/distribute-cache.c b/magick/distribute-cache.c +index d384af1..5282d12 100755 +--- a/magick/distribute-cache.c ++++ b/magick/distribute-cache.c +@@ -126,6 +126,9 @@ static SemaphoreInfo + static WSADATA + *wsaData = (WSADATA*) NULL; + #endif ++ ++# define magick_fallthrough /* nothing */ ++ + + /* + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@@ -504,8 +507,7 @@ MagickPrivate DistributeCacheInfo *AcquireDistributeCacheInfo( + { + server_info->session_key=session_key; + (void) CopyMagickString(server_info->hostname,hostname,MagickPathExtent); +- server_info->debug=GetLogEventMask() & CacheEvent ? MagickTrue : +- MagickFalse; ++ server_info->debug=IsEventLogging(); + } + hostname=DestroyString(hostname); + return(server_info); diff -Nru imagemagick-6.9.11.60+dfsg/debian/patches/port-distribute-cache-to-6.9.13-48.patch imagemagick-6.9.11.60+dfsg/debian/patches/port-distribute-cache-to-6.9.13-48.patch --- imagemagick-6.9.11.60+dfsg/debian/patches/port-distribute-cache-to-6.9.13-48.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-6.9.11.60+dfsg/debian/patches/port-distribute-cache-to-6.9.13-48.patch 2026-05-27 20:34:21.000000000 +0000 @@ -0,0 +1,1405 @@ +From: =?utf-8?q?Bastien_Roucari=C3=A8s?= +Date: Tue, 26 May 2026 15:43:58 +0200 +Subject: port distribute cache to 6.9.13-48 + +will fix: +- CVE-2026-46692 +- CVE-2026-46693 +- CVE-2026-47165 +- CVE-2026-47166 + +origin: https://github.com/ImageMagick/ImageMagick6/blob/6.9.13-48/magick/distribute-cache.c +--- + magick/distribute-cache-private.h | 12 +- + magick/distribute-cache.c | 729 +++++++++++++++++++++++++------------- + magick/distribute-cache.h | 10 +- + 3 files changed, 484 insertions(+), 267 deletions(-) + +diff --git a/magick/distribute-cache-private.h b/magick/distribute-cache-private.h +index b9a318f..81494d4 100644 +--- a/magick/distribute-cache-private.h ++++ b/magick/distribute-cache-private.h +@@ -1,12 +1,12 @@ + /* +- Copyright 1999-2021 ImageMagick Studio LLC, a non-profit organization ++ 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. +@@ -30,7 +30,7 @@ typedef struct _DistributeCacheInfo + int + file; + +- size_t ++ uint64_t + session_key; + + char +diff --git a/magick/distribute-cache.c b/magick/distribute-cache.c +index 2d7e35d..d384af1 100755 +--- a/magick/distribute-cache.c ++++ b/magick/distribute-cache.c +@@ -22,13 +22,13 @@ + % January 2013 % + % % + % % +-% Copyright 1999-2021 ImageMagick Studio LLC, a non-profit organization % ++% 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, % +@@ -79,15 +79,13 @@ + #include + #include + #include +-#define CHAR_TYPE_CAST + #define CLOSE_SOCKET(socket) (void) close(socket) + #define HANDLER_RETURN_TYPE void * + #define HANDLER_RETURN_VALUE (void *) NULL + #define SOCKET_TYPE int + #define LENGTH_TYPE size_t + #define MAGICKCORE_HAVE_DISTRIBUTE_CACHE +-#elif defined(MAGICKCORE_WINDOWS_SUPPORT) && !defined(__MINGW32__) +-#define CHAR_TYPE_CAST (char *) ++#elif defined(MAGICKCORE_WINDOWS_SUPPORT) && !defined(__MINGW32__) && !defined(__MINGW64__) + #define CLOSE_SOCKET(socket) (void) closesocket(socket) + #define HANDLER_RETURN_TYPE DWORD WINAPI + #define HANDLER_RETURN_VALUE 0 +@@ -121,6 +119,14 @@ + # define MSG_NOSIGNAL 0 + #endif + ++#ifdef MAGICKCORE_HAVE_WINSOCK2 ++static SemaphoreInfo ++ *winsock2_semaphore = (SemaphoreInfo *) NULL; ++ ++static WSADATA ++ *wsaData = (WSADATA*) NULL; ++#endif ++ + /* + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % % +@@ -157,12 +163,11 @@ static inline MagickOffsetType dpc_read(int file,const MagickSizeType length, + magick_unreferenced(file); + magick_unreferenced(message); + #endif +- + count=0; + for (i=0; i < (MagickOffsetType) length; i+=count) + { +- count=recv(file,CHAR_TYPE_CAST message+i,(LENGTH_TYPE) MagickMin(length-i, +- (MagickSizeType) MAGICK_SSIZE_MAX),0); ++ count=recv(file,(char *) message+i,(LENGTH_TYPE) MagickMin(length-i, ++ (MagickSizeType) MagickMaxBufferExtent),0); + if (count <= 0) + { + count=0; +@@ -173,14 +178,144 @@ static inline MagickOffsetType dpc_read(int file,const MagickSizeType length, + return(i); + } + ++#if defined(MAGICKCORE_HAVE_WINSOCK2) ++static void InitializeWinsock2(MagickBooleanType use_lock) ++{ ++ if (use_lock != MagickFalse) ++ { ++ if (winsock2_semaphore == (SemaphoreInfo *) NULL) ++ ActivateSemaphoreInfo(&winsock2_semaphore); ++ LockSemaphoreInfo(winsock2_semaphore); ++ } ++ if (wsaData == (WSADATA *) NULL) ++ { ++ wsaData=(WSADATA *) AcquireMagickMemory(sizeof(WSADATA)); ++ if (WSAStartup(MAKEWORD(2,2),wsaData) != 0) ++ ThrowFatalException(CacheFatalError,"WSAStartup failed"); ++ } ++ if (use_lock != MagickFalse) ++ UnlockSemaphoreInfo(winsock2_semaphore); ++} ++#endif ++ ++static inline uint64_t ROTL(uint64_t x,int b) ++{ ++ return((x << b) | (x >> (64-b))); ++} ++ ++static inline uint64_t U8TO64_LE(const uint8_t *p) ++{ ++ return(((uint64_t) p[0] << 0) | ((uint64_t) p[1] << 8) | ++ ((uint64_t) p[2] << 16) | ((uint64_t) p[3] << 24) | ++ ((uint64_t) p[4] << 32) | ((uint64_t) p[5] << 40) | ++ ((uint64_t) p[6] << 48) | ((uint64_t) p[7] << 56)); ++} ++ ++static inline uint64_t SIPHash24(const uint8_t key[16],const uint8_t *message, ++ const size_t length) ++{ ++ const uint8_t ++ *end = message+length-(length % 8); ++ ++ size_t ++ i; ++ ++ uint64_t ++ b = ((uint64_t) length) << 56, ++ k0 = U8TO64_LE(key), ++ k1 = U8TO64_LE(key+8), ++ m, ++ v0 = 0x736f6d6570736575ULL^k0, ++ v1 = 0x646f72616e646f6dULL^k1, ++ v2 = 0x6c7967656e657261ULL^k0, ++ v3 = 0x7465646279746573ULL^k1; ++ ++ for ( ; message != end; message+=8) ++ { ++ m=U8TO64_LE(message); ++ v3^=m; ++ for (i=0; i < 2; i++) ++ { ++ v0+=v1; v1=ROTL(v1,13); v1^=v0; v0=ROTL(v0,32); ++ v2+=v3; v3=ROTL(v3,16); v3^=v2; ++ v0+=v3; v3=ROTL(v3,21); v3^=v0; ++ v2+=v1; v1=ROTL(v1,17); v1^=v2; v2=ROTL(v2,32); ++ } ++ v0^=m; ++ } ++ switch (length & 0x07) ++ { ++ case 7: b|=((uint64_t) message[6]) << 48; magick_fallthrough; ++ case 6: b|=((uint64_t) message[5]) << 40; magick_fallthrough; ++ case 5: b|=((uint64_t) message[4]) << 32; magick_fallthrough; ++ case 4: b|=((uint64_t) message[3]) << 24; magick_fallthrough; ++ case 3: b|=((uint64_t) message[2]) << 16; magick_fallthrough; ++ case 2: b|=((uint64_t) message[1]) << 8; magick_fallthrough; ++ case 1: b|=((uint64_t) message[0]); magick_fallthrough; ++ default: break; ++ } ++ v3^=b; ++ for (i=0; i < 2; i++) ++ { ++ v0+=v1; v1=ROTL(v1,13); v1^=v0; v0=ROTL(v0,32); ++ v2+=v3; v3=ROTL(v3,16); v3^=v2; ++ v0+=v3; v3=ROTL(v3,21); v3^=v0; ++ v2+=v1; v1=ROTL(v1,17); v1^=v2; v2=ROTL(v2,32); ++ } ++ v0^=b; ++ v2^=0xff; ++ for (i=0; i < 4; i++) ++ { ++ v0+=v1; v1=ROTL(v1,13); v1^=v0; v0=ROTL(v0,32); ++ v2+=v3; v3=ROTL(v3,16); v3^=v2; ++ v0+=v3; v3=ROTL(v3,21); v3^=v0; ++ v2+=v1; v1=ROTL(v1,17); v1^=v2; v2=ROTL(v2,32); ++ } ++ return(v0^v1^v2^v3); ++} ++ ++static inline void DeriveSipKeyFromSecret(const char *shared_secret, ++ uint8_t key[16]) ++{ ++ size_t ++ i, ++ length; ++ ++ uint64_t ++ k0 = 0x0706050403020100ULL, ++ k1 = 0x0f0e0d0c0b0a0908ULL; ++ ++ length=strlen(shared_secret); ++ for (i=0; i < length; i++) ++ { ++ uint8_t ++ b = shared_secret[i]; ++ ++ k0^=b; ++ k0*=0x100000001b3ULL; ++ k1^=(uint64_t) b << ((i & 7)*8); ++ k1=(k1 << 5) | (k1 >> (64-5)); ++ } ++ (void) memcpy(key,&k0,8); ++ (void) memcpy(key+8,&k1,8); ++} ++ ++static inline uint64_t GenerateSessionKey(const char *shared_secret, ++ const unsigned char *nonce,size_t length) ++{ ++ uint8_t ++ key[16]; ++ ++ DeriveSipKeyFromSecret(shared_secret,key); ++ return(SIPHash24(key,nonce,length)); ++} ++ + static int ConnectPixelCacheServer(const char *hostname,const int port, +- size_t *session_key,ExceptionInfo *exception) ++ uint64_t *session_key,ExceptionInfo *exception) + { + #if defined(MAGICKCORE_HAVE_DISTRIBUTE_CACHE) + char +- service[MaxTextExtent]; +- +- char ++ service[MagickPathExtent], + *shared_secret; + + int +@@ -193,37 +328,29 @@ static int ConnectPixelCacheServer(const char *hostname,const int port, + count; + + struct addrinfo +- hint, ++ hints, + *result; + + unsigned char +- secret[MaxTextExtent]; ++ nonce[DPCSessionKeyLength]; + + /* +- Connect to distributed pixel cache and get session key. ++ Connect to distributed pixel cache server and get session key. + */ + *session_key=0; +- shared_secret=GetPolicyValue("cache:shared-secret"); +- if (shared_secret == (char *) NULL) +- { +- (void) ThrowMagickException(exception,GetMagickModule(),CacheError, +- "DistributedPixelCache","'%s'","shared secret expected"); +- return(-1); +- } +- shared_secret=DestroyString(shared_secret); +-#if defined(MAGICKCORE_WINDOWS_SUPPORT) +- NTInitializeWinsock(MagickTrue); ++#if defined(MAGICKCORE_HAVE_WINSOCK2) ++ InitializeWinsock2(MagickTrue); + #endif +- (void) memset(&hint,0,sizeof(hint)); +- hint.ai_family=AF_INET; +- hint.ai_socktype=SOCK_STREAM; +- hint.ai_flags=AI_PASSIVE; +- (void) FormatLocaleString(service,MaxTextExtent,"%d",port); +- status=getaddrinfo(hostname,service,&hint,&result); ++ (void) memset(&hints,0,sizeof(hints)); ++ hints.ai_family=AF_INET; ++ hints.ai_socktype=SOCK_STREAM; ++ hints.ai_flags=AI_PASSIVE; ++ (void) FormatLocaleString(service,MagickPathExtent,"%d",port); ++ status=getaddrinfo(hostname,service,&hints,&result); + if (status != 0) + { + (void) ThrowMagickException(exception,GetMagickModule(),CacheError, +- "DistributedPixelCache","'%s'",hostname); ++ "DistributedPixelCache","'%s': %s",hostname,gai_strerror(status)); + return(-1); + } + client_socket=socket(result->ai_family,result->ai_socktype, +@@ -232,44 +359,59 @@ static int ConnectPixelCacheServer(const char *hostname,const int port, + { + freeaddrinfo(result); + (void) ThrowMagickException(exception,GetMagickModule(),CacheError, +- "DistributedPixelCache","'%s'",hostname); ++ "DistributedPixelCache","'%s': %s",hostname,GetExceptionMessage(errno)); + return(-1); + } + status=connect(client_socket,result->ai_addr,(socklen_t) result->ai_addrlen); ++ freeaddrinfo(result); + if (status == -1) + { + CLOSE_SOCKET(client_socket); +- freeaddrinfo(result); + (void) ThrowMagickException(exception,GetMagickModule(),CacheError, +- "DistributedPixelCache","'%s'",hostname); ++ "DistributedPixelCache","'%s': %s",hostname,GetExceptionMessage(errno)); + return(-1); + } +- count=recv(client_socket,CHAR_TYPE_CAST secret,MaxTextExtent,0); +- if (count != -1) ++ /* ++ Receive server nonce. ++ */ ++ count=recv(client_socket,(char *) nonce,sizeof(nonce),0); ++ if (count != (ssize_t) sizeof(nonce)) + { +- StringInfo +- *nonce; +- +- nonce=AcquireStringInfo(count); +- (void) memcpy(GetStringInfoDatum(nonce),secret,(size_t) count); +- *session_key=GetMagickCoreSignature(nonce); +- nonce=DestroyStringInfo(nonce); ++ CLOSE_SOCKET(client_socket); ++ (void) ThrowMagickException(exception,GetMagickModule(),CacheError, ++ "DistributedPixelCache","'%s': %s",hostname,GetExceptionMessage(errno)); ++ return(-1); + } +- if (*session_key == 0) ++ /* ++ Compute keyed hash(shared_secret,nonce). ++ */ ++ shared_secret=GetPolicyValue("cache:shared-secret"); ++ if (shared_secret == (char*) NULL) + { + CLOSE_SOCKET(client_socket); +- client_socket=(SOCKET_TYPE) (-1); ++ (void) ThrowMagickException(exception,GetMagickModule(),CacheError, ++ "DistributedPixelCache","'%s': shared secret required",hostname); ++ return(-1); + } +- freeaddrinfo(result); +- return(client_socket); ++ *session_key=GenerateSessionKey(shared_secret,nonce,sizeof(nonce)); ++ shared_secret=DestroyString(shared_secret); ++ /* ++ Send keyed hash back to server. ++ */ ++ count=send(client_socket,(char *) session_key,sizeof(*session_key), ++ MSG_NOSIGNAL); ++ if (count != (ssize_t) sizeof(*session_key)) ++ { ++ CLOSE_SOCKET(client_socket); ++ (void) ThrowMagickException(exception,GetMagickModule(),CacheError, ++ "DistributedPixelCache","'%s': authentication failed",hostname); ++ return(-1); ++ } ++ return((int) client_socket); + #else +- magick_unreferenced(hostname); +- magick_unreferenced(port); +- magick_unreferenced(session_key); +- magick_unreferenced(exception); + (void) ThrowMagickException(exception,GetMagickModule(),MissingDelegateError, + "DelegateLibrarySupportNotBuiltIn","distributed pixel cache"); +- return(MagickFalse); ++ return(-1); + #endif + } + +@@ -306,7 +448,11 @@ static char *GetHostname(int *port,ExceptionInfo *exception) + *port=DPCPort; + return(AcquireString(DPCHostname)); + } +- hosts=AcquireString(hostlist[(id++ % (argc-1))+1]); ++ { ++ size_t host_count = (size_t) argc-1; ++ size_t index = (id++ % host_count)+1; ++ hosts=AcquireString(hostlist[index]); ++ } + for (i=0; i < (ssize_t) argc; i++) + hostlist[i]=DestroyString(hostlist[i]); + hostlist=(char **) RelinquishMagickMemory(hostlist); +@@ -337,15 +483,14 @@ MagickPrivate DistributeCacheInfo *AcquireDistributeCacheInfo( + DistributeCacheInfo + *server_info; + +- size_t ++ uint64_t + session_key; + + /* + Connect to the distributed pixel cache server. + */ +- server_info=(DistributeCacheInfo *) AcquireMagickMemory(sizeof(*server_info)); +- if (server_info == (DistributeCacheInfo *) NULL) +- ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); ++ server_info=(DistributeCacheInfo *) AcquireCriticalMemory( ++ sizeof(*server_info)); + (void) memset(server_info,0,sizeof(*server_info)); + server_info->signature=MagickCoreSignature; + server_info->port=0; +@@ -358,8 +503,9 @@ MagickPrivate DistributeCacheInfo *AcquireDistributeCacheInfo( + else + { + server_info->session_key=session_key; +- (void) CopyMagickString(server_info->hostname,hostname,MaxTextExtent); +- server_info->debug=IsEventLogging(); ++ (void) CopyMagickString(server_info->hostname,hostname,MagickPathExtent); ++ server_info->debug=GetLogEventMask() & CacheEvent ? MagickTrue : ++ MagickFalse; + } + hostname=DestroyString(hostname); + return(server_info); +@@ -394,7 +540,7 @@ MagickPrivate DistributeCacheInfo *DestroyDistributeCacheInfo( + { + assert(server_info != (DistributeCacheInfo *) NULL); + assert(server_info->signature == MagickCoreSignature); +- if (server_info->file > 0) ++ if (server_info->file >= 0) + CLOSE_SOCKET(server_info->file); + server_info->signature=(~MagickCoreSignature); + server_info=(DistributeCacheInfo *) RelinquishMagickMemory(server_info); +@@ -428,16 +574,19 @@ MagickPrivate DistributeCacheInfo *DestroyDistributeCacheInfo( + */ + + static MagickBooleanType DestroyDistributeCache(SplayTreeInfo *registry, +- const size_t session_key) ++ const uint64_t session_key) + { ++ MagickAddressType ++ key = (MagickAddressType) session_key; ++ + /* + Destroy distributed pixel cache. + */ +- return(DeleteNodeFromSplayTree(registry,(const void *) session_key)); ++ return(DeleteNodeFromSplayTree(registry,(const void *) key)); + } + + static inline MagickOffsetType dpc_send(int file,const MagickSizeType length, +- const unsigned char *magick_restrict message) ++ const void *magick_restrict message) + { + MagickOffsetType + count; +@@ -456,8 +605,8 @@ static inline MagickOffsetType dpc_send(int file,const MagickSizeType length, + count=0; + for (i=0; i < (MagickOffsetType) length; i+=count) + { +- count=(MagickOffsetType) send(file,CHAR_TYPE_CAST message+i,(LENGTH_TYPE) +- MagickMin(length-i,(MagickSizeType) MAGICK_SSIZE_MAX),MSG_NOSIGNAL); ++ count=(MagickOffsetType) send(file,(char *) message+i,(LENGTH_TYPE) ++ MagickMin(length-i,(MagickSizeType) MagickMaxBufferExtent),MSG_NOSIGNAL); + if (count <= 0) + { + count=0; +@@ -469,11 +618,14 @@ static inline MagickOffsetType dpc_send(int file,const MagickSizeType length, + } + + static MagickBooleanType OpenDistributeCache(SplayTreeInfo *registry,int file, +- const size_t session_key,ExceptionInfo *exception) ++ const uint64_t session_key,ExceptionInfo *exception) + { + Image + *image; + ++ MagickAddressType ++ key = (MagickAddressType) session_key; ++ + MagickBooleanType + status; + +@@ -484,11 +636,9 @@ static MagickBooleanType OpenDistributeCache(SplayTreeInfo *registry,int file, + length; + + unsigned char ++ message[MagickPathExtent], + *p; + +- unsigned char +- message[MaxTextExtent]; +- + /* + Open distributed pixel cache. + */ +@@ -499,36 +649,70 @@ static MagickBooleanType OpenDistributeCache(SplayTreeInfo *registry,int file, + sizeof(image->channels)+sizeof(image->columns)+sizeof(image->rows); + count=dpc_read(file,length,message); + if (count != (MagickOffsetType) length) +- return(MagickFalse); ++ { ++ image=DestroyImage(image); ++ return(MagickFalse); ++ } + /* + Deserialize the image attributes. + */ + p=message; + (void) memcpy(&image->storage_class,p,sizeof(image->storage_class)); +- p+=sizeof(image->storage_class); ++ p+=(ptrdiff_t) sizeof(image->storage_class); + (void) memcpy(&image->colorspace,p,sizeof(image->colorspace)); +- p+=sizeof(image->colorspace); ++ p+=(ptrdiff_t) sizeof(image->colorspace); + (void) memcpy(&image->channels,p,sizeof(image->channels)); +- p+=sizeof(image->channels); ++ p+=(ptrdiff_t) sizeof(image->channels); + (void) memcpy(&image->columns,p,sizeof(image->columns)); +- p+=sizeof(image->columns); ++ p+=(ptrdiff_t) sizeof(image->columns); + (void) memcpy(&image->rows,p,sizeof(image->rows)); +- p+=sizeof(image->rows); ++ p+=(ptrdiff_t) sizeof(image->rows); + if (SyncImagePixelCache(image,exception) == MagickFalse) +- return(MagickFalse); +- status=AddValueToSplayTree(registry,(const void *) session_key,image); ++ { ++ image=DestroyImage(image); ++ return(MagickFalse); ++ } ++ status=AddValueToSplayTree(registry,(const void *) key,image); ++ if (status == MagickFalse) ++ { ++ image=DestroyImage(image); ++ return(MagickFalse); ++ } + return(status); + } + ++static inline MagickBooleanType ValidateDistributedPixelCache( ++ const RectangleInfo *region,const size_t per_pixel, ++ const MagickSizeType length) ++{ ++ size_t ++ extent = 0, ++ pixels = 0; ++ ++ if (HeapOverflowSanityCheckGetSize(region->width,region->height,&pixels) != MagickFalse) ++ return(MagickFalse); ++ if (HeapOverflowSanityCheckGetSize(pixels,per_pixel,&extent) != MagickFalse) ++ return(MagickFalse); ++ if (length > (MagickSizeType) extent) ++ return(MagickFalse); ++ return(MagickTrue); ++} ++ + static MagickBooleanType ReadDistributeCacheIndexes(SplayTreeInfo *registry, +- int file,const size_t session_key,ExceptionInfo *exception) ++ int file,const uint64_t session_key,ExceptionInfo *exception) + { + const IndexPacket + *indexes; + ++ const PixelPacket ++ *p; ++ + Image + *image; + ++ MagickAddressType ++ key = (MagickAddressType) session_key; ++ + MagickOffsetType + count; + +@@ -538,19 +722,17 @@ static MagickBooleanType ReadDistributeCacheIndexes(SplayTreeInfo *registry, + RectangleInfo + region; + +- const PixelPacket +- *p; ++ size_t ++ per_pixel; + + unsigned char ++ message[MagickPathExtent], + *q; + +- unsigned char +- message[MaxTextExtent]; +- + /* + Read distributed pixel cache indexes. + */ +- image=(Image *) GetValueFromSplayTree(registry,(const void *) session_key); ++ image=(Image *) GetValueFromSplayTree(registry,(const void *) key); + if (image == (Image *) NULL) + return(MagickFalse); + length=sizeof(region.width)+sizeof(region.height)+sizeof(region.x)+ +@@ -560,32 +742,41 @@ static MagickBooleanType ReadDistributeCacheIndexes(SplayTreeInfo *registry, + return(MagickFalse); + q=message; + (void) memcpy(®ion.width,q,sizeof(region.width)); +- q+=sizeof(region.width); ++ q+=(ptrdiff_t) sizeof(region.width); + (void) memcpy(®ion.height,q,sizeof(region.height)); +- q+=sizeof(region.height); ++ q+=(ptrdiff_t) sizeof(region.height); + (void) memcpy(®ion.x,q,sizeof(region.x)); +- q+=sizeof(region.x); ++ q+=(ptrdiff_t) sizeof(region.x); + (void) memcpy(®ion.y,q,sizeof(region.y)); +- q+=sizeof(region.y); ++ q+=(ptrdiff_t) sizeof(region.y); + (void) memcpy(&length,q,sizeof(length)); +- q+=sizeof(length); ++ per_pixel=sizeof(IndexPacket); ++ if (ValidateDistributedPixelCache(®ion,per_pixel,length) == MagickFalse) ++ return(MagickFalse); ++ q+=(ptrdiff_t) sizeof(length); + p=GetVirtualPixels(image,region.x,region.y,region.width,region.height, + exception); + if (p == (const PixelPacket *) NULL) + return(MagickFalse); + indexes=GetVirtualIndexQueue(image); +- count=dpc_send(file,length,(unsigned char *) indexes); ++ count=dpc_send(file,length,indexes); + if (count != (MagickOffsetType) length) + return(MagickFalse); + return(MagickTrue); + } + + static MagickBooleanType ReadDistributeCachePixels(SplayTreeInfo *registry, +- int file,const size_t session_key,ExceptionInfo *exception) ++ int file,const uint64_t session_key,ExceptionInfo *exception) + { ++ const PixelPacket ++ *p; ++ + Image + *image; + ++ MagickAddressType ++ key = (MagickAddressType) session_key; ++ + MagickOffsetType + count; + +@@ -595,19 +786,17 @@ static MagickBooleanType ReadDistributeCachePixels(SplayTreeInfo *registry, + RectangleInfo + region; + +- const PixelPacket +- *p; ++ size_t ++ per_pixel; + + unsigned char ++ message[MagickPathExtent], + *q; + +- unsigned char +- message[MaxTextExtent]; +- + /* + Read distributed pixel cache pixels. + */ +- image=(Image *) GetValueFromSplayTree(registry,(const void *) session_key); ++ image=(Image *) GetValueFromSplayTree(registry,(const void *) key); + if (image == (Image *) NULL) + return(MagickFalse); + length=sizeof(region.width)+sizeof(region.height)+sizeof(region.x)+ +@@ -617,20 +806,23 @@ static MagickBooleanType ReadDistributeCachePixels(SplayTreeInfo *registry, + return(MagickFalse); + q=message; + (void) memcpy(®ion.width,q,sizeof(region.width)); +- q+=sizeof(region.width); ++ q+=(ptrdiff_t) sizeof(region.width); + (void) memcpy(®ion.height,q,sizeof(region.height)); +- q+=sizeof(region.height); ++ q+=(ptrdiff_t) sizeof(region.height); + (void) memcpy(®ion.x,q,sizeof(region.x)); +- q+=sizeof(region.x); ++ q+=(ptrdiff_t) sizeof(region.x); + (void) memcpy(®ion.y,q,sizeof(region.y)); +- q+=sizeof(region.y); ++ q+=(ptrdiff_t) sizeof(region.y); + (void) memcpy(&length,q,sizeof(length)); +- q+=sizeof(length); ++ q+=(ptrdiff_t) sizeof(length); ++ per_pixel=sizeof(PixelPacket); ++ if (ValidateDistributedPixelCache(®ion,per_pixel,length) == MagickFalse) ++ return(MagickFalse); + p=GetVirtualPixels(image,region.x,region.y,region.width,region.height, + exception); + if (p == (const PixelPacket *) NULL) + return(MagickFalse); +- count=dpc_send(file,length,(unsigned char *) p); ++ count=dpc_send(file,length,p); + if (count != (MagickOffsetType) length) + return(MagickFalse); + return(MagickTrue); +@@ -642,7 +834,7 @@ static void *RelinquishImageRegistry(void *image) + } + + static MagickBooleanType WriteDistributeCacheIndexes(SplayTreeInfo *registry, +- int file,const size_t session_key,ExceptionInfo *exception) ++ int file,const uint64_t session_key,ExceptionInfo *exception) + { + Image + *image; +@@ -650,28 +842,32 @@ static MagickBooleanType WriteDistributeCacheIndexes(SplayTreeInfo *registry, + IndexPacket + *indexes; + ++ MagickAddressType ++ key = (MagickAddressType) session_key; ++ + MagickOffsetType + count; + + MagickSizeType + length; + ++ PixelPacket ++ *q; ++ + RectangleInfo + region; + +- unsigned char +- *p; +- +- PixelPacket +- *q; ++ size_t ++ per_pixel; + + unsigned char +- message[MaxTextExtent]; ++ message[MagickPathExtent], ++ *p; + + /* + Write distributed pixel cache indexes. + */ +- image=(Image *) GetValueFromSplayTree(registry,(const void *) session_key); ++ image=(Image *) GetValueFromSplayTree(registry,(const void *) key); + if (image == (Image *) NULL) + return(MagickFalse); + length=sizeof(region.width)+sizeof(region.height)+sizeof(region.x)+ +@@ -681,15 +877,18 @@ static MagickBooleanType WriteDistributeCacheIndexes(SplayTreeInfo *registry, + return(MagickFalse); + p=message; + (void) memcpy(®ion.width,p,sizeof(region.width)); +- p+=sizeof(region.width); ++ p+=(ptrdiff_t) sizeof(region.width); + (void) memcpy(®ion.height,p,sizeof(region.height)); +- p+=sizeof(region.height); ++ p+=(ptrdiff_t) sizeof(region.height); + (void) memcpy(®ion.x,p,sizeof(region.x)); +- p+=sizeof(region.x); ++ p+=(ptrdiff_t) sizeof(region.x); + (void) memcpy(®ion.y,p,sizeof(region.y)); +- p+=sizeof(region.y); ++ p+=(ptrdiff_t) sizeof(region.y); + (void) memcpy(&length,p,sizeof(length)); +- p+=sizeof(length); ++ per_pixel=sizeof(IndexPacket); ++ if (ValidateDistributedPixelCache(®ion,per_pixel,length) == MagickFalse) ++ return(MagickFalse); ++ p+=(ptrdiff_t) sizeof(length); + q=GetAuthenticPixels(image,region.x,region.y,region.width,region.height, + exception); + if (q == (PixelPacket *) NULL) +@@ -702,33 +901,37 @@ static MagickBooleanType WriteDistributeCacheIndexes(SplayTreeInfo *registry, + } + + static MagickBooleanType WriteDistributeCachePixels(SplayTreeInfo *registry, +- int file,const size_t session_key,ExceptionInfo *exception) ++ int file,const uint64_t session_key,ExceptionInfo *exception) + { + Image + *image; + ++ MagickAddressType ++ key = (MagickAddressType) session_key; ++ + MagickOffsetType + count; + + MagickSizeType + length; + ++ PixelPacket ++ *q; ++ + RectangleInfo + region; + +- PixelPacket +- *q; ++ size_t ++ per_pixel; + + unsigned char ++ message[MagickPathExtent], + *p; + +- unsigned char +- message[MaxTextExtent]; +- + /* + Write distributed pixel cache pixels. + */ +- image=(Image *) GetValueFromSplayTree(registry,(const void *) session_key); ++ image=(Image *) GetValueFromSplayTree(registry,(const void *) key); + if (image == (Image *) NULL) + return(MagickFalse); + length=sizeof(region.width)+sizeof(region.height)+sizeof(region.x)+ +@@ -738,15 +941,18 @@ static MagickBooleanType WriteDistributeCachePixels(SplayTreeInfo *registry, + return(MagickFalse); + p=message; + (void) memcpy(®ion.width,p,sizeof(region.width)); +- p+=sizeof(region.width); ++ p+=(ptrdiff_t) sizeof(region.width); + (void) memcpy(®ion.height,p,sizeof(region.height)); +- p+=sizeof(region.height); ++ p+=(ptrdiff_t) sizeof(region.height); + (void) memcpy(®ion.x,p,sizeof(region.x)); +- p+=sizeof(region.x); ++ p+=(ptrdiff_t) sizeof(region.x); + (void) memcpy(®ion.y,p,sizeof(region.y)); +- p+=sizeof(region.y); ++ p+=(ptrdiff_t) sizeof(region.y); + (void) memcpy(&length,p,sizeof(length)); +- p+=sizeof(length); ++ p+=(ptrdiff_t) sizeof(length); ++ per_pixel=sizeof(PixelPacket); ++ if (ValidateDistributedPixelCache(®ion,per_pixel,length) == MagickFalse) ++ return(MagickFalse); + q=GetAuthenticPixels(image,region.x,region.y,region.width,region.height, + exception); + if (q == (PixelPacket *) NULL) +@@ -757,7 +963,7 @@ static MagickBooleanType WriteDistributeCachePixels(SplayTreeInfo *registry, + return(SyncAuthenticPixels(image,exception)); + } + +-static HANDLER_RETURN_TYPE DistributePixelCacheClient(void *socket) ++static HANDLER_RETURN_TYPE DistributePixelCacheClient(void *socket_arg) + { + char + *shared_secret; +@@ -766,7 +972,7 @@ static HANDLER_RETURN_TYPE DistributePixelCacheClient(void *socket) + *exception; + + MagickBooleanType +- status; ++ status = MagickFalse; + + MagickOffsetType + count; +@@ -774,63 +980,87 @@ static HANDLER_RETURN_TYPE DistributePixelCacheClient(void *socket) + RandomInfo + *random_info; + +- unsigned char +- *p; +- +- size_t +- key, +- session_key; +- + SOCKET_TYPE +- client_socket; ++ client_socket, ++ *client_socket_ptr = (SOCKET_TYPE *) socket_arg; + + SplayTreeInfo + *registry; + + StringInfo +- *secret; ++ *entropy; ++ ++ uint64_t ++ key, ++ session_key; + + unsigned char + command, +- session[2*MaxTextExtent]; ++ nonce[DPCSessionKeyLength]; + + /* +- Distributed pixel cache client. ++ Load shared secret. + */ ++ client_socket=(*client_socket_ptr); ++ client_socket_ptr=(SOCKET_TYPE *) RelinquishMagickMemory(client_socket_ptr); + shared_secret=GetPolicyValue("cache:shared-secret"); +- if (shared_secret == (char *) NULL) +- ThrowFatalException(CacheFatalError,"shared secret expected"); +- p=session; +- (void) CopyMagickString((char *) p,shared_secret,MaxTextExtent); +- p+=strlen(shared_secret); +- shared_secret=DestroyString(shared_secret); ++ if (shared_secret == NULL) ++ ThrowFatalException(CacheFatalError,"shared secret required"); ++ /* ++ Generate random nonce. ++ */ + random_info=AcquireRandomInfo(); +- secret=GetRandomKey(random_info,DPCSessionKeyLength); +- (void) memcpy(p,GetStringInfoDatum(secret),DPCSessionKeyLength); +- session_key=GetMagickCoreSignature(secret); ++ entropy=GetRandomKey(random_info,sizeof(nonce)); ++ (void) memcpy(nonce,GetStringInfoDatum(entropy),sizeof(nonce)); ++ entropy=DestroyStringInfo(entropy); + random_info=DestroyRandomInfo(random_info); ++ /* ++ Derive session key. ++ */ ++ session_key=GenerateSessionKey(shared_secret,nonce,sizeof(nonce)); ++ shared_secret=DestroyString(shared_secret); ++ /* ++ Send nonce to client. ++ */ ++ count=dpc_send(client_socket,sizeof(nonce),nonce); ++ if (count != (MagickOffsetType) sizeof(nonce)) ++ { ++ CLOSE_SOCKET(client_socket); ++ return(HANDLER_RETURN_VALUE); ++ } ++ /* ++ Receive client's keyed hash. ++ */ ++ count=dpc_read(client_socket,sizeof(key),(unsigned char *) &key); ++ if ((count != (MagickOffsetType) sizeof(key)) || (key != session_key)) ++ { ++ CLOSE_SOCKET(client_socket); ++ return(HANDLER_RETURN_VALUE); ++ } + exception=AcquireExceptionInfo(); + registry=NewSplayTree((int (*)(const void *,const void *)) NULL, + (void *(*)(void *)) NULL,RelinquishImageRegistry); +- client_socket=(*(int *) socket); +- count=dpc_send(client_socket,DPCSessionKeyLength,GetStringInfoDatum(secret)); +- secret=DestroyStringInfo(secret); +- for ( ; ; ) ++ /* ++ Command loop. ++ */ ++ for (status=MagickFalse; ; ) + { ++ /* ++ Each command must echo the authenticated session key. ++ */ + count=dpc_read(client_socket,1,(unsigned char *) &command); + if (count <= 0) + break; + count=dpc_read(client_socket,sizeof(key),(unsigned char *) &key); + if ((count != (MagickOffsetType) sizeof(key)) || (key != session_key)) + break; +- status=MagickFalse; + switch (command) + { + case 'o': + { + status=OpenDistributeCache(registry,client_socket,session_key, + exception); +- count=dpc_send(client_socket,sizeof(status),(unsigned char *) &status); ++ dpc_send(client_socket,sizeof(status),&status); + break; + } + case 'r': +@@ -865,12 +1095,10 @@ static HANDLER_RETURN_TYPE DistributePixelCacheClient(void *socket) + default: + break; + } +- if (status == MagickFalse) +- break; +- if (command == 'd') ++ if ((status == MagickFalse) || (command == 'd')) + break; + } +- count=dpc_send(client_socket,sizeof(status),(unsigned char *) &status); ++ count=dpc_send(client_socket,sizeof(status),&status); + CLOSE_SOCKET(client_socket); + exception=DestroyExceptionInfo(exception); + registry=DestroySplayTree(registry); +@@ -880,9 +1108,8 @@ static HANDLER_RETURN_TYPE DistributePixelCacheClient(void *socket) + MagickExport void DistributePixelCacheServer(const int port, + ExceptionInfo *exception) + { +-#if defined(MAGICKCORE_HAVE_DISTRIBUTE_CACHE) + char +- service[MaxTextExtent]; ++ service[MagickPathExtent]; + + int + status; +@@ -892,20 +1119,20 @@ MagickExport void DistributePixelCacheServer(const int port, + attributes; + + pthread_t +- threads; +-#elif defined(MAGICKCORE_WINDOWS_SUPPORT) ++ thread_id; ++#elif defined(_MSC_VER) + DWORD + threadID; + #else + Not implemented! + #endif + +- struct addrinfo +- *p; +- + SOCKET_TYPE + server_socket; + ++ struct addrinfo ++ *p; ++ + struct addrinfo + hint, + *result; +@@ -919,29 +1146,28 @@ MagickExport void DistributePixelCacheServer(const int port, + assert(exception != (ExceptionInfo *) NULL); + assert(exception->signature == MagickCoreSignature); + magick_unreferenced(exception); +-#if defined(MAGICKCORE_WINDOWS_SUPPORT) +- NTInitializeWinsock(MagickFalse); ++#if defined(MAGICKCORE_HAVE_WINSOCK2) ++ InitializeWinsock2(MagickFalse); + #endif +- (void) memset(&hint,0,sizeof(hint)); ++ memset(&hint,0,sizeof(hint)); + hint.ai_family=AF_INET; + hint.ai_socktype=SOCK_STREAM; + hint.ai_flags=AI_PASSIVE; +- (void) FormatLocaleString(service,MaxTextExtent,"%d",port); +- status=getaddrinfo((const char *) NULL,service,&hint,&result); ++ FormatLocaleString(service,MagickPathExtent,"%d",port); ++ status=getaddrinfo(NULL,service,&hint,&result); + if (status != 0) +- ThrowFatalException(CacheFatalError,"UnableToListen"); ++ ThrowFatalException(CacheFatalError, "UnableToListen"); + server_socket=(SOCKET_TYPE) 0; +- for (p=result; p != (struct addrinfo *) NULL; p=p->ai_next) ++ for (p=result; p != NULL; p=p->ai_next) + { + int +- one; ++ one = 1; + + server_socket=socket(p->ai_family,p->ai_socktype,p->ai_protocol); + if (server_socket == -1) + continue; +- one=1; +- status=setsockopt(server_socket,SOL_SOCKET,SO_REUSEADDR, +- CHAR_TYPE_CAST &one,(socklen_t) sizeof(one)); ++ status=setsockopt(server_socket,SOL_SOCKET,SO_REUSEADDR,(char *) &one, ++ (socklen_t) sizeof(one)); + if (status == -1) + { + CLOSE_SOCKET(server_socket); +@@ -963,37 +1189,47 @@ MagickExport void DistributePixelCacheServer(const int port, + ThrowFatalException(CacheFatalError,"UnableToListen"); + #if defined(MAGICKCORE_THREAD_SUPPORT) + pthread_attr_init(&attributes); ++ pthread_attr_setdetachstate(&attributes,PTHREAD_CREATE_DETACHED); + #endif + for ( ; ; ) + { + SOCKET_TYPE +- client_socket; ++ *client_socket_ptr; + + socklen_t +- length; +- +- length=(socklen_t) sizeof(address); +- client_socket=accept(server_socket,(struct sockaddr *) &address,&length); +- if (client_socket == -1) +- ThrowFatalException(CacheFatalError,"UnableToEstablishConnection"); ++ length = (socklen_t) sizeof(address); ++ ++ client_socket_ptr=(SOCKET_TYPE *) AcquireMagickMemory(sizeof(SOCKET_TYPE)); ++ if (client_socket_ptr == NULL) ++ continue; /* skip connection */ ++ *client_socket_ptr=accept(server_socket,(struct sockaddr *) &address, ++ &length); ++ if (*client_socket_ptr == -1) ++ { ++ client_socket_ptr=(SOCKET_TYPE *) RelinquishMagickMemory( ++ client_socket_ptr); ++ continue; ++ } + #if defined(MAGICKCORE_THREAD_SUPPORT) +- status=pthread_create(&threads,&attributes,DistributePixelCacheClient, +- (void *) &client_socket); +- if (status == -1) +- ThrowFatalException(CacheFatalError,"UnableToCreateClientThread"); +-#elif defined(MAGICKCORE_WINDOWS_SUPPORT) +- if (CreateThread(0,0,DistributePixelCacheClient,(void*) &client_socket,0, +- &threadID) == (HANDLE) NULL) +- ThrowFatalException(CacheFatalError,"UnableToCreateClientThread"); ++ status=pthread_create(&thread_id, &attributes,DistributePixelCacheClient, ++ (void *) client_socket_ptr); ++ if (status != 0) ++ { ++ CLOSE_SOCKET(*client_socket_ptr); ++ RelinquishMagickMemory(client_socket_ptr); ++ ThrowFatalException(CacheFatalError,"UnableToCreateClientThread"); ++ } ++#elif defined(_MSC_VER) ++ if (CreateThread(0,0,DistributePixelCacheClient,(void*) client_socket_ptr,0,&threadID) == (HANDLE) NULL) ++ { ++ CLOSE_SOCKET(*client_socket_ptr); ++ RelinquishMagickMemory(client_socket_ptr); ++ ThrowFatalException(CacheFatalError,"UnableToCreateClientThread"); ++ } + #else + Not implemented! + #endif + } +-#else +- magick_unreferenced(port); +- magick_unreferenced(exception); +- ThrowFatalException(MissingDelegateError,"DelegateLibrarySupportNotBuiltIn"); +-#endif + } + + /* +@@ -1117,21 +1353,15 @@ MagickPrivate MagickBooleanType OpenDistributePixelCache( + DistributeCacheInfo *server_info,Image *image) + { + MagickBooleanType +-#ifdef __VMS +- status=MagickTrue; +-#else + status; +-#endif + + MagickOffsetType + count; + + unsigned char ++ message[MagickPathExtent], + *p; + +- unsigned char +- message[MaxTextExtent]; +- + /* + Open distributed pixel cache. + */ +@@ -1145,17 +1375,17 @@ MagickPrivate MagickBooleanType OpenDistributePixelCache( + Serialize image attributes (see ValidatePixelCacheMorphology()). + */ + (void) memcpy(p,&server_info->session_key,sizeof(server_info->session_key)); +- p+=sizeof(server_info->session_key); ++ p+=(ptrdiff_t) sizeof(server_info->session_key); + (void) memcpy(p,&image->storage_class,sizeof(image->storage_class)); +- p+=sizeof(image->storage_class); ++ p+=(ptrdiff_t) sizeof(image->storage_class); + (void) memcpy(p,&image->colorspace,sizeof(image->colorspace)); +- p+=sizeof(image->colorspace); ++ p+=(ptrdiff_t) sizeof(image->colorspace); + (void) memcpy(p,&image->channels,sizeof(image->channels)); +- p+=sizeof(image->channels); ++ p+=(ptrdiff_t) sizeof(image->channels); + (void) memcpy(p,&image->columns,sizeof(image->columns)); +- p+=sizeof(image->columns); ++ p+=(ptrdiff_t) sizeof(image->columns); + (void) memcpy(p,&image->rows,sizeof(image->rows)); +- p+=sizeof(image->rows); ++ p+=(ptrdiff_t) sizeof(image->rows); + count=dpc_send(server_info->file,p-message,message); + if (count != (MagickOffsetType) (p-message)) + return(MagickFalse); +@@ -1207,11 +1437,9 @@ MagickPrivate MagickOffsetType ReadDistributePixelCacheIndexes( + count; + + unsigned char ++ message[MagickPathExtent], + *p; + +- unsigned char +- message[MaxTextExtent]; +- + /* + Read distributed pixel cache indexes. + */ +@@ -1224,17 +1452,17 @@ MagickPrivate MagickOffsetType ReadDistributePixelCacheIndexes( + p=message; + *p++='R'; + (void) memcpy(p,&server_info->session_key,sizeof(server_info->session_key)); +- p+=sizeof(server_info->session_key); ++ p+=(ptrdiff_t) sizeof(server_info->session_key); + (void) memcpy(p,®ion->width,sizeof(region->width)); +- p+=sizeof(region->width); ++ p+=(ptrdiff_t) sizeof(region->width); + (void) memcpy(p,®ion->height,sizeof(region->height)); +- p+=sizeof(region->height); ++ p+=(ptrdiff_t) sizeof(region->height); + (void) memcpy(p,®ion->x,sizeof(region->x)); +- p+=sizeof(region->x); ++ p+=(ptrdiff_t) sizeof(region->x); + (void) memcpy(p,®ion->y,sizeof(region->y)); +- p+=sizeof(region->y); ++ p+=(ptrdiff_t) sizeof(region->y); + (void) memcpy(p,&length,sizeof(length)); +- p+=sizeof(length); ++ p+=(ptrdiff_t) sizeof(length); + count=dpc_send(server_info->file,p-message,message); + if (count != (MagickOffsetType) (p-message)) + return(-1); +@@ -1282,11 +1510,9 @@ MagickPrivate MagickOffsetType ReadDistributePixelCachePixels( + count; + + unsigned char ++ message[MagickPathExtent], + *p; + +- unsigned char +- message[MaxTextExtent]; +- + /* + Read distributed pixel cache pixels. + */ +@@ -1299,17 +1525,17 @@ MagickPrivate MagickOffsetType ReadDistributePixelCachePixels( + p=message; + *p++='r'; + (void) memcpy(p,&server_info->session_key,sizeof(server_info->session_key)); +- p+=sizeof(server_info->session_key); ++ p+=(ptrdiff_t) sizeof(server_info->session_key); + (void) memcpy(p,®ion->width,sizeof(region->width)); +- p+=sizeof(region->width); ++ p+=(ptrdiff_t) sizeof(region->width); + (void) memcpy(p,®ion->height,sizeof(region->height)); +- p+=sizeof(region->height); ++ p+=(ptrdiff_t) sizeof(region->height); + (void) memcpy(p,®ion->x,sizeof(region->x)); +- p+=sizeof(region->x); ++ p+=(ptrdiff_t) sizeof(region->x); + (void) memcpy(p,®ion->y,sizeof(region->y)); +- p+=sizeof(region->y); ++ p+=(ptrdiff_t) sizeof(region->y); + (void) memcpy(p,&length,sizeof(length)); +- p+=sizeof(length); ++ p+=(ptrdiff_t) sizeof(length); + count=dpc_send(server_info->file,p-message,message); + if (count != (MagickOffsetType) (p-message)) + return(-1); +@@ -1344,21 +1570,15 @@ MagickPrivate MagickBooleanType RelinquishDistributePixelCache( + DistributeCacheInfo *server_info) + { + MagickBooleanType +-#ifdef __VMS +- status = MagickTrue; +-#else + status; +-#endif + + MagickOffsetType + count; + + unsigned char ++ message[MagickPathExtent], + *p; + +- unsigned char +- message[MaxTextExtent]; +- + /* + Delete distributed pixel cache. + */ +@@ -1367,10 +1587,11 @@ MagickPrivate MagickBooleanType RelinquishDistributePixelCache( + p=message; + *p++='d'; + (void) memcpy(p,&server_info->session_key,sizeof(server_info->session_key)); +- p+=sizeof(server_info->session_key); ++ p+=(ptrdiff_t) sizeof(server_info->session_key); + count=dpc_send(server_info->file,p-message,message); + if (count != (MagickOffsetType) (p-message)) + return(MagickFalse); ++ status=MagickFalse; + count=dpc_read(server_info->file,sizeof(status),(unsigned char *) &status); + if (count != (MagickOffsetType) sizeof(status)) + return(MagickFalse); +@@ -1418,11 +1639,9 @@ MagickPrivate MagickOffsetType WriteDistributePixelCacheIndexes( + count; + + unsigned char ++ message[MagickPathExtent], + *p; + +- unsigned char +- message[MaxTextExtent]; +- + /* + Write distributed pixel cache indexes. + */ +@@ -1435,17 +1654,17 @@ MagickPrivate MagickOffsetType WriteDistributePixelCacheIndexes( + p=message; + *p++='W'; + (void) memcpy(p,&server_info->session_key,sizeof(server_info->session_key)); +- p+=sizeof(server_info->session_key); ++ p+=(ptrdiff_t) sizeof(server_info->session_key); + (void) memcpy(p,®ion->width,sizeof(region->width)); +- p+=sizeof(region->width); ++ p+=(ptrdiff_t) sizeof(region->width); + (void) memcpy(p,®ion->height,sizeof(region->height)); +- p+=sizeof(region->height); ++ p+=(ptrdiff_t) sizeof(region->height); + (void) memcpy(p,®ion->x,sizeof(region->x)); +- p+=sizeof(region->x); ++ p+=(ptrdiff_t) sizeof(region->x); + (void) memcpy(p,®ion->y,sizeof(region->y)); +- p+=sizeof(region->y); ++ p+=(ptrdiff_t) sizeof(region->y); + (void) memcpy(p,&length,sizeof(length)); +- p+=sizeof(length); ++ p+=(ptrdiff_t) sizeof(length); + count=dpc_send(server_info->file,p-message,message); + if (count != (MagickOffsetType) (p-message)) + return(-1); +@@ -1494,11 +1713,9 @@ MagickPrivate MagickOffsetType WriteDistributePixelCachePixels( + count; + + unsigned char ++ message[MagickPathExtent], + *p; + +- unsigned char +- message[MaxTextExtent]; +- + /* + Write distributed pixel cache pixels. + */ +@@ -1511,17 +1728,17 @@ MagickPrivate MagickOffsetType WriteDistributePixelCachePixels( + p=message; + *p++='w'; + (void) memcpy(p,&server_info->session_key,sizeof(server_info->session_key)); +- p+=sizeof(server_info->session_key); ++ p+=(ptrdiff_t) sizeof(server_info->session_key); + (void) memcpy(p,®ion->width,sizeof(region->width)); +- p+=sizeof(region->width); ++ p+=(ptrdiff_t) sizeof(region->width); + (void) memcpy(p,®ion->height,sizeof(region->height)); +- p+=sizeof(region->height); ++ p+=(ptrdiff_t) sizeof(region->height); + (void) memcpy(p,®ion->x,sizeof(region->x)); +- p+=sizeof(region->x); ++ p+=(ptrdiff_t) sizeof(region->x); + (void) memcpy(p,®ion->y,sizeof(region->y)); +- p+=sizeof(region->y); ++ p+=(ptrdiff_t) sizeof(region->y); + (void) memcpy(p,&length,sizeof(length)); +- p+=sizeof(length); ++ p+=(ptrdiff_t) sizeof(length); + count=dpc_send(server_info->file,p-message,message); + if (count != (MagickOffsetType) (p-message)) + return(-1); +diff --git a/magick/distribute-cache.h b/magick/distribute-cache.h +index 132c3aa..bb38e89 100644 +--- a/magick/distribute-cache.h ++++ b/magick/distribute-cache.h +@@ -1,12 +1,12 @@ + /* +- Copyright 1999-2021 ImageMagick Studio LLC, a non-profit organization ++ 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. diff -Nru imagemagick-6.9.11.60+dfsg/debian/patches/series imagemagick-6.9.11.60+dfsg/debian/patches/series --- imagemagick-6.9.11.60+dfsg/debian/patches/series 2026-04-25 14:03:16.000000000 +0000 +++ imagemagick-6.9.11.60+dfsg/debian/patches/series 2026-05-27 20:34:21.000000000 +0000 @@ -168,3 +168,20 @@ CVE-2026-34238.patch CVE-2026-40310.patch CVE-2026-40311.patch +CVE-2026-42050.patch +CVE-2026-33901_bug420_1.patch +CVE-2026-33901_bug420_2.patch +CVE-2026-42326.patch +CVE-2026-45031.patch +CVE-2026-45358.patch +CVE-2026-45359.patch +CVE-2026-45624.patch +CVE-2026-45664_1.patch +CVE-2026-45664_2.patch +CVE-2026-46520.patch +CVE-2026-46521.patch +CVE-2026-46522.patch +CVE-2026-46523.patch +CVE-2026-46559.patch +port-distribute-cache-to-6.9.13-48.patch +distribute-cache-backport.patch