summaryrefslogtreecommitdiff
path: root/mail/mutt/patches/patch-ad
blob: aded4370a80778cf874c85440bfb039772947071 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
$NetBSD: patch-ad,v 1.9 2006/12/11 12:46:51 salo Exp $

Security fixes for CVE-2006-5297 and CVE-2006-5298, from mutt git.

--- lib.c.orig	2002-04-29 19:12:18.000000000 +0200
+++ lib.c	2006-12-11 13:24:17.000000000 +0100
@@ -346,13 +346,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 ||