CVE-2016-10060: Unchecked Return Value (CWE-252)
value: The ConcatenateImages function in MagickWand/magick-cli.c in ImageMagick before 7.0.1-10 does not check the return value of the fputc function, which allows remote attackers to cause a denial of service (application crash) via a crafted file.
CWE description: The product does not check the return value from a method or function, which can prevent it from detecting unexpected states and conditions.
CVSS v3 base score: 6.5
Published: 2017-03-02T21:59Z
Repository: https://github.com/ImageMagick/ImageMagick
Language: C
Files changed: MagickWand/magick-cli.c
Commit date: 2016-06-03 20:11:36 -0400
Commit message: https://github.com/ImageMagick/ImageMagick/issues/196

Diff: diff --git a/MagickWand/magick-cli.c b/MagickWand/magick-cli.c
index b4ad33bded..c28dd71696 100644
--- a/MagickWand/magick-cli.c
+++ b/MagickWand/magick-cli.c
@@ -634,47 +634,52 @@ static void MagickUsage(MagickBooleanType verbose)
 
    This is much like the UNIX "cat" command, but for both UNIX and Windows,
    however the last argument provides the output filename.
 */
 static MagickBooleanType ConcatenateImages(int argc,char **argv,
-     ExceptionInfo *exception )
+  ExceptionInfo *exception )
 {
   FILE
     *input,
     *output;
 
+  MagickBooleanType
+    status;
+
   int
     c;
 
   register ssize_t
     i;
 
   if (ExpandFilenames(&argc,&argv) == MagickFalse)
     ThrowFileException(exception,ResourceLimitError,"MemoryAllocationFailed",
-         GetExceptionMessage(errno));
-
+      GetExceptionMessage(errno));
   output=fopen_utf8(argv[argc-1],"wb");
-  if (output == (FILE *) NULL) {
-    ThrowFileException(exception,FileOpenError,"UnableToOpenFile",argv[argc-1]);
-    return(MagickFalse);
-  }
-  for (i=2; i < (ssize_t) (argc-1); i++) {
-#if 0
-    fprintf(stderr, "DEBUG: Concatenate Image: \"%s\"\n", argv[i]);
-#endif
+  if (output == (FILE *) NULL)
+    {
+      ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
+        argv[argc-1]);
+      return(MagickFalse);
+    }
+  status=MagickTrue;
+  for (i=2; i < (ssize_t) (argc-1); i++)
+  {
     input=fopen_utf8(argv[i],"rb");
-    if (input == (FILE *) NULL) {
+    if (input == (FILE *) NULL)
+      {
         ThrowFileException(exception,FileOpenError,"UnableToOpenFile",argv[i]);
         continue;
       }
     for (c=fgetc(input); c != EOF; c=fgetc(input))
-      (void) fputc((char) c,output);
+      if (fputc((char) c,output) != c)
+        status=MagickFalse;
     (void) fclose(input);
     (void) remove_utf8(argv[i]);
   }
   (void) fclose(output);
-  return(MagickTrue);
+  return(status);
 }
 
 WandExport MagickBooleanType MagickImageCommand(ImageInfo *image_info,int argc,
   char **argv,char **metadata,ExceptionInfo *exception)
 {

Vulnerable code:      ExceptionInfo *exception )
         GetExceptionMessage(errno));

  if (output == (FILE *) NULL) {
    ThrowFileException(exception,FileOpenError,"UnableToOpenFile",argv[argc-1]);
    return(MagickFalse);
  }
  for (i=2; i < (ssize_t) (argc-1); i++) {
#if 0
    fprintf(stderr, "DEBUG: Concatenate Image: \"%s\"\n", argv[i]);
#endif
    if (input == (FILE *) NULL) {
      (void) fputc((char) c,output);
  return(MagickTrue);
Fixed code:   ExceptionInfo *exception )
  MagickBooleanType
    status;

      GetExceptionMessage(errno));
  if (output == (FILE *) NULL)
    {
      ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
        argv[argc-1]);
      return(MagickFalse);
    }
  status=MagickTrue;
  for (i=2; i < (ssize_t) (argc-1); i++)
  {
    if (input == (FILE *) NULL)
      {
      if (fputc((char) c,output) != c)
        status=MagickFalse;
  return(status);