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 scm-commits
mailing list