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)
openSUSE Build Service is sponsored by