]> granicus.if.org Git - nethack/commitdiff
fix github issue #507 - filename buffer overflow
authorPatR <rankin@nethack.org>
Sun, 9 May 2021 01:02:00 +0000 (18:02 -0700)
committerPatR <rankin@nethack.org>
Sun, 9 May 2021 01:02:00 +0000 (18:02 -0700)
when compressing or uncompressing a save file.  Defining
VAR_PLAYGROUND forces PREFIXES_IN_USE to be defined, and the latter
causes docompress_file() to be called with save file name containing
a full path instead of just save/xyzzy.Z relative to the playground.
Depending on the value of VAR_PLAYGROUND, that could be too long for
the buffer used to make a copy of the name with ".Z"/".gz"/".bz2"
appended.

Probably only applies to Unix/linux/OSX configurations.

Fixes #507

doc/fixes37.0
src/files.c

index e0c478227cbc3e7fbc2309d368e777c9f83a3f32..6ccdc257118e7aaca9ef960e8deac4c381640018 100644 (file)
@@ -1,4 +1,4 @@
-NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.527 $ $NHDT-Date: 1620413928 2021/05/07 18:58:48 $
+NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.528 $ $NHDT-Date: 1620522110 2021/05/09 01:01:50 $
 
 General Fixes and Modified Features
 -----------------------------------
@@ -504,6 +504,10 @@ when an unseen non-pet picks up or uses an item, hero loses known/dknown/
        particular, player won't be asked what to call unseen thrown potion)
 wishing for a partly eaten wraith corpse yielded "partly eaten food (1) more
        nutritious than untouched food (0)"
+if PREFIXES_IN_USE was defined (and VAR_PLAYGROUND forces it to be) when
+       COMPRESS was also defined (external save and bones file compression
+       via fork()+exec()), the file name buffer in docompress_file() wasn't
+       big enough so could overflow and trigger a crash
 
 
 Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
index 58ede76f858d484aca0acc96740c49d8232daddc..66f50963305492946d7843870a4888fc19c7950a 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.7 files.c $NHDT-Date: 1612819003 2021/02/08 21:16:43 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.331 $ */
+/* NetHack 3.7 files.c $NHDT-Date: 1620522110 2021/05/09 01:01:50 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.334 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Derek S. Ray, 2015. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -1312,7 +1312,7 @@ free_saved_games(char **saved)
 
 /* ----------  BEGIN FILE COMPRESSION HANDLING ----------- */
 
-#ifdef COMPRESS
+#ifdef COMPRESS /* external compression */
 
 static void
 redirect(const char *filename, const char *mode, FILE *stream, boolean uncomp)
@@ -1341,7 +1341,8 @@ redirect(const char *filename, const char *mode, FILE *stream, boolean uncomp)
 static void
 docompress_file(const char *filename, boolean uncomp)
 {
-    char cfn[SAVESIZE];
+    char *cfn = 0;
+    const char *xtra;
     FILE *cf;
     const char *args[10];
 #ifdef COMPRESS_OPTIONS
@@ -1349,18 +1350,27 @@ docompress_file(const char *filename, boolean uncomp)
 #endif
     int i = 0;
     int f;
+    unsigned ln;
 #ifdef TTY_GRAPHICS
     boolean istty = WINDOWPORT("tty");
 #endif
 
-    Strcpy(cfn, filename);
 #ifdef COMPRESS_EXTENSION
-    Strcat(cfn, COMPRESS_EXTENSION);
+    xtra = COMPRESS_EXTENSION;
+#else
+    xtra = "";
 #endif
+    ln = (unsigned) (strlen(filename) + strlen(xtra));
+    cfn = (char *) alloc(ln + 1);
+    Strcpy(cfn, filename);
+    Strcat(cfn, xtra);
+
     /* when compressing, we know the file exists */
     if (uncomp) {
-        if ((cf = fopen(cfn, RDBMODE)) == (FILE *) 0)
+        if ((cf = fopen(cfn, RDBMODE)) == (FILE *) 0) {
+            free((genericptr_t) cfn);
             return;
+        }
         (void) fclose(cf);
     }
 
@@ -1431,10 +1441,12 @@ docompress_file(const char *filename, boolean uncomp)
         perror((char *) 0);
         (void) fprintf(stderr, "Exec to %scompress %s failed.\n",
                        uncomp ? "un" : "", filename);
+        free((genericptr_t) cfn);
         nh_terminate(EXIT_FAILURE);
     } else if (f == -1) {
         perror((char *) 0);
         pline("Fork to %scompress %s failed.", uncomp ? "un" : "", filename);
+        free((genericptr_t) cfn);
         return;
     }
 #ifndef NO_SIGNAL
@@ -1483,8 +1495,11 @@ docompress_file(const char *filename, boolean uncomp)
         }
 #endif
     }
+
+    free((genericptr_t) cfn);
 }
-#endif /* COMPRESS */
+
+#endif /* COMPRESS : external compression */
 
 #if defined(COMPRESS) || defined(ZLIB_COMP)
 #define UNUSED_if_not_COMPRESS /*empty*/
@@ -3840,7 +3855,7 @@ recover_savefile(void)
     struct savefile_info sfi;
     char tmpplbuf[PL_NSIZ];
     const char *savewrite_failure = (const char *) 0;
-    
+
     for (lev = 0; lev < 256; lev++)
         processed[lev] = 0;
 
@@ -3937,7 +3952,7 @@ recover_savefile(void)
     if (savewrite_failure)
         goto cleanup;
 
-    if (snhfp->structlevel) {         
+    if (snhfp->structlevel) {
         if (write(snhfp->fd, (genericptr_t) &pltmpsiz, sizeof pltmpsiz)
             != sizeof pltmpsiz)
             savewrite_failure = "player name size";