$NetBSD: patch-ae,v 1.8 2006/12/11 12:47:13 salo Exp $ Security fixes for CVE-2006-5297 and CVE-2006-5298, from mutt git. --- lib.c.orig 2006-05-18 20:44:29.000000000 +0200 +++ lib.c 2006-12-11 13:39:27.000000000 +0100 @@ -481,13 +481,84 @@ int safe_rename (const char *src, const return 0; } +/* Create a temporary directory next to a file name */ + +int mutt_mkwrapdir (const char *path, char *newfile, size_t nflen, + char *newdir, size_t ndlen) +{ + const char *basename; + char parent[_POSIX_PATH_MAX]; + char *p; + int rv; + + strfcpy (parent, NONULL (path), sizeof (parent)); + + if ((p = strrchr (parent, '/'))) + { + *p = '\0'; + basename = p + 1; + } + else + { + strfcpy (parent, ".", sizeof (parent)); + basename = path; + } + + do + { + snprintf (newdir, ndlen, "%s/%s", parent, ".muttXXXXXX"); + mktemp (newdir); + } + while ((rv = mkdir (newdir, 0700)) == -1 && errno == EEXIST); + + if (rv == -1) + return -1; + + snprintf (newfile, nflen, "%s/%s", newdir, NONULL(basename)); + return 0; +} + +int mutt_put_file_in_place (const char *path, const char *safe_file, const char *safe_dir) +{ + int rv; + + rv = safe_rename (safe_file, path); + unlink (safe_file); + rmdir (safe_dir); + return rv; +} + int safe_open (const char *path, int flags) { struct stat osb, nsb; int fd; + if (flags & O_EXCL) + { + char safe_file[_POSIX_PATH_MAX]; + char safe_dir[_POSIX_PATH_MAX]; + + if (mutt_mkwrapdir (path, safe_file, sizeof (safe_file), + safe_dir, sizeof (safe_dir)) == -1) + return -1; + + if ((fd = open (safe_file, flags, 0600)) < 0) + { + rmdir (safe_dir); + return fd; + } + + if (mutt_put_file_in_place (path, safe_file, safe_dir) == -1) + { + close (fd); + return -1; + } + } + else + { if ((fd = open (path, flags, 0600)) < 0) return fd; + } /* make sure the file is not symlink */ if (lstat (path, &osb) < 0 || fstat (fd, &nsb) < 0 ||