Sophie

Sophie

distrib > Mageia > 8 > x86_64 > by-pkgid > 51b54b09f77a16e952254bb35bbf5878 > files > 6

bsd-games-2.17-32.mga8.src.rpm

diff -Naur --exclude '*.swp' bsd-games-2.17/hack/hack.bones.c bsd-games-2.17.new/hack/hack.bones.c
--- bsd-games-2.17/hack/hack.bones.c	2003-12-16 18:47:37.000000000 -0800
+++ bsd-games-2.17.new/hack/hack.bones.c	2006-04-27 14:17:06.000000000 -0700
@@ -140,10 +140,14 @@
 						 * ghost */
 		}
 	}
-	if ((fd = creat(bones, FMASK)) < 0)
+        setgid(hackgid);
+	if ((fd = creat(bones, FMASK)) < 0) {
+                setgid(getgid());
 		return;
+        }
 	savelev(fd, dlevel);
 	(void) close(fd);
+        setgid(getgid());
 }
 
 int
@@ -168,9 +172,12 @@
 	if (!wizard)		/* duvel!frans: don't remove bones while
 				 * debugging */
 #endif	/* WiZARD */
+                setgid(hackgid);
 		if (unlink(bones) < 0) {
+                        setgid(getgid());
 			pline("Cannot unlink %s .", bones);
 			return (0);
 		}
+                setgid(getgid());
 	return (ok);
 }
diff -Naur --exclude '*.swp' bsd-games-2.17/hack/hack.do.c bsd-games-2.17.new/hack/hack.do.c
--- bsd-games-2.17/hack/hack.do.c	2004-01-27 12:52:07.000000000 -0800
+++ bsd-games-2.17.new/hack/hack.do.c	2006-04-27 14:32:43.000000000 -0700
@@ -206,7 +206,9 @@
 		return;		/* this can happen */
 
 	glo(dlevel);
+        setgid(hackgid);
 	fd = creat(lock, FMASK);
+        setgid(getgid());
 	if (fd < 0) {
 		/*
 		 * This is not quite impossible: e.g., we may have
@@ -231,8 +233,10 @@
 	u.ux = FAR;		/* hack */
 	(void) inshop();	/* probably was a trapdoor */
 
+        setgid(hackgid);
 	savelev(fd, dlevel);
 	(void) close(fd);
+        setgid(getgid());
 
 	dlevel = newlevel;
 	if (maxdlevel < dlevel)
diff -Naur --exclude '*.swp' bsd-games-2.17/hack/hack.end.c bsd-games-2.17.new/hack/hack.end.c
--- bsd-games-2.17/hack/hack.end.c	2003-12-16 18:47:37.000000000 -0800
+++ bsd-games-2.17.new/hack/hack.end.c	2006-04-27 15:48:03.000000000 -0700
@@ -290,7 +290,11 @@
 #ifdef WIZARD
 	if (!wizard)
 #endif	/* WIZARD */
-		topten();
+        {
+            setgid(hackgid);
+            topten();
+            setgid(getgid());
+        }
 	if (done_stopprint)
 		printf("\n\n");
 	exit(0);
diff -Naur --exclude '*.swp' bsd-games-2.17/hack/hack.h bsd-games-2.17.new/hack/hack.h
--- bsd-games-2.17/hack/hack.h	2004-01-27 12:52:07.000000000 -0800
+++ bsd-games-2.17.new/hack/hack.h	2006-04-27 11:48:15.000000000 -0700
@@ -218,6 +218,7 @@
 extern int bases[];
 extern int doorindex;
 extern int hackpid;
+extern gid_t hackgid;
 extern int multi;
 extern int nroom;
 extern long moves;
diff -Naur --exclude '*.swp' bsd-games-2.17/hack/hack.main.c bsd-games-2.17.new/hack/hack.main.c
--- bsd-games-2.17/hack/hack.main.c	2004-01-27 12:52:07.000000000 -0800
+++ bsd-games-2.17.new/hack/hack.main.c	2006-04-27 20:16:23.000000000 -0700
@@ -61,6 +61,7 @@
  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#define _GNU_SOURCE /* this must be done before the first include of unistd.h */
 #include <sys/cdefs.h>
 #ifndef lint
 __RCSID("$NetBSD: hack.main.c,v 1.9 2004/01/27 20:30:29 jsm Exp $");
@@ -70,6 +71,9 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <fcntl.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <limits.h>
 #include "hack.h"
 #include "extern.h"
 
@@ -83,12 +87,13 @@
 int             (*occupation)(void);
 const char           *occtxt;		/* defined when occupation != NULL */
 
+gid_t           hackgid;        /* privileged gid for writing scoreboard */
 int             hackpid;	/* current pid */
 int             locknum;	/* max num of players */
 #ifdef DEF_PAGER
 const char     *catmore;	/* default pager */
 #endif
-char            SAVEF[PL_NSIZ + 11] = "save/";	/* save/99999player */
+char            SAVEF[PATH_MAX + PL_NSIZ + 11] = ".hack.save";
 char           *hname;		/* name of the game (argv[0] of call) */
 char            obuf[BUFSIZ];	/* BUFSIZ is defined in stdio.h */
 
@@ -101,9 +106,10 @@
 	char           *argv[];
 {
 	int             fd;
-#ifdef CHDIR
-	char           *dir;
-#endif
+        char           *savedir = (char *)NULL;
+
+        hackgid = getegid();
+        setgid(getgid());
 
 	/* Check for dirty tricks with closed fds 0, 1, 2 */
 	fd = open("/dev/null", O_RDONLY);
@@ -114,31 +120,47 @@
 	hname = argv[0];
 	hackpid = getpid();
 
-#ifdef CHDIR			/* otherwise no chdir() */
 	/*
-	 * See if we must change directory to the playground.
-	 * (Perhaps hack runs suid and playground is inaccessible
-	 *  for the player.)
+         * Find the directory containing the save files.
 	 * The environment variable HACKDIR is overridden by a
 	 *  -d command line option (must be the first option given)
 	 */
 
-	dir = getenv("HACKDIR");
+	savedir = getenv("HACKDIR");
 	if (argc > 1 && !strncmp(argv[1], "-d", 2)) {
 		argc--;
 		argv++;
-		dir = argv[0] + 2;
-		if (*dir == '=' || *dir == ':')
-			dir++;
-		if (!*dir && argc > 1) {
+		savedir = argv[0] + 2;
+		if (*savedir == '=' || *savedir == ':')
+			savedir++;
+		if (!*savedir && argc > 1) {
 			argc--;
 			argv++;
-			dir = argv[0];
+			savedir = argv[0];
 		}
-		if (!*dir)
+		if (!*savedir)
 			error("Flag -d must be followed by a directory name.");
 	}
-#endif
+
+        /*
+         * If the user didn't tell us where the save games are stored then
+         * look in the home directory.
+         */
+        if (savedir == (char *)NULL) {
+            if ((savedir = getenv("HOME")) == (char *)NULL) {
+                struct passwd *pwe;
+                pwe = getpwuid(getuid());
+                if (pwe == NULL || (savedir = pwe->pw_dir) == (char *)NULL) {
+                    savedir = ".";
+                }
+            }
+        }
+        /*
+         * One final check in case we missed something earlier.
+         */
+        if (savedir == NULL || strlen(savedir) > PATH_MAX-30) {
+            savedir = ".";
+        }
 
 	/*
 	 * Who am i? Algorithm: 1. Use name as specified in HACKOPTIONS
@@ -155,12 +177,21 @@
 		char           *s;
 
 		initoptions();
-		if (!*plname && (s = getenv("USER")))
+		if (!*plname && (s = getenv("USER"))) {
 			(void) strncpy(plname, s, sizeof(plname) - 1);
-		if (!*plname && (s = getenv("LOGNAME")))
+                }
+		if (!*plname && (s = getenv("LOGNAME"))) {
 			(void) strncpy(plname, s, sizeof(plname) - 1);
-		if (!*plname && (s = getlogin()))
+                }
+		if (!*plname && (s = getlogin())) {
 			(void) strncpy(plname, s, sizeof(plname) - 1);
+                }
+                /*
+                 * Ensure that plname is null-terminated.  strncpy
+                 * doesn't guarantee it if the source is longer than
+                 * the destination.
+                 */
+                plname[sizeof(plname) - 1] = (char)NULL;
 	}
 
 	/*
@@ -169,11 +200,12 @@
 	 */
 	if (argc > 1 && !strncmp(argv[1], "-s", 2)) {
 #ifdef CHDIR
-		chdirx(dir, 0);
+		chdirx(_PATH_HACK, 0);
 #endif
 		prscore(argc, argv);
 		exit(0);
 	}
+
 	/*
 	 * It seems he really wants to play.
 	 * Remember tty modes, to be restored on exit.
@@ -191,13 +223,13 @@
 	 * Find the creation date of this game,
 	 * so as to avoid restoring outdated savefiles.
 	 */
-	gethdate(hname);
+	gethdate(argv[0]);
 
 	/*
 	 * We cannot do chdir earlier, otherwise gethdate will fail.
 	 */
 #ifdef CHDIR
-	chdirx(dir, 1);
+	chdirx(_PATH_HACK, 1);
 #endif
 
 	/*
@@ -277,7 +309,9 @@
 		(void) signal(SIGINT, SIG_IGN);
 		if (!locknum)
 			(void) strcpy(lock, plname);
+                setgid(hackgid);
 		getlock();	/* sets lock if locknum != 0 */
+                setgid(getgid());
 #ifdef WIZARD
 	} else {
 		char           *sfoo;
@@ -308,10 +342,21 @@
 	}
 #endif
 	setftty();
-	(void) sprintf(SAVEF, "save/%d%s", getuid(), plname);
-	regularize(SAVEF + 5);	/* avoid . or / in name */
-	if ((fd = open(SAVEF, O_RDONLY)) >= 0 &&
-	    (uptodate(fd) || unlink(SAVEF) == 666)) {
+
+	(void) snprintf(SAVEF, PATH_MAX, "%s/.hack.save-%d%s", savedir, getuid(), plname);
+        /* Disable this regularization.  It's only needed when using
+         * setgid and a a shared directory for save games.  In Fedora we've
+         * patched it to save games with normal user permissions (not setgid),
+         * so this isn't necessary anymore.
+         */
+	/*regularize(SAVEF + 5);*/	/* avoid . or / in name */
+        /*
+         * Removed check if the save game is up-to-date so we can avoid
+         * invalidating games during bugfix releases.  It would be
+         * _much_ better to store some sort of savefile version number
+         * in the savefile itself.
+         */
+	if ((fd = open(SAVEF, O_RDONLY)) >= 0) {
 		(void) signal(SIGINT, done1);
 		pline("Restoring old save file...");
 		(void) fflush(stdout);
@@ -540,16 +585,6 @@
 	boolean         wr;
 {
 
-#ifdef SECURE
-	if (dir			/* User specified directory? */
-#ifdef HACKDIR
-	    && strcmp(dir, HACKDIR)	/* and not the default? */
-#endif
-		) {
-		(void) setuid(getuid());	/* Ron Wessels */
-		(void) setregid(getgid(), getgid());
-	}
-#endif
 
 #ifdef HACKDIR
 	if (dir == NULL)
@@ -568,12 +603,34 @@
 
 		if (dir == NULL)
 			dir = ".";
-		if ((fd = open(RECORD, O_RDWR)) < 0) {
-			printf("Warning: cannot write %s/%s", dir, RECORD);
+
+                setgid(hackgid);
+		fd = open(RECORD, O_RDWR);
+                setgid(getgid());
+
+		if (fd < 0) {
+			printf("Warning: cannot write %s", RECORD);
 			getret();
 		} else
 			(void) close(fd);
 	}
+
+#ifdef SECURE
+	if (dir			/* User specified directory? */
+#ifdef HACKDIR
+	    && strcmp(dir, HACKDIR)	/* and not the default? */
+#endif
+		) {
+                if (setresuid(-1, getuid(), getuid()) == -1) {
+                    perror("Could not drop setuid privileges.  Aborting.");
+                    exit(1);
+                }
+                if (setresgid(-1, getgid(), getgid()) == -1) {
+                    perror("Could not drop setgid privileges.  Aborting.");
+                    exit(1);
+                }
+	}
+#endif
 }
 #endif
 
diff -Naur --exclude '*.swp' bsd-games-2.17/hack/hack.save.c bsd-games-2.17.new/hack/hack.save.c
--- bsd-games-2.17/hack/hack.save.c	2003-12-16 18:47:37.000000000 -0800
+++ bsd-games-2.17.new/hack/hack.save.c	2006-04-27 20:12:41.000000000 -0700
@@ -105,8 +105,9 @@
 	(void) signal(SIGHUP, SIG_IGN);
 	(void) signal(SIGINT, SIG_IGN);
 	if ((fd = creat(SAVEF, FMASK)) < 0) {
-		if (!hu)
-			pline("Cannot open save file. (Continue or Quit)");
+		if (!hu) {
+			pline("Cannot open save file %s. (Continue or Quit)", SAVEF);
+                }
 		(void) unlink(SAVEF);	/* ab@unido */
 		return (0);
 	}
@@ -198,10 +199,14 @@
 			break;
 		getlev(fd, 0, tmp);
 		glo(tmp);
-		if ((nfd = creat(lock, FMASK)) < 0)
+                setgid(hackgid);
+		if ((nfd = creat(lock, FMASK)) < 0) {
+                        setgid(getgid());
 			panic("Cannot open temp file %s!\n", lock);
+                }
 		savelev(nfd, tmp);
 		(void) close(nfd);
+                setgid(getgid());
 	}
 	(void) lseek(fd, (off_t) 0, SEEK_SET);
 	getlev(fd, 0, 0);
diff -Naur --exclude '*.swp' bsd-games-2.17/hack/hack.unix.c bsd-games-2.17.new/hack/hack.unix.c
--- bsd-games-2.17/hack/hack.unix.c	2003-12-16 18:47:37.000000000 -0800
+++ bsd-games-2.17.new/hack/hack.unix.c	2006-04-27 19:50:20.000000000 -0700
@@ -161,6 +161,9 @@
 
 struct stat     buf, hbuf;
 
+/*
+ * Get the timestamp of the named executable.
+ */
 void
 gethdate(name)
 	char           *name;
@@ -192,9 +195,15 @@
 	for (;;) {
 		if ((np = strchr(path, ':')) == NULL)
 			np = path + strlen(path);	/* point to end str */
-		if (np - path <= 1)	/* %% */
+		if (np - path <= 1) {	/* %% */
 			(void) strcpy(filename, name);
-		else {
+                } else if (strlen(path) >= MAXPATHLEN-strlen(name)-2) {
+                /*
+                 * Protect against long directories in PATH by skipping them.
+                 */
+                    path = np + 1;
+                    continue;
+                } else {
 			(void) strncpy(filename, path, np - path);
 			filename[np - path] = '/';
 			(void) strcpy(filename + (np - path) + 1, name);
@@ -231,6 +240,9 @@
 {
 	int             i;
 	time_t          date;
+        gid_t           initial_egid;
+
+        initial_egid = getegid();
 
 	if (fstat(fd, &buf))
 		return (0);	/* cannot get status */
@@ -255,13 +267,17 @@
 			return (0);
 	}
 	(void) close(fd);
+        setgid(hackgid);
 	for (i = 1; i <= MAXLEVEL; i++) {	/* try to remove all */
 		glo(i);
 		(void) unlink(lock);
 	}
 	glo(0);
-	if (unlink(lock))
+	if (unlink(lock)) {
+                setgid(initial_egid);
 		return (0);	/* cannot remove it */
+        }
+        setgid(initial_egid);
 	return (1);		/* success! */
 }
 
@@ -321,8 +337,9 @@
 	      : "There is a game in progress under your name.");
 gotlock:
 	fd = creat(lock, FMASK);
-	if (unlink(LLOCK) == -1)
+	if (unlink(LLOCK) == -1) {
 		error("Cannot unlink %s.", LLOCK);
+        }
 	if (fd == -1) {
 		error("cannot creat lock file.");
 	} else {