Commit 061b7b28d for imagemagick.org

commit 061b7b28d807d9295ddf2bf12b2eaa63f53a015c
Author: Dirk Lemstra <dirk@lemstra.org>
Date:   Fri Nov 28 12:50:46 2025 +0100

    Disabling a module will now also disable all the coders in that module.

diff --git a/MagickCore/constitute.c b/MagickCore/constitute.c
index 9029c0391..c2409e0f3 100644
--- a/MagickCore/constitute.c
+++ b/MagickCore/constitute.c
@@ -445,8 +445,8 @@ MagickExport Image *PingImages(ImageInfo *image_info,const char *filename,
 %
 */

-static MagickBooleanType IsCoderAuthorized(const char *coder,
-  const PolicyRights rights,ExceptionInfo *exception)
+static MagickBooleanType IsCoderAuthorized(const char *module,
+  const char *coder,const PolicyRights rights,ExceptionInfo *exception)
 {
   if (IsRightsAuthorized(CoderPolicyDomain,rights,coder) == MagickFalse)
     {
@@ -455,6 +455,13 @@ static MagickBooleanType IsCoderAuthorized(const char *coder,
         "NotAuthorized","`%s'",coder);
       return(MagickFalse);
     }
+  if (IsRightsAuthorized(ModulePolicyDomain,rights,module) == MagickFalse)
+    {
+      errno=EPERM;
+      (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
+        "NotAuthorized","`%s'",module);
+      return(MagickFalse);
+    }
   return(MagickTrue);
 }

@@ -727,15 +734,14 @@ MagickExport Image *ReadImage(const ImageInfo *image_info,
       /*
         Call appropriate image reader based on image type.
       */
-      if ((magick_info != (const MagickInfo *) NULL) &&
-          (GetMagickDecoderThreadSupport(magick_info) == MagickFalse))
+      if (GetMagickDecoderThreadSupport(magick_info) == MagickFalse)
         LockSemaphoreInfo(magick_info->semaphore);
-      status=IsCoderAuthorized(read_info->magick,ReadPolicyRights,exception);
+      status=IsCoderAuthorized(magick_info->magick_module,read_info->magick,
+        ReadPolicyRights,exception);
       image=(Image *) NULL;
       if (status != MagickFalse)
         image=decoder(read_info,exception);
-      if ((magick_info != (const MagickInfo *) NULL) &&
-          (GetMagickDecoderThreadSupport(magick_info) == MagickFalse))
+      if (GetMagickDecoderThreadSupport(magick_info) == MagickFalse)
         UnlockSemaphoreInfo(magick_info->semaphore);
     }
   else
@@ -792,7 +798,8 @@ MagickExport Image *ReadImage(const ImageInfo *image_info,
       */
       if (GetMagickDecoderThreadSupport(magick_info) == MagickFalse)
         LockSemaphoreInfo(magick_info->semaphore);
-      status=IsCoderAuthorized(read_info->magick,ReadPolicyRights,exception);
+      status=IsCoderAuthorized(magick_info->magick_module,read_info->magick,
+        ReadPolicyRights,exception);
       image=(Image *) NULL;
       if (status != MagickFalse)
         image=(decoder)(read_info,exception);
@@ -1334,14 +1341,13 @@ MagickExport MagickBooleanType WriteImage(const ImageInfo *image_info,
       /*
         Call appropriate image writer based on image type.
       */
-      if ((magick_info != (const MagickInfo *) NULL) &&
-          (GetMagickEncoderThreadSupport(magick_info) == MagickFalse))
+      if (GetMagickEncoderThreadSupport(magick_info) == MagickFalse)
         LockSemaphoreInfo(magick_info->semaphore);
-      status=IsCoderAuthorized(write_info->magick,WritePolicyRights,exception);
+      status=IsCoderAuthorized(magick_info->magick_module,write_info->magick,
+        WritePolicyRights,exception);
       if (status != MagickFalse)
         status=encoder(write_info,image,exception);
-      if ((magick_info != (const MagickInfo *) NULL) &&
-          (GetMagickEncoderThreadSupport(magick_info) == MagickFalse))
+      if (GetMagickEncoderThreadSupport(magick_info) == MagickFalse)
         UnlockSemaphoreInfo(magick_info->semaphore);
     }
   else
@@ -1409,8 +1415,8 @@ MagickExport MagickBooleanType WriteImage(const ImageInfo *image_info,
               */
               if (GetMagickEncoderThreadSupport(magick_info) == MagickFalse)
                 LockSemaphoreInfo(magick_info->semaphore);
-              status=IsCoderAuthorized(write_info->magick,WritePolicyRights,
-                exception);
+              status=IsCoderAuthorized(magick_info->magick_module,write_info->magick,
+                WritePolicyRights,exception);
               if (status != MagickFalse)
                 status=encoder(write_info,image,exception);
               if (GetMagickEncoderThreadSupport(magick_info) == MagickFalse)
diff --git a/config/policy-limited.xml b/config/policy-limited.xml
index 431922e74..b5bc22a4a 100644
--- a/config/policy-limited.xml
+++ b/config/policy-limited.xml
@@ -85,7 +85,6 @@
   <!-- Indirect reads are not permitted. -->
   <policy domain="path" rights="none" pattern="@*"/>
   <!-- These image types are security risks on read, but write is fine -->
-  <policy domain="coder" rights="write" pattern="{MSL,MVG,PS,SVG,URL,XPS}"/>
   <policy domain="module" rights="write" pattern="{MSL,MVG,PS,SVG,URL,XPS}"/>
   <!-- This policy sets the number of times to replace content of certain
        memory buffers and temporary files before they are freed or deleted. -->
diff --git a/config/policy-open.xml b/config/policy-open.xml
index a1197af4c..17cb250aa 100644
--- a/config/policy-open.xml
+++ b/config/policy-open.xml
@@ -140,7 +140,6 @@
   <!-- Indirect reads are not permitted. -->
   <!-- <policy domain="path" rights="none" pattern="@*"/> -->
   <!-- These image types are security risks on read, but write is fine -->
-  <!-- <policy domain="coder" rights="write" pattern="{MSL,MVG,PS,SVG,URL,XPS}"/> -->
   <!-- <policy domain="module" rights="write" pattern="{MSL,MVG,PS,SVG,URL,XPS}"/> -->
   <!-- This policy sets the number of times to replace content of certain
        memory buffers and temporary files before they are freed or deleted. -->
diff --git a/config/policy-secure.xml b/config/policy-secure.xml
index 4785536ce..32b1c88de 100644
--- a/config/policy-secure.xml
+++ b/config/policy-secure.xml
@@ -95,7 +95,6 @@
   <!-- Indirect reads are not permitted. -->
   <policy domain="path" rights="none" pattern="@*"/>
   <!-- These image types are security risks on read, but write is fine -->
-  <policy domain="coder" rights="write" pattern="{MSL,MVG,PS,SVG,URL,XPS}"/>
   <policy domain="module" rights="write" pattern="{MSL,MVG,PS,SVG,URL,XPS}"/>
   <!-- This policy sets the number of times to replace content of certain
        memory buffers and temporary files before they are freed or deleted. -->