--- mutt-1.5.5.1/rfc1524.h.cve-2006-5298 2006-10-26 14:23:55.000000000 -0600 +++ mutt-1.5.5.1/rfc1524.h 2006-10-26 14:23:55.000000000 -0600 @@ -38,6 +38,7 @@ rfc1524_entry *rfc1524_new_entry (void); void rfc1524_free_entry (rfc1524_entry **); int rfc1524_expand_command (BODY *, char *, char *, char *, int); int rfc1524_expand_filename (char *, char *, char *, size_t); +int rfc1524_expand_tofile (char *, char *, char *, size_t, FILE **, const char *); int rfc1524_mailcap_lookup (BODY *, char *, rfc1524_entry *, int); int mutt_rename_file (char *, char *); int _mutt_rename_file (char *, char *, int); --- mutt-1.5.5.1/rfc1524.c.cve-2006-5298 2006-10-26 14:23:55.000000000 -0600 +++ mutt-1.5.5.1/rfc1524.c 2006-10-26 14:23:55.000000000 -0600 @@ -440,10 +440,10 @@ static void strnfcpy(char *d, char *s, s strfcpy(d, s, len); } -int rfc1524_expand_filename (char *nametemplate, +int rfc1524_expand_tofile (char *nametemplate, char *oldfile, char *newfile, - size_t nflen) + size_t nflen, FILE **tmpf, const char *openmode) { int i, j, k, ps, r; char *s; @@ -544,8 +544,11 @@ int rfc1524_expand_filename (char *namet } } - mutt_adv_mktemp(newfile, nflen); - + if (tmpf && openmode) + *tmpf = mutt_adv_mktempfile(newfile, nflen, openmode); + else + mutt_adv_mktemp(newfile, nflen); + if(rmatch && lmatch) return 0; else @@ -553,6 +556,15 @@ int rfc1524_expand_filename (char *namet } +int rfc1524_expand_filename (char *nametemplate, + char *oldfile, + char *newfile, + size_t nflen) +{ + return rfc1524_expand_tofile (nametemplate, oldfile, newfile, nflen, + NULL, NULL); +} + /* If rfc1524_expand_command() is used on a recv'd message, then * the filename doesn't exist yet, but if its used while sending a message, * then we need to rename the existing file. --- mutt-1.5.5.1/postpone.c.cve-2006-5298 2006-10-26 14:23:55.000000000 -0600 +++ mutt-1.5.5.1/postpone.c 2006-10-26 14:23:55.000000000 -0600 @@ -643,8 +643,7 @@ int mutt_prepare_template (FILE *fp, CON mutt_delete_parameter ("x-mutt-noconv", &b->parameter); } - mutt_adv_mktemp (file, sizeof(file)); - if ((s.fpout = safe_fopen (file, "w")) == NULL) + if ((s.fpout = mutt_adv_mktempfile (file, sizeof (file), "w")) == NULL) goto bail; --- mutt-1.5.5.1/attach.c.cve-2006-5298 2003-11-05 02:41:31.000000000 -0700 +++ mutt-1.5.5.1/attach.c 2006-10-26 14:23:55.000000000 -0600 @@ -396,6 +396,7 @@ int mutt_view_attachment (FILE *fp, BODY { char tempfile[_POSIX_PATH_MAX] = ""; char pagerfile[_POSIX_PATH_MAX] = ""; + FILE *pagerf = NULL; int is_message; int use_mailcap; int use_pipe = 0; @@ -490,7 +491,7 @@ int mutt_view_attachment (FILE *fp, BODY { /* recv case */ strfcpy (pagerfile, a->filename, sizeof (pagerfile)); - mutt_adv_mktemp (pagerfile, sizeof(pagerfile)); + pagerf = mutt_adv_mktempfile (pagerfile, sizeof(pagerfile), "w"); } else mutt_mktemp (pagerfile); --- mutt-1.5.5.1/muttlib.c.cve-2006-5298 2006-10-26 14:23:55.000000000 -0600 +++ mutt-1.5.5.1/muttlib.c 2006-10-26 14:28:42.000000000 -0600 @@ -32,6 +32,7 @@ #include "mutt_crypt.h" +#include <stdio.h> #include <string.h> #include <ctype.h> #include <unistd.h> @@ -95,12 +96,139 @@ void mutt_adv_mktemp (char *s, size_t l) } } +FILE *mutt_adv_mktempfile (char *s, size_t l, const char *mode) +{ + char buf[_POSIX_PATH_MAX]; + char tmp[_POSIX_PATH_MAX]; + char *period; + size_t sl; + int saved_errno; + FILE *tmpf = NULL; + + strfcpy (buf, NONULL (Tempdir), sizeof (buf)); + mutt_expand_path (buf, sizeof (buf)); + if (s[0] == '\0') + { + int tmpfd; + + snprintf (s, l, "%s/muttXXXXXX", buf); + if ((tmpfd = mkstemp (s)) == -1 || (tmpf = fdopen (tmpfd, mode)) == NULL) + { + if (tmpfd != -1) { + saved_errno = errno; + unlink (s); + close (tmpfd); + errno = saved_errno; + } + return NULL; + } + return tmpf; + } + else + { + int maxattempts; + int fd; + + strfcpy (tmp, s, sizeof (tmp)); + mutt_sanitize_filename (tmp, 1); + snprintf (s, l, "%s/%s", buf, tmp); + if ((fd = open (s, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR)) == -1 || + (tmpf = fdopen (fd, mode)) == NULL) + { + if (fd != -1) { + unlink (s); + close (fd); + } + } + else + return tmpf; + + /* Kind of mkstemps: First use mktemp to create a 'unique' filename + * then append the suffix to the filename and try to O_EXCL open it. + * If the open call fails (file exists) then this code tries to + * create the file TMP_MAX times before giving up. + */ + if ((period = strrchr (tmp, '.')) != NULL) + *period = 0; + + if (period == NULL) + { + /* No suffix use plain mkstemp */ + snprintf (s, l, "%s/%s.XXXXXX", buf, tmp); + if ((fd = mkstemp (s)) == -1 || (tmpf = fdopen (fd, mode)) == NULL) + { + if (fd != -1) + { + saved_errno = errno; + unlink (s); + close (fd); + errno = saved_errno; + } + return NULL; + } + else + return tmpf; + } + + for (maxattempts = 0; maxattempts < TMP_MAX; maxattempts++) + { + snprintf (s, l, "%s/%s.XXXXXX", buf, tmp); +#ifndef HAVE_MKSTEMPS + if (mktemp (s) == NULL) + return NULL; +#endif + + if (period != NULL) + { + *period = '.'; + sl = mutt_strlen (s); + strfcpy (s + sl, period, l - sl); + +#ifdef HAVE_MKSTEMPS + if ((fd = mkstemps (s, mutt_strlen (period))) == -1 || + (tmpf = fdopen (fd, mode)) == NULL) + { + if (fd != -1) + { + saved_errno = errno; + unlink (s); + close (fd); + errno = saved_errno; + } + return NULL; + } + else + return tmpf; +#endif + } + + if ((fd = open(s, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR)) != -1) + { + if ((tmpf = fdopen(fd, mode)) == NULL) + { + if (fd != -1) + { + unlink (s); + close (fd); + } + } + else + return tmpf; + } + else if (errno != EEXIST) + return NULL; /* if error is not EEXIST this is not going to work?*/ + } + } + return NULL; +} + /* create a send-mode duplicate from a receive-mode body */ int mutt_copy_body (FILE *fp, BODY **tgt, BODY *src) { char tmp[_POSIX_PATH_MAX]; BODY *b; + FILE *tmpf; PARAMETER *par, **ppar; @@ -117,10 +245,9 @@ int mutt_copy_body (FILE *fp, BODY **tgt tmp[0] = '\0'; } - mutt_adv_mktemp (tmp, sizeof (tmp)); - if (mutt_save_attachment (fp, src, tmp, 0, NULL) == -1) + if ((tmpf = mutt_adv_mktempfile (tmp, sizeof (tmp), "w")) == NULL) return -1; - + *tgt = mutt_new_body (); b = *tgt; --- mutt-1.5.5.1/protos.h.cve-2006-5298 2006-10-26 14:23:55.000000000 -0600 +++ mutt-1.5.5.1/protos.h 2006-10-26 14:23:55.000000000 -0600 @@ -140,6 +140,7 @@ const char *mutt_fqdn(short); void mutt_account_hook (const char* url); void mutt_add_to_reference_headers (ENVELOPE *env, ENVELOPE *curenv, LIST ***pp, LIST ***qq); void mutt_adv_mktemp (char *, size_t); +FILE *mutt_adv_mktempfile (char *, size_t, const char *); void mutt_alias_menu (char *, size_t, ALIAS *); void mutt_allow_interrupt (int); void mutt_attach_init (BODY *);