File: 0012-Fix-TOCTTOU-on-creating-temporary-file.patch

package info (click to toggle)
safecat 1.13%2Bgit20170317.185e8bf-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 776 kB
  • sloc: ansic: 2,748; makefile: 4
file content (58 lines) | stat: -rw-r--r-- 1,968 bytes parent folder | download
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
From: =?utf-8?b?0L3QsNCx?= <nabijaczleweli@nabijaczleweli.xyz>
Date: Fri, 22 Aug 2025 17:29:39 +0200
Subject: Fix TOCTTOU on creating temporary file

---
 safecat.c | 18 ++++++------------
 1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/safecat.c b/safecat.c
index 17d1f5f..d90895f 100644
--- a/safecat.c
+++ b/safecat.c
@@ -45,7 +45,6 @@ int main(int argc, char *argv[]) {
   int   outfd    = 0;
   FILE *outfdf   = NULL;
   int destdirfd = -1;
-  struct stat filestat;
   unsigned int count = 0;
 
   /* Check that we were called with the correct number of arguments. */
@@ -65,17 +64,19 @@ int main(int argc, char *argv[]) {
   tempdirfd = stat_dir(tempdir);
   destdirfd = stat_dir(destdir);
 
-  /* Step 2:  Stat the temporary file.  Wait for ENOENT as a response. */
+  /* Step 4:  Create the file tempdir/time.MusecPpid.host idempotently */
   for(count=1;;count++) {
     /* Get the temporary filename to use now for dumping data. */
     mk_tempfile(&outfile);
-    if(fstatat(tempdirfd,outfile.s,&filestat,0) == -1 && errno == ENOENT) {
+    alarm(86400);
+    outfd = openat(tempdirfd,outfile.s,O_WRONLY | O_EXCL | O_CREAT | O_LARGEFILE,0666);
+    if(outfd != -1) {
       break;
     }
 
     /* Try up to 5 times, every 2 seconds. */
-    if(count == 5) {
-      strerr_die_x(111, "safecat: fatal: ","could not stat temporary file");
+    if(errno != EEXIST || count == 5) {
+      strerr_die_x(111, "safecat: fatal: ","could not create output file");
     }
 
     /* Wait 2 seconds, and try again. */
@@ -83,13 +84,6 @@ int main(int argc, char *argv[]) {
     sleep(2);
   }
 
-  /* Step 4:  Create the file tempdir/time.MusecPpid.host */
-  alarm(86400);
-  outfd = openat(tempdirfd,outfile.s,O_WRONLY | O_EXCL | O_CREAT | O_LARGEFILE,0666);
-  if(outfd == -1) {
-    strerr_die_sys(111,"safecat: fatal: ","couldn't create output file: ");
-  }
-
   outfdf = fdopen(outfd, "w");
   if (!outfdf) {
     unlinkat(tempdirfd,outfile.s,0);