Commit ef0eb6df0 for imagemagick.org
commit ef0eb6df01f3bed2210d159da391381cba94ffcf
Author: Cristy <urban-warrior@imagemagick.org>
Date: Tue Jul 7 19:01:20 2026 -0400
time-of-check to time-of-use check
diff --git a/MagickCore/resource.c b/MagickCore/resource.c
index ec814a73e..71ca6b5e7 100644
--- a/MagickCore/resource.c
+++ b/MagickCore/resource.c
@@ -561,6 +561,9 @@ MagickExport int AcquireUniqueFileResource(char *path)
char
*p;
+ MagickBooleanType
+ status;
+
ssize_t
i;
@@ -571,6 +574,9 @@ MagickExport int AcquireUniqueFileResource(char *path)
StringInfo
*key;
+ struct stat
+ *attributes;
+
unsigned char
*datum;
@@ -641,10 +647,15 @@ MagickExport int AcquireUniqueFileResource(char *path)
LockSemaphoreInfo(resource_semaphore[FileResource]);
if (temporary_resources == (SplayTreeInfo *) NULL)
temporary_resources=NewSplayTree(CompareSplayTreeString,
- DestroyTemporaryResources,(void *(*)(void *)) NULL);
+ DestroyTemporaryResources,RelinquishMagickMemory);
UnlockSemaphoreInfo(resource_semaphore[FileResource]);
- (void) AddValueToSplayTree(temporary_resources,ConstantString(path),
- (const void *) NULL);
+ attributes=(struct stat *) AcquireCriticalMemory(sizeof(struct stat));
+ status=GetPathAttributes(path,attributes);
+ if (status != MagickFalse)
+ status=AddValueToSplayTree(temporary_resources,ConstantString(path),
+ attributes);
+ if (status == MagickFalse)
+ file=close_utf8(file)-1;
return(file);
}
@@ -793,7 +804,7 @@ MagickExport MagickSizeType GetMagickResourceLimit(const ResourceType type)
{
MagickSizeType
resource;
-
+
switch (type)
{
case AreaResource:
@@ -1168,7 +1179,26 @@ MagickExport MagickBooleanType RelinquishUniqueFileResource(const char *path)
ActivateSemaphoreInfo(&resource_semaphore[FileResource]);
LockSemaphoreInfo(resource_semaphore[FileResource]);
if (temporary_resources != (SplayTreeInfo *) NULL)
- status=DeleteNodeFromSplayTree(temporary_resources,(const void *) path);
+ {
+ const struct stat
+ *temporary_attributes;
+
+ struct stat
+ attributes;
+
+ temporary_attributes=(const struct stat *) GetValueFromSplayTree(
+ temporary_resources,(const void *) path);
+ status=GetPathAttributes(path,&attributes);
+ if ((temporary_attributes != (const struct stat *) NULL) &&
+ (status != MagickFalse))
+ {
+ if ((attributes.st_dev != temporary_attributes->st_dev) ||
+ (attributes.st_ino != temporary_attributes->st_ino))
+ ThrowFatalException(PolicyFatalError,
+ "time-of-check to time-of-use violation");
+ }
+ status=DeleteNodeFromSplayTree(temporary_resources,(const void *) path);
+ }
UnlockSemaphoreInfo(resource_semaphore[FileResource]);
(void) CopyMagickString(cache_path,path,MagickPathExtent);
AppendImageFormat("cache",cache_path);