Patch subject is complete summary.

# HG changeset patch
# User Kevin McCarthy <ke...@8t8.us>
# Date 1478734908 28800
#      Wed Nov 09 15:41:48 2016 -0800
# Node ID 7186fdb54bdd233846c47818b264ff753ed3fdbd
# Parent  b08235dfc7855189252702449b298d58a0b1dec6
Compress: safe_fopen() the tempfile, to prevent tempfile attacks.

diff --git a/compress.c b/compress.c
--- a/compress.c
+++ b/compress.c
@@ -110,34 +110,44 @@
 }
 
 /**
  * setup_paths - Set the mailbox paths
  * @ctx: Mailbox to modify
  *
  * Save the compressed filename in ctx->realpath.
  * Create a temporary filename and put its name in ctx->path.
+ * The temporary file is created to prevent symlink attacks.
  *
- * Note: The temporary file is NOT created.
+ * Returns:
+ *      0: Success
+ *      -1: Error
  */
-static void
+static int
 setup_paths (CONTEXT *ctx)
 {
   if (!ctx)
-    return;
+    return -1;
 
   char tmppath[_POSIX_PATH_MAX];
+  FILE *tmpfp;
 
   /* Setup the right paths */
   FREE(&ctx->realpath);
   ctx->realpath = ctx->path;
 
   /* We will uncompress to /tmp */
   mutt_mktemp (tmppath, sizeof (tmppath));
   ctx->path = safe_strdup (tmppath);
+
+  if ((tmpfp = safe_fopen (ctx->path, "w")) == NULL)
+    return -1;
+
+  safe_fclose (&tmpfp);
+  return 0;
 }
 
 /**
  * get_size - Get the size of a file
  * @path: File to measure
  *
  * Returns:
  *      number: Size in bytes
@@ -419,17 +429,18 @@
   COMPRESS_INFO *ci = set_compress_info (ctx);
   if (!ci)
     return -1;
 
   /* If there's no close-hook, or the file isn't writable */
   if (!ci->close || (access (ctx->path, W_OK) != 0))
     ctx->readonly = 1;
 
-  setup_paths (ctx);
+  if (setup_paths (ctx) != 0)
+    goto or_fail;
   store_size (ctx);
 
   int rc = execute_command (ctx, ci->open, 0, _("Decompressing %s"));
   if (rc == 0)
     goto or_fail;
 
   ctx->magic = mx_get_magic (ctx->path);
   if (ctx->magic == 0)
@@ -484,17 +495,18 @@
     goto oa_fail1;
   }
 
   ctx->magic = DefaultMagic;
   /* We can only deal with mbox and mmdf mailboxes */
   if ((ctx->magic != MUTT_MBOX) && (ctx->magic != MUTT_MMDF))
     goto oa_fail1;
 
-  setup_paths (ctx);
+  if (setup_paths (ctx) != 0)
+    goto oa_fail2;
 
   ctx->mx_ops = &mx_comp_ops;
   ci->child_ops = mx_get_ops (ctx->magic);
   if (!ci->child_ops)
   {
     mutt_error (_("Can't find mailbox ops for mailbox type %d"), ctx->magic);
     goto oa_fail2;
   }

Reply via email to