File ImageMagick-6.2.5-delegate-symlink-CVE-2005-4601.patch of Package ImageMagick
--- coders/pdf.c
+++ coders/pdf.c
@@ -357,6 +357,16 @@
" -sPDFPassword=%s",read_info->authenticate);
(void) CopyMagickString(filename,read_info->filename,MaxTextExtent);
(void) AcquireUniqueFilename(read_info->filename);
+ if (AcquireTemporarySymlink((char *) image_info->filename,filename)
+ == MagickFalse)
+ {
+ (void) RelinquishUniqueFileResource(postscript_filename);
+ (void) RelinquishUniqueFileResource(read_info->filename);
+ (void) DestroyImageInfo(read_info);
+ ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
+ image_info->filename);
+ return((Image *) NULL);
+ }
(void) FormatMagickString(command,MaxTextExtent,
GetDelegateCommands(delegate_info),
read_info->antialias != MagickFalse ? 4 : 1,
@@ -364,6 +374,8 @@
read_info->filename,postscript_filename,image_info->filename);
status=InvokePostscriptDelegate(read_info->verbose,command);
image=ReadImage(read_info,exception);
+ unlink(image_info->filename);
+ (void) CopyMagickString((char *) image_info->filename,filename,MaxTextExtent);
(void) RelinquishUniqueFileResource(postscript_filename);
(void) RelinquishUniqueFileResource(read_info->filename);
read_info=DestroyImageInfo(read_info);
--- coders/ps.c
+++ coders/ps.c
@@ -487,6 +487,16 @@
}
(void) CopyMagickString(filename,read_info->filename,MaxTextExtent);
(void) AcquireUniqueFilename(read_info->filename);
+ if (AcquireTemporarySymlink((char *) image_info->filename,filename)
+ == MagickFalse)
+ {
+ (void) RelinquishUniqueFileResource(postscript_filename);
+ (void) RelinquishUniqueFileResource(read_info->filename);
+ (void) DestroyImageInfo(read_info);
+ ThrowFileException(&image->exception,FileOpenError,
+ "UnableToCreateTemporaryFile",image_info->filename);
+ return((Image *) NULL);
+ }
(void) FormatMagickString(command,MaxTextExtent,
GetDelegateCommands(delegate_info),
read_info->antialias != MagickFalse ? 4 : 1,
@@ -503,6 +513,8 @@
}
(void) RelinquishUniqueFileResource(postscript_filename);
(void) RelinquishUniqueFileResource(read_info->filename);
+ unlink(image_info->filename);
+ (void) CopyMagickString((char *) image_info->filename,filename,MaxTextExtent);
if (image == (Image *) NULL)
{
/*
--- magick/delegate.c
+++ magick/delegate.c
@@ -673,6 +674,72 @@
% %
% %
% %
++ A c q u i r e T e m p o r a r y S y m l i n k %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% AcquireTemporarySymlink replaces the contents of the string buffer pointed
+% to by filename with the unique name of a symbolic link. True is returned
+% if a symlink waas created, or False is returned if there is a failure.
+% The allocated symlink should be recovered via the LiberateTemporaryFile()
+% function once it is no longer required.
+%
+% The format of the AcquireTemporarySymlink method is:
+%
+% unsigned int AcquireTemporarySymlink(char *linkname, const char *name)
+%
+% A description of each parameter follows.
+%
+% o linkname: Specifies a pointer to an array of characters that must be
+% MaxTextExtent characters of size. The unique
+% name of the symlink is returned in this array.
+% o name: Specifies a file name the symlink should point to.
+*/
+MagickExport unsigned int AcquireTemporarySymlink(char *linkname, const char *name)
+{
+ char
+ *tempname;
+
+ int
+ fd,
+ tries;
+
+ assert(linkname != (char *)NULL);
+ linkname[0]='\0';
+ linkname[MaxTextExtent-1]='\0';
+
+ for (tries=0; tries < 15; tries++)
+ {
+ tempname=tempnam(getenv("MAGICK_TMPDIR"),"magick-");
+ strncpy(linkname,tempname,MaxTextExtent-1);
+ free(tempname);
+ if (*name == '/')
+ fd=symlink(name, linkname);
+ else
+ {
+ char cname[MaxTextExtent];
+ if (!getcwd(cname,(size_t)MaxTextExtent))
+ return (MagickFalse);
+ strncat(cname,"/",MaxTextExtent-1);
+ strncat(cname,name,MaxTextExtent-1);
+ fd=symlink(cname,linkname);
+ }
+ if (fd != -1)
+ {
+ close(fd);
+ return (MagickTrue);
+ }
+ }
+ return (MagickFalse);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
% I n v o k e D e l e g a t e %
% %
% %
@@ -703,7 +770,9 @@
{
char
*command,
- **commands;
+ **commands,
+ linkedname[MaxTextExtent],
+ linkedinfoname[MaxTextExtent];
const DelegateInfo
*delegate_info;
@@ -724,19 +793,39 @@
assert(image->signature == MagickSignature);
if (image->debug != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
+ linkedname[0]='\0';
+ linkedinfoname[0]='\0';
temporary=(*image->filename == '\0') ? MagickTrue : MagickFalse;
if (temporary != MagickFalse)
- if (AcquireUniqueFilename(image->filename) == MagickFalse)
- {
- ThrowFileException(exception,FileOpenError,
- "UnableToCreateTemporaryFile",image->filename);
- return(MagickFalse);
- }
+ {
+ if (AcquireUniqueFilename(image->filename) == MagickFalse)
+ {
+ ThrowFileException(exception,FileOpenError,
+ "UnableToCreateTemporaryFile",image->filename);
+ return(MagickFalse);
+ }
+ }
+ else
+ {
+ (void) CopyMagickString(linkedname,image->filename,MaxTextExtent);
+ if (AcquireTemporarySymlink(image->filename,linkedname) == MagickFalse)
+ {
+ ThrowFileException(exception,FileOpenError,
+ "UnableToCreateTemporaryFile",image->filename);
+ return(MagickFalse);
+ }
+ }
+
delegate_info=GetDelegateInfo(decode,encode,exception);
if (delegate_info == (DelegateInfo *) NULL)
{
if (temporary != MagickFalse)
(void) RelinquishUniqueFileResource(image->filename);
+ else
+ {
+ unlink(image->filename);
+ (void) CopyMagickString(image->filename,linkedname,MaxTextExtent);
+ }
(void) ThrowMagickException(exception,GetMagickModule(),DelegateError,
"NoTagFound","`%s'",decode ? decode : encode);
return(MagickFalse);
@@ -747,12 +836,31 @@
{
if (temporary != MagickFalse)
(void) RelinquishUniqueFileResource(image->filename);
+ else
+ {
+ unlink(image->filename);
+ (void) CopyMagickString(image->filename,linkedname,
+ MaxTextExtent);
+ }
ThrowFileException(exception,FileOpenError,
"UnableToCreateTemporaryFile",image_info->filename);
return(MagickFalse);
}
image_info->temporary=MagickTrue;
}
+ else
+ {
+ (void) CopyMagickString(linkedinfoname,image_info->filename,
+ MaxTextExtent);
+ if (AcquireTemporarySymlink(image_info->filename,linkedinfoname)
+ == MagickFalse)
+ {
+ ThrowFileException(exception,FileOpenError,
+ "UnableToCreateTemporaryFile",image_info->filename);
+ return(MagickFalse);
+ }
+ }
+
if (delegate_info->mode != 0)
if (((decode != (const char *) NULL) &&
(delegate_info->encode != (char *) NULL)) ||
@@ -792,6 +900,12 @@
(void) RelinquishUniqueFileResource(image_info->zero);
if (temporary != MagickFalse)
(void) RelinquishUniqueFileResource(image->filename);
+ else
+ {
+ unlink(image->filename);
+ (void) CopyMagickString(image->filename,linkedname,
+ MaxTextExtent);
+ }
(void) ThrowMagickException(exception,GetMagickModule(),
DelegateError,"DelegateFailed","`%s'",decode ? decode : encode);
return(MagickFalse);
@@ -820,6 +934,12 @@
(void) RelinquishUniqueFileResource(image_info->zero);
if (temporary != MagickFalse)
(void) RelinquishUniqueFileResource(image->filename);
+ else
+ {
+ unlink(image->filename);
+ (void) CopyMagickString(image->filename,linkedname,
+ MaxTextExtent);
+ }
clone_info=DestroyImageInfo(clone_info);
(void) ThrowMagickException(exception,GetMagickModule(),
DelegateError,"DelegateFailed","`%s'",decode ? decode : encode);
@@ -840,6 +960,18 @@
{
if (temporary != MagickFalse)
(void) RelinquishUniqueFileResource(image->filename);
+ else
+ {
+ unlink(image->filename);
+ (void) CopyMagickString(image->filename,linkedname,
+ MaxTextExtent);
+ }
+ if (*linkedinfoname)
+ {
+ unlink(image_info->filename);
+ (void) CopyMagickString(image_info->filename,linkedinfoname,
+ MaxTextExtent);
+ }
(void) ThrowMagickException(exception,GetMagickModule(),
ResourceLimitError,"MemoryAllocationFailed","`%s'",
decode ? decode : encode);
@@ -892,6 +1024,18 @@
commands=(char **) RelinquishMagickMemory(commands);
if (temporary != MagickFalse)
(void) RelinquishUniqueFileResource(image->filename);
+ else
+ {
+ unlink(image->filename);
+ (void) CopyMagickString(image->filename,linkedname,
+ MaxTextExtent);
+ }
+ if (*linkedinfoname)
+ {
+ unlink(image_info->filename);
+ (void) CopyMagickString(image_info->filename,linkedinfoname,
+ MaxTextExtent);
+ }
return((MagickBooleanType) (status == MagickFalse));
}
--- magick/delegate.h
+++ magick/delegate.h
@@ -96,6 +96,9 @@
extern MagickExport long
GetDelegateMode(const DelegateInfo *);
+extern MagickExport unsigned int
+ AcquireTemporarySymlink(char *, const char *);
+
extern MagickExport MagickBooleanType
InvokePostscriptDelegate(const MagickBooleanType,const char *),
InvokeDelegate(ImageInfo *,Image *,const char *,const char *,ExceptionInfo *),
--- magick/methods.h
+++ magick/methods.h
@@ -47,6 +47,7 @@
#define AcquireSemaphoreInfo PrependMagickMethod(AcquireSemaphoreInfo)
#define AcquireStringInfo PrependMagickMethod(AcquireStringInfo)
#define AcquireString PrependMagickMethod(AcquireString)
+#define AcquireTemporarySymlink PrependMagickMethod(AcquireTemporarySymlink)
#define AcquireUniqueFilename PrependMagickMethod(AcquireUniqueFilename)
#define AcquireUniqueFileResource PrependMagickMethod(AcquireUniqueFileResource)
#define AdaptiveThresholdImage PrependMagickMethod(AdaptiveThresholdImage)