]> granicus.if.org Git - imagemagick/commitdiff
Support image sequence list length security policy
authorCristy <urban-warrior@imagemagick.org>
Sat, 27 Jan 2018 15:02:34 +0000 (10:02 -0500)
committerCristy <urban-warrior@imagemagick.org>
Sat, 27 Jan 2018 15:02:34 +0000 (10:02 -0500)
MagickCore/cache.c
MagickCore/resource.c
MagickCore/resource_.h
config/english.xml
config/francais.xml
config/policy.xml

index b27850345d2fc098919f6c96d10eaa44844498d7..89368056f5441fcd0db65539780c910e68881080 100644 (file)
@@ -3485,6 +3485,9 @@ static MagickBooleanType OpenPixelCache(Image *image,const MapMode mode,
     ThrowBinaryException(CacheError,"NoPixelsDefinedInCache",image->filename);
   cache_info=(CacheInfo *) image->cache;
   assert(cache_info->signature == MagickCoreSignature);
+  length=GetImageListLength(image);
+  if (AcquireMagickResource(ListLengthResource,length) == MagickFalse)
+    ThrowBinaryException(ImageError,"ListLengthExceedsLimit",image->filename);
   if ((AcquireMagickResource(WidthResource,image->columns) == MagickFalse) ||
       (AcquireMagickResource(HeightResource,image->rows) == MagickFalse))
     ThrowBinaryException(ImageError,"WidthOrHeightExceedsLimit",
index 5e81531d70627d3e1ef4c83ea2e390d58fc26526..e30879ac72e3fc9385f295c4acc25ceaae10295b 100644 (file)
@@ -80,6 +80,7 @@ typedef struct _ResourceInfo
   MagickOffsetType
     width,
     height,
+    list_length,
     area,
     memory,
     map,
@@ -92,6 +93,7 @@ typedef struct _ResourceInfo
   MagickSizeType
     width_limit,
     height_limit,
+    list_length_limit,
     area_limit,
     memory_limit,
     map_limit,
@@ -113,6 +115,7 @@ static ResourceInfo
   {
     MagickULLConstant(0),              /* initial width */
     MagickULLConstant(0),              /* initial height */
+    MagickULLConstant(0),              /* initial list length */
     MagickULLConstant(0),              /* initial area */
     MagickULLConstant(0),              /* initial memory */
     MagickULLConstant(0),              /* initial map */
@@ -123,6 +126,7 @@ static ResourceInfo
     MagickULLConstant(0),              /* initial time */
     (INT_MAX/(5*sizeof(Quantum))),     /* width limit */
     (INT_MAX/(5*sizeof(Quantum))),     /* height limit */
+    MagickResourceInfinity,            /* list length limit */
     MagickULLConstant(3072)*1024*1024, /* area limit */
     MagickULLConstant(1536)*1024*1024, /* memory limit */
     MagickULLConstant(3072)*1024*1024, /* map limit */
@@ -207,50 +211,6 @@ MagickExport MagickBooleanType AcquireMagickResource(const ResourceType type,
         }
       break;
     }
-    case MemoryResource:
-    {
-      if ((resource_info.memory+(MagickOffsetType) size) < 0)
-        return(MagickFalse);
-      resource_info.memory+=(MagickOffsetType) size;
-      limit=resource_info.memory_limit;
-      if ((limit == MagickResourceInfinity) ||
-          (resource_info.memory < (MagickOffsetType) limit))
-        status=MagickTrue;
-      else
-        resource_info.memory-=(MagickOffsetType) size;
-      if (logging != MagickFalse)
-        {
-          (void) FormatMagickSize(size,MagickTrue,"B",MagickFormatExtent,
-            resource_request);
-          (void) FormatMagickSize((MagickSizeType) resource_info.memory,
-            MagickTrue,"B",MagickFormatExtent,resource_current);
-          (void) FormatMagickSize(limit,MagickTrue,"B",MagickFormatExtent,
-            resource_limit);
-        }
-      break;
-    }
-    case MapResource:
-    {
-      if ((resource_info.map+(MagickOffsetType) size) < 0)
-        return(MagickFalse);
-      resource_info.map+=(MagickOffsetType) size;
-      limit=resource_info.map_limit;
-      if ((limit == MagickResourceInfinity) ||
-          (resource_info.map < (MagickOffsetType) limit))
-        status=MagickTrue;
-      else
-        resource_info.map-=(MagickOffsetType) size;
-      if (logging != MagickFalse)
-        {
-          (void) FormatMagickSize(size,MagickTrue,"B",MagickFormatExtent,
-            resource_request);
-          (void) FormatMagickSize((MagickSizeType) resource_info.map,
-            MagickTrue,"B",MagickFormatExtent,resource_current);
-          (void) FormatMagickSize(limit,MagickTrue,"B",MagickFormatExtent,
-            resource_limit);
-        }
-      break;
-    }
     case DiskResource:
     {
       if ((resource_info.disk+(MagickOffsetType) size) < 0)
@@ -313,6 +273,67 @@ MagickExport MagickBooleanType AcquireMagickResource(const ResourceType type,
         }
       break;
     }
+    case MapResource:
+    {
+      if ((resource_info.map+(MagickOffsetType) size) < 0)
+        return(MagickFalse);
+      resource_info.map+=(MagickOffsetType) size;
+      limit=resource_info.map_limit;
+      if ((limit == MagickResourceInfinity) ||
+          (resource_info.map < (MagickOffsetType) limit))
+        status=MagickTrue;
+      else
+        resource_info.map-=(MagickOffsetType) size;
+      if (logging != MagickFalse)
+        {
+          (void) FormatMagickSize(size,MagickTrue,"B",MagickFormatExtent,
+            resource_request);
+          (void) FormatMagickSize((MagickSizeType) resource_info.map,
+            MagickTrue,"B",MagickFormatExtent,resource_current);
+          (void) FormatMagickSize(limit,MagickTrue,"B",MagickFormatExtent,
+            resource_limit);
+        }
+      break;
+    }
+    case ListLengthResource:
+    {
+      resource_info.list_length=(MagickOffsetType) size;
+      limit=resource_info.list_length_limit;
+      if ((limit == MagickResourceInfinity) || (size < limit))
+        status=MagickTrue;
+      if (logging != MagickFalse)
+        {
+          (void) FormatMagickSize(size,MagickFalse,(const char *) NULL,
+            MagickFormatExtent,resource_request);
+          (void) FormatMagickSize(size,MagickFalse,(const char *) NULL,
+            MagickFormatExtent,resource_current);
+          (void) FormatMagickSize(limit,MagickFalse,(const char *) NULL,
+            MagickFormatExtent,resource_limit);
+        }
+      break;
+    }
+    case MemoryResource:
+    {
+      if ((resource_info.memory+(MagickOffsetType) size) < 0)
+        return(MagickFalse);
+      resource_info.memory+=(MagickOffsetType) size;
+      limit=resource_info.memory_limit;
+      if ((limit == MagickResourceInfinity) ||
+          (resource_info.memory < (MagickOffsetType) limit))
+        status=MagickTrue;
+      else
+        resource_info.memory-=(MagickOffsetType) size;
+      if (logging != MagickFalse)
+        {
+          (void) FormatMagickSize(size,MagickTrue,"B",MagickFormatExtent,
+            resource_request);
+          (void) FormatMagickSize((MagickSizeType) resource_info.memory,
+            MagickTrue,"B",MagickFormatExtent,resource_current);
+          (void) FormatMagickSize(limit,MagickTrue,"B",MagickFormatExtent,
+            resource_limit);
+        }
+      break;
+    }
     case ThreadResource:
     {
       limit=resource_info.thread_limit;
@@ -688,39 +709,39 @@ MagickExport MagickSizeType GetMagickResource(const ResourceType type)
   LockSemaphoreInfo(resource_semaphore);
   switch (type)
   {
-    case WidthResource:
+    case AreaResource:
     {
-      resource=(MagickSizeType) resource_info.width;
+      resource=(MagickSizeType) resource_info.area;
       break;
     }
-    case HeightResource:
+    case DiskResource:
     {
-      resource=(MagickSizeType) resource_info.height;
+      resource=(MagickSizeType) resource_info.disk;
       break;
     }
-    case AreaResource:
+    case FileResource:
     {
-      resource=(MagickSizeType) resource_info.area;
+      resource=(MagickSizeType) resource_info.file;
       break;
     }
-    case MemoryResource:
+    case HeightResource:
     {
-      resource=(MagickSizeType) resource_info.memory;
+      resource=(MagickSizeType) resource_info.height;
       break;
     }
-    case MapResource:
+    case ListLengthResource:
     {
-      resource=(MagickSizeType) resource_info.map;
+      resource=(MagickSizeType) resource_info.list_length;
       break;
     }
-    case DiskResource:
+    case MapResource:
     {
-      resource=(MagickSizeType) resource_info.disk;
+      resource=(MagickSizeType) resource_info.map;
       break;
     }
-    case FileResource:
+    case MemoryResource:
     {
-      resource=(MagickSizeType) resource_info.file;
+      resource=(MagickSizeType) resource_info.memory;
       break;
     }
     case ThreadResource:
@@ -738,6 +759,11 @@ MagickExport MagickSizeType GetMagickResource(const ResourceType type)
       resource=(MagickSizeType) resource_info.time;
       break;
     }
+    case WidthResource:
+    {
+      resource=(MagickSizeType) resource_info.width;
+      break;
+    }
     default:
       break;
   }
@@ -778,39 +804,39 @@ MagickExport MagickSizeType GetMagickResourceLimit(const ResourceType type)
   LockSemaphoreInfo(resource_semaphore);
   switch (type)
   {
-    case WidthResource:
+    case AreaResource:
     {
-      resource=resource_info.width_limit;
+      resource=resource_info.area_limit;
       break;
     }
-    case HeightResource:
+    case DiskResource:
     {
-      resource=resource_info.height_limit;
+      resource=resource_info.disk_limit;
       break;
     }
-    case AreaResource:
+    case FileResource:
     {
-      resource=resource_info.area_limit;
+      resource=resource_info.file_limit;
       break;
     }
-    case MemoryResource:
+    case HeightResource:
     {
-      resource=resource_info.memory_limit;
+      resource=resource_info.height_limit;
       break;
     }
-    case MapResource:
+    case ListLengthResource:
     {
-      resource=resource_info.map_limit;
+      resource=resource_info.list_length_limit;
       break;
     }
-    case DiskResource:
+    case MemoryResource:
     {
-      resource=resource_info.disk_limit;
+      resource=resource_info.memory_limit;
       break;
     }
-    case FileResource:
+    case MapResource:
     {
-      resource=resource_info.file_limit;
+      resource=resource_info.map_limit;
       break;
     }
     case ThreadResource:
@@ -828,6 +854,11 @@ MagickExport MagickSizeType GetMagickResourceLimit(const ResourceType type)
       resource=resource_info.time_limit;
       break;
     }
+    case WidthResource:
+    {
+      resource=resource_info.width_limit;
+      break;
+    }
     default:
       break;
   }
@@ -867,6 +898,7 @@ MagickExport MagickBooleanType ListMagickResourceInfo(FILE *file,
     area_limit[MagickFormatExtent],
     disk_limit[MagickFormatExtent],
     height_limit[MagickFormatExtent],
+    list_length_limit[MagickFormatExtent],
     map_limit[MagickFormatExtent],
     memory_limit[MagickFormatExtent],
     time_limit[MagickFormatExtent],
@@ -883,6 +915,8 @@ MagickExport MagickBooleanType ListMagickResourceInfo(FILE *file,
     MagickFormatExtent,width_limit);
   (void) FormatMagickSize(resource_info.height_limit,MagickFalse,"P",
     MagickFormatExtent,height_limit);
+  (void) FormatMagickSize(resource_info.list_length_limit,MagickFalse,"P",
+    MagickFormatExtent,list_length_limit);
   (void) FormatMagickSize(resource_info.area_limit,MagickFalse,"P",
     MagickFormatExtent,area_limit);
   (void) FormatMagickSize(resource_info.memory_limit,MagickTrue,"B",
@@ -900,6 +934,7 @@ MagickExport MagickBooleanType ListMagickResourceInfo(FILE *file,
   (void) FormatLocaleFile(file,"Resource limits:\n");
   (void) FormatLocaleFile(file,"  Width: %s\n",width_limit);
   (void) FormatLocaleFile(file,"  Height: %s\n",height_limit);
+  (void) FormatLocaleFile(file,"  List length: %s\n",list_length_limit);
   (void) FormatLocaleFile(file,"  Area: %s\n",area_limit);
   (void) FormatLocaleFile(file,"  Memory: %s\n",memory_limit);
   (void) FormatLocaleFile(file,"  Map: %s\n",map_limit);
@@ -973,36 +1008,6 @@ MagickExport void RelinquishMagickResource(const ResourceType type,
         }
       break;
     }
-    case MemoryResource:
-    {
-      resource_info.memory-=size;
-      assert(resource_info.memory >= 0);
-      if (logging != MagickFalse)
-        {
-          (void) FormatMagickSize(size,MagickFalse,"B",MagickFormatExtent,
-            resource_request);
-          (void) FormatMagickSize((MagickSizeType) resource_info.memory,
-            MagickTrue,"B",MagickFormatExtent,resource_current);
-          (void) FormatMagickSize(resource_info.memory_limit,MagickTrue,"B",
-            MagickFormatExtent,resource_limit);
-        }
-      break;
-    }
-    case MapResource:
-    {
-      resource_info.map-=size;
-      assert(resource_info.map >= 0);
-      if (logging != MagickFalse)
-        {
-          (void) FormatMagickSize(size,MagickFalse,"B",MagickFormatExtent,
-            resource_request);
-          (void) FormatMagickSize((MagickSizeType) resource_info.map,
-            MagickTrue,"B",MagickFormatExtent,resource_current);
-          (void) FormatMagickSize(resource_info.map_limit,MagickTrue,"B",
-            MagickFormatExtent,resource_limit);
-        }
-      break;
-    }
     case DiskResource:
     {
       resource_info.disk-=size;
@@ -1048,6 +1053,51 @@ MagickExport void RelinquishMagickResource(const ResourceType type,
         }
       break;
     }
+    case ListLengthResource:
+    {
+      resource_info.list_length=(MagickOffsetType) size;
+      if (logging != MagickFalse)
+        {
+          (void) FormatMagickSize(size,MagickFalse,(const char *) NULL,
+            MagickFormatExtent,resource_request);
+          (void) FormatMagickSize((MagickSizeType) resource_info.list_length,
+            MagickFalse,(const char *) NULL,MagickFormatExtent,
+            resource_current);
+          (void) FormatMagickSize(resource_info.list_length_limit,MagickFalse,
+            (const char *) NULL,MagickFormatExtent,resource_limit);
+        }
+      break;
+    }
+    case MapResource:
+    {
+      resource_info.map-=size;
+      assert(resource_info.map >= 0);
+      if (logging != MagickFalse)
+        {
+          (void) FormatMagickSize(size,MagickFalse,"B",MagickFormatExtent,
+            resource_request);
+          (void) FormatMagickSize((MagickSizeType) resource_info.map,
+            MagickTrue,"B",MagickFormatExtent,resource_current);
+          (void) FormatMagickSize(resource_info.map_limit,MagickTrue,"B",
+            MagickFormatExtent,resource_limit);
+        }
+      break;
+    }
+    case MemoryResource:
+    {
+      resource_info.memory-=size;
+      assert(resource_info.memory >= 0);
+      if (logging != MagickFalse)
+        {
+          (void) FormatMagickSize(size,MagickFalse,"B",MagickFormatExtent,
+            resource_request);
+          (void) FormatMagickSize((MagickSizeType) resource_info.memory,
+            MagickTrue,"B",MagickFormatExtent,resource_current);
+          (void) FormatMagickSize(resource_info.memory_limit,MagickTrue,"B",
+            MagickFormatExtent,resource_limit);
+        }
+      break;
+    }
     case ThreadResource:
     {
       if (logging != MagickFalse)
@@ -1314,6 +1364,13 @@ MagickPrivate MagickBooleanType ResourceComponentGenesis(void)
         100.0));
       limit=DestroyString(limit);
     }
+  limit=GetEnvironmentValue("MAGICK_LIST_LENGTH_LIMIT");
+  if (limit != (char *) NULL)
+    {
+      (void) SetMagickResourceLimit(ListLengthResource,
+        StringToMagickSizeType(limit,100.0));
+      limit=DestroyString(limit);
+    }
   return(MagickTrue);
 }
 \f
@@ -1390,67 +1447,67 @@ MagickExport MagickBooleanType SetMagickResourceLimit(const ResourceType type,
   value=(char *) NULL;
   switch (type)
   {
-    case WidthResource:
+    case AreaResource:
     {
-      resource_info.width_limit=limit;
-      value=GetPolicyValue("resource:width");
+      resource_info.area_limit=limit;
+      value=GetPolicyValue("resource:area");
       if (value != (char *) NULL)
-        resource_info.width_limit=MagickMin(limit,StringToMagickSizeType(value,
+        resource_info.area_limit=MagickMin(limit,StringToMagickSizeType(value,
           100.0));
       break;
     }
-    case HeightResource:
+    case DiskResource:
     {
-      resource_info.height_limit=limit;
-      value=GetPolicyValue("resource:height");
+      resource_info.disk_limit=limit;
+      value=GetPolicyValue("resource:disk");
       if (value != (char *) NULL)
-        resource_info.height_limit=MagickMin(limit,StringToMagickSizeType(
-          value,100.0));
+        resource_info.disk_limit=MagickMin(limit,StringToMagickSizeType(value,
+          100.0));
       break;
     }
-    case AreaResource:
+    case FileResource:
     {
-      resource_info.area_limit=limit;
-      value=GetPolicyValue("resource:area");
+      resource_info.file_limit=limit;
+      value=GetPolicyValue("resource:file");
       if (value != (char *) NULL)
-        resource_info.area_limit=MagickMin(limit,StringToMagickSizeType(value,
+        resource_info.file_limit=MagickMin(limit,StringToMagickSizeType(value,
           100.0));
       break;
     }
-    case MemoryResource:
+    case HeightResource:
     {
-      resource_info.memory_limit=limit;
-      value=GetPolicyValue("resource:memory");
+      resource_info.height_limit=limit;
+      value=GetPolicyValue("resource:height");
       if (value != (char *) NULL)
-        resource_info.memory_limit=MagickMin(limit,StringToMagickSizeType(
+        resource_info.height_limit=MagickMin(limit,StringToMagickSizeType(
           value,100.0));
       break;
     }
-    case MapResource:
+    case ListLengthResource:
     {
-      resource_info.map_limit=limit;
-      value=GetPolicyValue("resource:map");
+      resource_info.list_length_limit=limit;
+      value=GetPolicyValue("resource:list-length");
       if (value != (char *) NULL)
-        resource_info.map_limit=MagickMin(limit,StringToMagickSizeType(value,
-          100.0));
+        resource_info.list_length_limit=MagickMin(limit,
+          StringToMagickSizeType(value,100.0));
       break;
     }
-    case DiskResource:
+    case MapResource:
     {
-      resource_info.disk_limit=limit;
-      value=GetPolicyValue("resource:disk");
+      resource_info.map_limit=limit;
+      value=GetPolicyValue("resource:map");
       if (value != (char *) NULL)
-        resource_info.disk_limit=MagickMin(limit,StringToMagickSizeType(value,
-          100.0));
+        resource_info.map_limit=MagickMin(limit,StringToMagickSizeType(
+          value,100.0));
       break;
     }
-    case FileResource:
+    case MemoryResource:
     {
-      resource_info.file_limit=limit;
-      value=GetPolicyValue("resource:file");
+      resource_info.memory_limit=limit;
+      value=GetPolicyValue("resource:memory");
       if (value != (char *) NULL)
-        resource_info.file_limit=MagickMin(limit,StringToMagickSizeType(value,
-          100.0));
+        resource_info.memory_limit=MagickMin(limit,StringToMagickSizeType(
+          value,100.0));
       break;
     }
     case ThreadResource:
@@ -1486,9 +1543,20 @@ MagickExport MagickBooleanType SetMagickResourceLimit(const ResourceType type,
       ResetPixelCacheEpoch();
       break;
     }
+    case WidthResource:
+    {
+      resource_info.width_limit=limit;
+      value=GetPolicyValue("resource:width");
+      if (value != (char *) NULL)
+        resource_info.width_limit=MagickMin(limit,StringToMagickSizeType(value,
+          100.0));
+      break;
+    }
     default:
+    {
       status=MagickFalse;
       break;
+    }
   }
   if (value != (char *) NULL)
     value=DestroyString(value);
index 9f74fc5a12319957a4169ce0cb9a51c52dad10d0..08334deb241df4b5458725c23ecdbb1db488c3cf 100644 (file)
@@ -34,7 +34,8 @@ typedef enum
   ThreadResource,
   ThrottleResource,
   TimeResource,
-  WidthResource
+  WidthResource,
+  ListLengthResource
 } ResourceType;
 
 #define MagickResourceInfinity  MagickULLConstant(~0)
index dbaa11d800207f919f6ccd80444d8d0a6a12caba..81bec765103ffc2c459072446dbab1c4e0e6a684 100644 (file)
         <message name="LeftAndRightImageSizesDiffer">
           left and right image sizes differ
         </message>
+        <message name="ListLengthExceedsLimit">
+          list length exceeds limit
+        </message>
         <message name="NegativeOrZeroImageSize">
           negative or zero image size
         </message>
index 2f7c7000514af7b2f37f54cb686f901cb1d75279..5e94ab57f6716e6184cf387ea524defd2bf2eeb4 100644 (file)
         <message name="LeftAndRightImageSizesDiffer">
           diffĂ©rences dans les tailles des images gauche et droite
         </message>
+        <message name="ListLengthExceedsLimit">
+          list length exceeds limit
+        </message>
         <message name="NegativeOrZeroImageSize">
           Taille d'image nĂ©gative ou nulle
         </message>
index d497934e7ad36b21fe882a7bfb55a049fe12a976..71cc8fa6188557953a3e5bfd978c623f159659b3 100644 (file)
@@ -61,6 +61,7 @@
   <!-- <policy domain="system" name="memory-map" value="anonymous"/> -->
   <!-- <policy domain="system" name="max-memory-request" value="256MiB"/> -->
   <!-- <policy domain="resource" name="temporary-path" value="/tmp"/> -->
+  <!-- <policy domain="resource" name="list-length" value="128"/> -->
   <!-- <policy domain="resource" name="memory" value="2GiB"/> -->
   <!-- <policy domain="resource" name="map" value="4GiB"/> -->
   <!-- <policy domain="resource" name="width" value="10KP"/> -->