]> git.llucax.com Git - software/mutt-debian.git/blob - debian/patches/misc/tempfile-race.diff
mutt (1.5.13-2) experimental; urgency=low
[software/mutt-debian.git] / debian / patches / misc / tempfile-race.diff
1 From: roessler <roessler>
2 Date: Mon, 9 Oct 2006 13:39:38 +0000 (+0000)
3 Subject: From: Thomas Roessler <roessler@does-not-exist.org>
4 X-Git-Url: http://dev.mutt.org/cgi-bin/gitweb.cgi?p=mutt/.git;a=commitdiff;h=f6404a53a2b7a9a3b36d89def185e1192abdd108
5
6   From: Thomas Roessler <roessler@does-not-exist.org>
7   
8   Even more paranoid temporary file creation.
9 ---
10
11 --- a/lib.c
12 +++ b/lib.c
13 @@ -481,14 +481,85 @@ int safe_rename (const char *src, const 
14    return 0;
15  }
16  
17 +/* Create a temporary directory next to a file name */
18 +
19 +int mutt_mkwrapdir (const char *path, char *newfile, size_t nflen, 
20 +                   char *newdir, size_t ndlen)
21 +{
22 +  const char *basename;
23 +  char parent[_POSIX_PATH_MAX];
24 +  char *p;
25 +  int rv;
26 +
27 +  strfcpy (parent, NONULL (path), sizeof (parent));
28 +  
29 +  if ((p = strrchr (parent, '/')))
30 +  {
31 +    *p = '\0';
32 +    basename = p + 1;
33 +  }
34 +  else
35 +  {
36 +    strfcpy (parent, ".", sizeof (parent));
37 +    basename = path;
38 +  }
39 +
40 +  do 
41 +  {
42 +    snprintf (newdir, ndlen, "%s/%s", parent, ".muttXXXXXX");
43 +    mktemp (newdir);
44 +  } 
45 +  while ((rv = mkdir (newdir, 0700)) == -1 && errno == EEXIST);
46 +  
47 +  if (rv == -1)
48 +    return -1;
49 +  
50 +  snprintf (newfile, nflen, "%s/%s", newdir, NONULL(basename));
51 +  return 0;  
52 +}
53 +
54 +int mutt_put_file_in_place (const char *path, const char *safe_file, const char *safe_dir)
55 +{
56 +  int rv;
57 +  
58 +  rv = safe_rename (safe_file, path);
59 +  unlink (safe_file);
60 +  rmdir (safe_dir);
61 +  return rv;
62 +}
63 +
64  int safe_open (const char *path, int flags)
65  {
66    struct stat osb, nsb;
67    int fd;
68  
69 -  if ((fd = open (path, flags, 0600)) < 0)
70 -    return fd;
71 +  if (flags & O_EXCL) 
72 +  {
73 +    char safe_file[_POSIX_PATH_MAX];
74 +    char safe_dir[_POSIX_PATH_MAX];
75  
76 +    if (mutt_mkwrapdir (path, safe_file, sizeof (safe_file),
77 +                       safe_dir, sizeof (safe_dir)) == -1)
78 +      return -1;
79 +    
80 +    if ((fd = open (safe_file, flags, 0600)) < 0)
81 +    {
82 +      rmdir (safe_dir);
83 +      return fd;
84 +    }
85 +    
86 +    if (mutt_put_file_in_place (path, safe_file, safe_dir) == -1)
87 +    {
88 +      close (fd);
89 +      return -1;
90 +    }
91 +  }
92 +  else
93 +  {
94 +    if ((fd = open (path, flags, 0600)) < 0)
95 +      return fd;
96 +  }
97 +    
98    /* make sure the file is not symlink */
99    if (lstat (path, &osb) < 0 || fstat (fd, &nsb) < 0 ||
100        compare_stat(&osb, &nsb) == -1)