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);
|