From: deneb@lisa.python.it Sent: Thursday, January 03, 2002 12:46 PM To: Christian Recktenwald Cc: secprog@securityfocus.com Subject: Re: tmpfile alternative Thanks for your answers. So this is better (my major mistake was the assumption that fopen implementations are safe against race condition): #include #include #include #include #include #include "bondlog.h" /* here there are all headers needed by the app */ #include #include #include #include #include #include #define MAX_BUF 11 #define RANDOMFILE "/dev/urandom" FILE * mytmpfile (void ) { char appname[] = "/var/spool/bondlog/tmp"; char filename[PATH_MAX]; base64buf b; unsigned int num = 0; unsigned int count = 0; int mypid; FILE *urand_file; FILE *tmp; unsigned char *stream; struct stat f_stat_info, l_stat_info; int fd, finfo; if ((stream = (char *) malloc (MAX_BUF)) == NULL) { return NULL; } memset (stream, '\0', MAX_BUF); memset(filename,'\0',sizeof(filename)-1); urand_file = fopen (RANDOMFILE, "r"); if (urand_file == NULL) { /* If I cannot open the random file i assume that i can't create a safe filename so I cannot assume that the file creation is safe */ free (stream); return NULL; } do { count = 0; while (count < 9) { fread (&num, sizeof (unsigned int), 1, urand_file); stream[count] = (char) num; count++; } base64_encode (&b, stream, 9); memset (filename, '\0', sizeof (filename)-1); mypid = (int) getpid(); snprintf (filename, sizeof (filename), "%s-%d-%s", appname, mypid, b.data); } while ((finfo = lstat (filename, &l_stat_info)) != -1); fclose (urand_file); if (finfo == -1) { if (errno != ENOENT) return NULL; if ((fd = open (filename, O_CREAT | O_EXCL | O_RDWR, 0600)) == -1) return NULL; lstat (filename, &l_stat_info); } else { free (stream); return NULL; } if ((fstat (fd, &f_stat_info) == -1) || (l_stat_info.st_mode != f_stat_info.st_mode) || (l_stat_info.st_ino != f_stat_info.st_ino) || (l_stat_info.st_dev != f_stat_info.st_dev)) { free(stream); close (fd); return NULL; } if ((tmp = fdopen (fd, "r+b")) == NULL) { close (fd); unlink (filename); free (stream); return NULL; } unlink (filename); // the file will be not delete until closed; free (stream); buffer_delete (&b); return (tmp); } ---------------end-------------------