Hi Brandon, 

Your patch is not full.  It only tries to create unique filename, but it
cannot guarantee that the file doesn't exist.  The filename shouldn't be
totally unpredictable, but there must be a guarantee that the file
doesn't exists.  mkstemp(3) does it.  Glibc calls open(2) with perms = 0600,
for other systems umask(2) should be called.

Please see the attached patch.  I don't have eve access too, so please
test it who can :-)


Thanks,

-- 
Vasiliy
commit 7ce5ed0dfd1b3efe5be3e002554a9cdeade7d59a
Author: Vasiliy Kulikov <[email protected]>
Date:   Thu Feb 10 19:30:17 2011 +0300

    Fixed race between stat(2) and fopen(3).

diff --git a/src/eve.cc b/src/eve.cc
index 187a5f4..9cd2f6f 100644
--- a/src/eve.cc
+++ b/src/eve.cc
@@ -254,19 +254,6 @@ static char *formatTime(struct tm *ends)
 	}
 }
 
-static int file_exists(const char *filename)
-{
-	struct stat fi;
-
-	if ((stat(filename, &fi)) == 0) {
-		if (fi.st_size > 0)
-			return 1;
-		else
-			return 0;
-	} else
-		return 0;
-}
-
 static void writeSkilltree(char *content, const char *filename)
 {
 	FILE *fp = fopen(filename, "w");
@@ -283,11 +270,9 @@ static char *getSkillname(const char *file, int skillid)
 	xmlDocPtr doc = 0;
 	xmlNodePtr root = 0;
 
-	if (!file_exists(file)) {
-		skilltree = getXmlFromAPI(NULL, NULL, NULL, EVEURL_SKILLTREE);
-		writeSkilltree(skilltree, file);
-		free(skilltree);
-	}
+	skilltree = getXmlFromAPI(NULL, NULL, NULL, EVEURL_SKILLTREE);
+	writeSkilltree(skilltree, file);
+	free(skilltree);
 
 	doc = xmlReadFile(file, NULL, 0);
 	if (!doc)
@@ -340,7 +325,7 @@ static char *getSkillname(const char *file, int skillid)
 static char *eve(char *userid, char *apikey, char *charid)
 {
 	Character *chr = NULL;
-	const char *skillfile = "/tmp/.cesf";
+	char skillfile[] = "/tmp/.cesfXXXXXX";
 	int i = 0;
 	char *output = 0;
 	char *timel = 0;
@@ -348,6 +333,7 @@ static char *eve(char *userid, char *apikey, char *charid)
 	char *content = 0;
 	time_t now = 0;
 	char *error = 0;
+	int tmp_fd, old_umask;
 
 
 	for (i = 0; i < MAXCHARS; i++) {
@@ -400,6 +386,14 @@ static char *eve(char *userid, char *apikey, char *charid)
 
 		output = (char *)malloc(200 * sizeof(char));
 		timel = formatTime(&chr->ends);
+		old_umask = umask(0066);
+		tmp_fd = mkstemp(skillfile);
+		umask(old_umask);
+		if (tmp_fd == -1) {
+			error = strdup("Cannot create temporary file");
+			return error;
+		}
+		close(tmp_fd);
 		skill = getSkillname(skillfile, chr->skill);
 
 		chr->skillname = strdup(skill);

Reply via email to