xonix (1.4-29) 10-makefile=11-x11.c-CAN-2004-0157-and-other.patch

Summary

 x11.c |  106 +++++++++++++++++++++++++++++++++++++++++-------------------------
 1 file changed, 67 insertions(+), 39 deletions(-)

    
download this patch

Patch contents

From 01d38098b85628e90c9a326583ab0facf8b7c339 Mon Sep 17 00:00:00 2001
From: Jari Aalto <jari.aalto@cante.net>
Date: Wed, 27 Jan 2010 21:24:07 +0200
Subject: [PATCH] x11.c: CAN-2004-0157 and other changes

Signed-off-by: Jari Aalto <jari.aalto@cante.net>
---
 x11.c |  106 +++++++++++++++++++++++++++++++++++++++++------------------------
 1 files changed, 67 insertions(+), 39 deletions(-)

diff --git a/x11.c b/x11.c
index a1fdcfe..1d6589d 100644
--- a/x11.c
+++ b/x11.c
@@ -52,8 +52,7 @@
 #ifdef __unix
 
 #define MAXSCORES 10		/* number of entries in high score table */
-#define PATH_HIGHSCORE XONIXDIR "/scores"
-#define PATH_TEMPSCORE XONIXDIR "/score_tmp"
+#define PATH_HIGHSCORE "/var/cache/xonix/xonix.scores"
 
 #if defined(__unix) && !defined PATH_RMAIL
 #define PATH_RMAIL "rmail"	/* rely on the $PATH */
@@ -61,6 +60,7 @@
 
 #include <sys/types.h>
 #include <sys/time.h>
+#include <sys/file.h>
 #include <pwd.h>
 #include <string.h>
 #include <stdlib.h>
@@ -898,7 +898,6 @@ DisplayHighScore(void)
   char *fullname = 0, *cp;
   struct score_rec score_rec[MAXSCORES];
   int i, numentries = 0;
-  char tempname[sizeof(PATH_TEMPSCORE) + 15];
   char hugestring[MAXSCORES * 100];
   
   Widget box1, box2, msg, headl, done, area;
@@ -926,53 +925,62 @@ DisplayHighScore(void)
     }
     else
       fullname = strdup(pw->pw_gecos);
-    if((cp = strchr(fullname, ','))) *cp = 0; /* remove trailing garbage */
+    cp = strchr(fullname, ',');
+    if (cp == fullname) {
+	free(fullname);
+	fullname = strdup("(No name)");
+    }
+    else if (cp != NULL)
+       *cp = 0; /* remove trailing garbage */
   }
   else
     fullname = strdup("(No name)"); /* the strdup() allows to free() it */
-  
+ 
   /* try opening high score file, and read it */
-  if((high = fopen(PATH_HIGHSCORE, "r"))) {
-    for(i = 0; i < 10; i++) {
+  if((high=fopen(PATH_HIGHSCORE, "r")) && (flock(fileno(high),LOCK_EX)==0)){
+    for(i = 0; i < MAXSCORES; i++) {
       char line[100];
 
       if(fgets(line, 100, high) == NULL)
 	break;
-
-      if(sscanf(line, " %u %u%*[\t]%10[^\t]%*[\t]%64[^\t] %ld",
+      
+      if(sscanf(line, "%u%*[\t]%u%*[\t]%10[^\t]%*[\t]%64[^\t]%*[\t]%ld",
 		&score_rec[i].score, &score_rec[i].level,
 		score_rec[i].login, score_rec[i].full,
 		&score_rec[i].tstamp)
-	 != 5) break;		/* mangled entry */
+	 <3 ) break;		/* mangled entry */
     }
     numentries = i;
-    fclose(high);
   }
-  if(numentries)
-    qsort(score_rec, numentries, sizeof(struct score_rec), compare);
-
-  /* make sure the new list will be world-readable */
-  (void)umask(umask(0) & ~0644);
-  sprintf(tempname, "%s.%d", PATH_TEMPSCORE, (int)getpid());
-  if((high = fopen(tempname, "w")) == NULL) {
-    fprintf(stderr, "xonix: cannot rewrite high score file\n");
+  else
+  {
+    if (high != NULL) {
+      fprintf(stderr, "xonix: cannot lock high score file\n");
+      fclose(high);
+    }
+    else
+	fprintf(stderr, "xonix: cannot open high score file\n");
     free(fullname);
     gameover_pending = 0;
     return;
   }
+
+  if(numentries)
+    qsort(score_rec, numentries, sizeof(struct score_rec), compare);
   
-  if(numentries >= MAXSCORES && gHighScore < score_rec[0].score) {
+  if(numentries >= MAXSCORES && gHighScore <= score_rec[0].score) {
     /* sorry, not among top ten */
-    fclose(high);
-    (void)unlink(tempname);
     free(fullname);
+    if(flock(fileno(high),LOCK_UN) != 0)
+      fprintf(stderr, "xonix: cannot unlock high score file\n");
+    fclose(high);
     gameover_pending = 0;
     return;
   }
   
   for(i = 0; i < numentries; i++) {
     /* look where to put entry */
-    if(score_rec[i].score > gHighScore) break;
+    if(score_rec[i].score >= gHighScore) break;
   }
 
 #ifdef SEND_MAIL
@@ -993,19 +1001,32 @@ DisplayHighScore(void)
     tm = localtime(&sp->tstamp);
     strftime(tbuf, 20, "%d-%b-%y", tm);
 
-    if((mail = popen(cmd, "w")) != NULL) {
-      fprintf(mail,
-	      "To: %s (%s)\n"
-	      "Subject: Lost xonix championship\n\n"
-	      "Your previously held first rank in the local xonix score\n"
-	      "table (%u points, level %u, dated %s) has been\n"
-	      "vanished today by me with %u points.\n\n"
-	      "\t\tpitying you\t%s (%s)\n",
-	      sp->login, sp->full,
-	      sp->score, sp->level, tbuf,
-	      gHighScore,
-	      pw->pw_name, fullname);
-      (void)pclose(mail);
+    /* format a text - fork and exec the processes so we can drop privileges */
+    switch( fork() ) {
+       case -1:          /* Error */
+         perror(fork);
+	 exit(1);
+	 break;
+       case 0:           /* Child */
+	 setgid(pw->pw_gid);
+	 setuid(pw->pw_uid);
+	 if((mail = popen(cmd, "w")) != NULL) {
+	   fprintf(mail,
+		   "To: %s (%s)\n"
+		   "Subject: Lost xonix championship\n\n"
+		   "Your previously held first rank in the local xonix score\n"
+		   "table (%u points, level %u, dated %s) has been\n"
+		   "vanished today by me with %u points.\n\n"
+		   "\t\tpitying you\t%s (%s)\n",
+		   sp->login, sp->full,
+		   sp->score, sp->level, tbuf,
+		   gHighScore,
+		   pw->pw_name, fullname);
+	   (void)pclose(mail);
+	   break;
+	 default: /* parent */
+	   break;
+      }
     }
   }
   
@@ -1036,16 +1057,23 @@ DisplayHighScore(void)
   score_rec[i].tstamp = time(NULL);
   free(fullname);
 
+  if((high = freopen(PATH_HIGHSCORE, "w",high)) == NULL) {
+    fprintf(stderr, "xonix: cannot reopen high score file\n");
+    free(fullname);
+    gameover_pending = 0;
+    return;
+  }
+
   for(i = 0; i < numentries; i++)
     (void)fprintf(high, "%u\t%u\t%s\t%s\t%ld\n",
 		  score_rec[i].score, score_rec[i].level,
 		  score_rec[i].login, score_rec[i].full,
 		  score_rec[i].tstamp);
+
+  if(flock(fileno(high),LOCK_UN) != 0)
+    fprintf(stderr, "xonix: cannot unlock high score file\n");
   fclose(high);
   
-  if(rename(tempname, PATH_HIGHSCORE))
-    fprintf(stderr, "xonix: cannot install new highscore file\n");
-
   /* create hugestring for highscore label */
   hugestring[0] = 0;
   for(i = 0; i < numentries; i++) {
-- 
1.6.5