rpms/rogue/FC-5 rogue-5.4-setgid.patch,NONE,1.1

Michael Thomas (wart) fedora-extras-commits at redhat.com
Tue Apr 11 02:04:46 UTC 2006


Author: wart

Update of /cvs/extras/rpms/rogue/FC-5
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv7964

Added Files:
	rogue-5.4-setgid.patch 
Log Message:
Better setuid/setgid handling (BZ #187392)



rogue-5.4-setgid.patch:

--- NEW FILE rogue-5.4-setgid.patch ---
diff -Naur --exclude '*.swp' rogue/extern.c rogue.new/extern.c
--- rogue/extern.c	2006-01-03 16:17:29.000000000 -0800
+++ rogue.new/extern.c	2006-03-30 13:24:12.000000000 -0800
@@ -111,7 +111,7 @@
 };
 
 int count = 0;				/* Number of times to repeat command */
-int fd;					/* File descriptor for score file */
+FILE *scoreboard = (FILE *)NULL;	/* File descriptor for score file */
 int food_left;				/* Amount of food in hero's stomach */
 int lastscore = -1;			/* Score before this turn */
 int no_command = 0;			/* Number of turns asleep */
diff -Naur --exclude '*.swp' rogue/extern.h rogue.new/extern.h
--- rogue/extern.h	2006-03-19 11:22:14.000000000 -0800
+++ rogue.new/extern.h	2006-03-30 13:24:22.000000000 -0800
@@ -50,7 +50,7 @@
 
 extern char	fruit[], orig_dsusp, prbuf[], whoami[];
 
-extern int	fd;
+extern FILE     *scoreboard;
 
 #ifdef TIOCGLTC
 extern struct ltchars	ltc;
diff -Naur --exclude '*.swp' rogue/mach_dep.c rogue.new/mach_dep.c
--- rogue/mach_dep.c	2006-01-30 08:36:21.000000000 -0800
+++ rogue.new/mach_dep.c	2006-04-01 19:26:15.000000000 -0800
@@ -45,7 +45,9 @@
 #include <sys/stat.h>
 #include <limits.h>
 
+#include <unistd.h>
 #include <fcntl.h>
+#include <errno.h>
 
 static char scorefile[PATH_MAX] = "rogue54.scr";
 static char lockfile[PATH_MAX] = "rogue54.lck";
@@ -99,22 +101,41 @@
 {
     char *homedir = md_getroguedir();
 
+    /*
+     * We drop setgid privileges after opening the score file, so subsequent
+     * open()'s will fail.  Just reuse the earlier filehandle.
+     */
+    if (scoreboard != NULL) {
+        rewind(scoreboard);
+        return;
+    }
+
     if (homedir == NULL)
         homedir = "";
 
 #ifdef SCOREFILE
-    strcpy(scorefile, homedir);
-    if (*scorefile)
-        strcat(scorefile,"/");
-    strcat(scorefile, "rogue54.scr");
-    strcpy(lockfile, homedir);
-    if (*lockfile)
-        strcat(lockfile, "/");
-    strcat(lockfile, "rogue54.lck");
-    fd = open(scorefile, O_RDWR | O_CREAT, 0666);
+    if (*homedir) {
+        snprintf(scorefile, PATH_MAX, "%s/rogue54.scr", homedir);
+    } else {
+        strcpy(scorefile, "rogue54.scr");
+    }
+
+    if (*homedir) {
+        snprintf(lockfile, PATH_MAX, "%s/rogue54.lck", homedir);
+    } else {
+        strcpy(scorefile, "rogue54.lck");
+    }
+    scoreboard = fopen(scorefile, "r+");
+    if (scoreboard == NULL) {
+        fprintf(stderr, "Could not open %s for writing: %s\n", scorefile, strerror(errno));
+        fflush(stderr);
+    }
 #else
-    fd = -1;
+    scoreboard = NULL;
 #endif
+    /*
+     * Drop setuid/setgid after opening the scoreboard file.
+     */
     md_normaluser();
 }
 
diff -Naur --exclude '*.swp' rogue/main.c rogue.new/main.c
--- rogue/main.c	2006-01-29 16:11:32.000000000 -0800
+++ rogue.new/main.c	2006-03-30 13:40:16.000000000 -0800
@@ -24,6 +24,13 @@
     char *env;
     int lowtime;
 
+    /*
+     * Open the scoreboard file and drop setuid/setgid privileges immediately.
+     * open_score() calls md_normaluser() to drop privileges, so we don't have
+     * to do it here explicitly.
+     */
+    open_score();
+
     md_init();
 
 #ifndef DUMP
@@ -89,7 +96,6 @@
     /*
      * check for print-score option
      */
-    open_score();
     if (argc == 2)
 	if (strcmp(argv[1], "-s") == 0)
 	{
diff -Naur --exclude '*.swp' rogue/mdport.c rogue.new/mdport.c
--- rogue/mdport.c	2006-01-29 18:24:39.000000000 -0800
+++ rogue.new/mdport.c	2006-04-01 19:26:16.000000000 -0800
@@ -193,8 +193,17 @@
 md_normaluser()
 {
 #ifndef _WIN32
-    setuid(getuid());
-    setgid(getgid());
+    gid_t realgid = getgid();
+    uid_t realuid = getuid();
+
+    if (setresgid(-1, realgid, realgid) != 0) {
+        perror("Could not drop setgid privileges.  Aborting.");
+        exit(1);
+    }
+    if (setresuid(-1, realuid, realuid) != 0) {
+        perror("Could not drop setuid privileges.  Aborting.");
+        exit(1);
+    }
 #endif
 }
 
@@ -397,22 +406,31 @@
 char *
 md_getroguedir()
 {
-    static char path[1024];
+    static char path[PATH_MAX];
     char *end,*home;
 
     if ( (home = getenv("ROGUEHOME")) != NULL)
     {
         if (*home)
         {
-            strncpy(path, home, PATH_MAX - 20);
-
-            end = &path[strlen(path)-1];
-
-            while( (end >= path) && ((*end == '/') || (*end == '\\')))
-                *end-- = '\0';
-
-            if (directory_exists(path))
-                return(path);
+            if (strlen(home) > PATH_MAX-20) {
+                fprintf(stderr, "ROGUEHOME path is too long.  Ignoring.\n");
+            } else {
+                strncpy(path, home, PATH_MAX-20);
+                /* Ensure that we have a terminating NULL character.
+                 */
+                path[PATH_MAX-1] = (char)NULL;
+    
+                end = &path[strlen(path)-1];
+    
+                /* Strip off any trailing path separators from the path.
+                 */
+                while( (end >= path) && ((*end == '/') || (*end == '\\')))
+                    *end-- = '\0';
+    
+                if (directory_exists(path))
+                    return(path);
+            }
         }
     }
 
diff -Naur --exclude '*.swp' rogue/rip.c rogue.new/rip.c
--- rogue/rip.c	2006-01-03 16:17:29.000000000 -0800
+++ rogue.new/rip.c	2006-03-30 13:32:17.000000000 -0800
@@ -60,7 +60,6 @@
     int i;
     SCORE *sc2;
     SCORE *top_ten, *endp;
-    FILE *outf;
 # ifdef MASTER
     int prflags = 0;
 # endif
@@ -96,11 +95,7 @@
 	    delwin(hw);
     }
 
-    if (fd >= 0)
-	outf = (FILE *)fdopen(fd, "w");
-    else
-	return;
-
+    open_score();
     top_ten = (SCORE *) malloc(numscores * sizeof (SCORE));
     endp = &top_ten[numscores];
     for (scp = top_ten; scp < endp; scp++)
@@ -123,11 +118,9 @@
 	else if (strcmp(prbuf, "edit") == 0)
 	    prflags = 2;
 #endif
-    rd_score(top_ten, fd);
-    fclose(outf);
-    close(fd);
-    open_score(0);
-    outf = (FILE *) fdopen(fd, "w");
+    open_score();
+    rd_score(top_ten, scoreboard);
+    open_score();
     /*
      * Insert her in list if need be
      */
@@ -222,7 +215,7 @@
 	else
 	    break;
     }
-    fseek(outf, 0L, SEEK_SET);
+    fseek(scoreboard, 0L, SEEK_SET);
     /*
      * Update the list file
      */
@@ -231,12 +224,11 @@
 	if (lock_sc())
 	{
 	    fp = signal(SIGINT, SIG_IGN);
-	    wr_score(top_ten, outf);
+	    wr_score(top_ten, scoreboard);
 	    unlock_sc();
 	    signal(SIGINT, fp);
 	}
     }
-    fclose(outf);
 }
 
 /*
diff -Naur --exclude '*.swp' rogue/save.c rogue.new/save.c
--- rogue/save.c	2006-01-30 08:05:35.000000000 -0800
+++ rogue.new/save.c	2006-03-30 13:33:45.000000000 -0800
@@ -335,7 +335,40 @@
 
 /*
  * encread:
- *	Perform an encrypted read
+ *	Perform an encrypted read from a FILE stream
+ */
+size_t
+encread_fromstream(char *start, size_t size, FILE *inf)
+{
+    char *e1, *e2, fb;
+    int temp, read_size;
+    extern char statlist[];
+
+    fb = frob;
+
+    if ((read_size = fread(start, size, 1, inf)) == 0 || read_size == -1)
+	return(read_size);
+
+    e1 = encstr;
+    e2 = statlist;
+
+    while (size--)
+    {
+	*start++ ^= *e1 ^ *e2 ^ fb;
+	temp = *e1++;
+	fb += temp * *e2++;
+	if (*e1 == '\0')
+	    e1 = encstr;
+	if (*e2 == '\0')
+	    e2 = statlist;
+    }
+
+    return(read_size);
+}
+
+/*
+ * encread
+ *	Perform an encrypted read from a file descriptor
  */
 size_t
 encread(char *start, size_t size, int inf)
@@ -371,14 +404,14 @@
  * read_scrore
  *	Read in the score file
  */
-rd_score(SCORE *top_ten, int fd)
+rd_score(SCORE *top_ten, FILE *fd)
 {
     unsigned int i;
 
     for(i = 0; i < numscores; i++)
     {
-        encread(top_ten[i].sc_name, MAXSTR, fd);
-        encread(scoreline, 100, fd);
+        encread_fromstream(top_ten[i].sc_name, MAXSTR, fd);
+        encread_fromstream(scoreline, 100, fd);
         sscanf(scoreline, " %u %hu %u %hu %hu %lx \n",
             &top_ten[i].sc_uid, &top_ten[i].sc_score,
             &top_ten[i].sc_flags, &top_ten[i].sc_monster,
diff -Naur --exclude '*.swp' rogue/state.c rogue.new/state.c
--- rogue/state.c	2006-01-03 16:17:29.000000000 -0800
+++ rogue.new/state.c	2006-03-30 13:09:46.000000000 -0800
@@ -2138,7 +2138,8 @@
     rs_write_int(savef, no_food);
     rs_write_ints(savef,a_class,MAXARMORS);
     rs_write_int(savef, count);
-    rs_write_int(savef, fd);
+    // Don't bother saving the file descriptor anymore.
+    rs_write_int(savef, -1);
     rs_write_int(savef, food_left);
     rs_write_int(savef, lastscore);
     rs_write_int(savef, no_command);
@@ -2275,7 +2276,8 @@
     rs_read_int(inf, &no_food);
     rs_read_ints(inf,a_class,MAXARMORS);
     rs_read_int(inf, &count);
-    rs_read_int(inf, &fd);
+    // Read the file descriptor, but ignore it.
+    rs_read_int(inf, &junk3);
     rs_read_int(inf, &food_left);
     rs_read_int(inf, &lastscore);
     rs_read_int(inf, &no_command);




More information about the fedora-extras-commits mailing list