Commit 3705205e1 for imagemagick.org
commit 3705205e1424d379c2fc46c026c8560ccea0509e
Author: Cristy <urban-warrior@imagemagick.org>
Date: Wed May 20 22:26:20 2026 -0400
https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-gm48-c7f2-v67p
diff --git a/MagickCore/blob.c b/MagickCore/blob.c
index 3b2eb0bcc..f6a6d7933 100644
--- a/MagickCore/blob.c
+++ b/MagickCore/blob.c
@@ -3518,6 +3518,13 @@ MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
}
(void) CopyMagickString(image->filename,filename,MagickPathExtent);
}
+ if (IsPathAuthorized(rights,filename) == MagickFalse)
+ {
+ errno=EPERM;
+ (void) ThrowMagickException(exception,GetMagickModule(),
+ PolicyError,"NotAuthorized","`%s'",filename);
+ return(MagickFalse);
+ }
}
if (image_info->file != (FILE *) NULL)
{
@@ -3666,13 +3673,6 @@ MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
(void) SetStreamBuffering(image_info,blob_info);
}
}
- if (IsPathAuthorized(rights,filename) == MagickFalse)
- {
- errno=EPERM;
- (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
- "NotAuthorized","`%s'",filename);
- return(MagickFalse);
- }
blob_info->status=0;
blob_info->error_number=0;
if (blob_info->type != UndefinedStream)
diff --git a/MagickCore/policy.c b/MagickCore/policy.c
index acd145543..0cb4cb336 100644
--- a/MagickCore/policy.c
+++ b/MagickCore/policy.c
@@ -680,8 +680,7 @@ MagickExport MagickBooleanType IsRightsAuthorized(const PolicyDomain domain,
{
char
*name = (char *) NULL,
- *pattern = (char *) NULL,
- *real_pattern = (char *) NULL;
+ *pattern = (char *) NULL;
const PolicyInfo
**policies = (const PolicyInfo **) NULL;
@@ -729,17 +728,36 @@ MagickExport MagickBooleanType IsRightsAuthorized(const PolicyDomain domain,
*policy = policies[i];
MagickBooleanType
- match;
+ match = MagickFalse;
if (policy->domain != domain)
continue;
if ((name != (char *) NULL) && (LocaleCompare(name,policy->name) != 0))
continue;
- if ((policy->domain == PathPolicyDomain) &&
- (real_pattern == (const char *) NULL))
- real_pattern=realpath_utf8(pattern);
- match=GlobExpression(real_pattern != (char*) NULL ? real_pattern : pattern,
- policy->pattern,MagickFalse);
+ if (policy->domain != PathPolicyDomain)
+ match=GlobExpression(pattern,policy->pattern,MagickFalse);
+ else
+ {
+ char
+ *canonical_directory,
+ *canonical_path,
+ directory[MagickPathExtent];
+
+ GetPathComponent(pattern,HeadPath,directory);
+ canonical_directory=realpath_utf8(directory);
+ if (canonical_directory != (char *) NULL)
+ {
+ match=GlobExpression(canonical_directory,policy->pattern,
+ MagickFalse);
+ canonical_directory=DestroyString(canonical_directory);
+ }
+ canonical_path=realpath_utf8(pattern);
+ if ((canonical_path != (char *) NULL) && (match == MagickFalse))
+ {
+ match=GlobExpression(canonical_path,policy->pattern,MagickFalse);
+ canonical_path=DestroyString(canonical_path);
+ }
+ }
if (match == MagickFalse)
continue;
matched_any=MagickTrue;
@@ -750,8 +768,6 @@ MagickExport MagickBooleanType IsRightsAuthorized(const PolicyDomain domain,
pattern=DestroyString(pattern);
if (name != (char *) NULL)
name=DestroyString(name);
- if (real_pattern != (char *) NULL)
- real_pattern=DestroyString(real_pattern);
/*
Is rights authorized?
*/