From 3dfd8fd09b82834d478c2356f54d9c8eb3332bc1 Mon Sep 17 00:00:00 2001 From: "John \"Elwin\" Edwards" Date: Mon, 3 May 2021 19:05:37 -0400 Subject: [PATCH] Advanced Rogue family: fix some potential buffer overflows. Some code for determining the score file location assumed that PATH_MAX would be less than 1024, which cannot be guaranteed. Advanced Rogue 5 and 7, and XRogue, have had the buffers for the file name enlarged. UltraRogue never called the functions, so the code has been deleted instead. --- arogue5/main.c | 5 +++-- arogue5/mdport.c | 16 ++++++++++------ arogue5/options.c | 3 ++- arogue5/rogue.c | 3 ++- arogue7/main.c | 6 ++++-- arogue7/mdport.c | 15 +++++++++------ arogue7/options.c | 3 ++- arogue7/rogue.c | 3 ++- urogue/mdport.c | 48 ----------------------------------------------- xrogue/main.c | 6 ++++-- xrogue/options.c | 3 ++- xrogue/rogue.c | 3 ++- xrogue/state.c | 15 +++++++++------ 13 files changed, 51 insertions(+), 78 deletions(-) diff --git a/arogue5/main.c b/arogue5/main.c index 8f9a511..61705fb 100644 --- a/arogue5/main.c +++ b/arogue5/main.c @@ -61,6 +61,7 @@ main(int argc, char *argv[], char *envp[]) * get home and options from environment */ strncpy(home,md_gethomedir(),LINELEN); + home[LINELEN-1] = '\0'; #ifdef SAVEDIR if (argc >= 3 && !strcmp(argv[1], "-n")) { @@ -82,8 +83,8 @@ main(int argc, char *argv[], char *envp[]) } #ifdef SCOREFILE - strncpy(score_file, SCOREFILE, LINELEN); - score_file[LINELEN - 1] = '\0'; + strncpy(score_file, SCOREFILE, PATH_MAX); + score_file[PATH_MAX - 1] = '\0'; #else /* Get default score file */ strcpy(score_file, roguedir); diff --git a/arogue5/mdport.c b/arogue5/mdport.c index 17f17f8..968f948 100644 --- a/arogue5/mdport.c +++ b/arogue5/mdport.c @@ -418,7 +418,7 @@ directory_exists(char *dirname) char * md_getroguedir(void) { - static char path[1024]; + static char path[PATH_MAX-20]; char *end,*home; if ( (home = getenv("ROGUEHOME")) != NULL) @@ -427,13 +427,17 @@ md_getroguedir(void) { strncpy(path, home, PATH_MAX - 20); - end = &path[strlen(path)-1]; + if (path[PATH_MAX-21] == '\0') + { - while( (end >= path) && ((*end == '/') || (*end == '\\'))) - *end-- = '\0'; + end = &path[strlen(path)-1]; - if (directory_exists(path)) - return(path); + while( (end >= path) && ((*end == '/') || (*end == '\\'))) + *end-- = '\0'; + + if (directory_exists(path)) + return(path); + } } } diff --git a/arogue5/options.c b/arogue5/options.c index a1e50b9..39795fa 100644 --- a/arogue5/options.c +++ b/arogue5/options.c @@ -17,6 +17,7 @@ #include "curses.h" #include #include +#include #include "rogue.h" #define NUM_OPTS (sizeof optlist / sizeof (OPTION)) @@ -91,7 +92,7 @@ int get_restr(char *optstr, WINDOW *win) /* For the score file, which must be opened. */ int get_score(char *optstr, WINDOW *win) { - char old_score_file[LINELEN]; + char old_score_file[PATH_MAX]; int status; if (use_savedir) diff --git a/arogue5/rogue.c b/arogue5/rogue.c index cbdc399..100c6a7 100644 --- a/arogue5/rogue.c +++ b/arogue5/rogue.c @@ -13,6 +13,7 @@ */ #include +#include #include "curses.h" #include "rogue.h" @@ -85,7 +86,7 @@ char *ws_guess[MAXSTICKS]; /* Players guess at what wand is */ char *m_guess[MAXMM]; /* Players guess at what MM is */ char *ws_type[MAXSTICKS]; /* Is it a wand or a staff */ char file_name[256]; /* Save file name */ -char score_file[LINELEN]; /* Score file name */ +char score_file[PATH_MAX]; /* Score file name */ char home[LINELEN]; /* User's home directory */ WINDOW *cw; /* Window that the player sees */ WINDOW *hw; /* Used for the help command */ diff --git a/arogue7/main.c b/arogue7/main.c index 21c9768..e20d566 100644 --- a/arogue7/main.c +++ b/arogue7/main.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #ifdef BSD #include @@ -59,6 +60,7 @@ main(int argc, char *argv[], char *envp[]) */ strncpy(home, md_gethomedir(), LINELEN); + home[LINELEN-1] = '\0'; /* Get default save file */ strcpy(file_name, home); @@ -66,8 +68,8 @@ main(int argc, char *argv[], char *envp[]) /* Get default score file */ #ifdef SCOREFILE - strncpy(score_file, SCOREFILE, LINELEN); - score_file[LINELEN-1] = '\0'; + strncpy(score_file, SCOREFILE, PATH_MAX); + score_file[PATH_MAX-1] = '\0'; #else strcpy(score_file, md_getroguedir()); diff --git a/arogue7/mdport.c b/arogue7/mdport.c index 2deef49..332acfd 100644 --- a/arogue7/mdport.c +++ b/arogue7/mdport.c @@ -421,7 +421,7 @@ directory_exists(char *dirname) char * md_getroguedir(void) { - static char path[1024]; + static char path[PATH_MAX-20]; char *end,*home; if ( (home = getenv("ROGUEHOME")) != NULL) @@ -430,13 +430,16 @@ md_getroguedir(void) { strncpy(path, home, PATH_MAX - 20); - end = &path[strlen(path)-1]; + if (path[PATH_MAX-21] == '\0') + { + end = &path[strlen(path)-1]; - while( (end >= path) && ((*end == '/') || (*end == '\\'))) - *end-- = '\0'; + while( (end >= path) && ((*end == '/') || (*end == '\\'))) + *end-- = '\0'; - if (directory_exists(path)) - return(path); + if (directory_exists(path)) + return(path); + } } } diff --git a/arogue7/options.c b/arogue7/options.c index d22dc92..48235ea 100644 --- a/arogue7/options.c +++ b/arogue7/options.c @@ -21,6 +21,7 @@ #include "curses.h" #include +#include #include #include "rogue.h" @@ -491,7 +492,7 @@ get_str_prot(char *opt, WINDOW *win) int get_score(char *optstr, WINDOW *win) { - char old_score_file[LINELEN]; + char old_score_file[PATH_MAX]; int status; if (use_savedir) diff --git a/arogue7/rogue.c b/arogue7/rogue.c index 121d363..b2456ce 100644 --- a/arogue7/rogue.c +++ b/arogue7/rogue.c @@ -13,6 +13,7 @@ */ #include +#include #include "curses.h" #include "rogue.h" #ifdef PC7300 @@ -102,7 +103,7 @@ char *ws_guess[MAXSTICKS]; /* Players guess at what wand is */ char *m_guess[MAXMM]; /* Players guess at what MM is */ char *ws_type[MAXSTICKS]; /* Is it a wand or a staff */ char file_name[LINELEN]; /* Save file name */ -char score_file[LINELEN]; /* Score file name */ +char score_file[PATH_MAX]; /* Score file name */ char home[LINELEN]; /* User's home directory */ WINDOW *cw; /* Window that the player sees */ WINDOW *hw; /* Used for the help command */ diff --git a/urogue/mdport.c b/urogue/mdport.c index 056643f..e28c554 100644 --- a/urogue/mdport.c +++ b/urogue/mdport.c @@ -401,54 +401,6 @@ md_shellescape() #endif } -int -directory_exists(char *dirname) -{ - struct stat sb; - - if (stat(dirname, &sb) == 0) /* path exists */ - return (sb.st_mode & S_IFDIR); - - return(0); -} - -char * -md_getroguedir() -{ - static char path[1024]; - 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 (directory_exists("/var/games/roguelike")) - return("/var/games/roguelike"); - if (directory_exists("/var/lib/roguelike")) - return("/var/lib/roguelike"); - if (directory_exists("/var/roguelike")) - return("/var/roguelike"); - if (directory_exists("/usr/games/lib")) - return("/usr/games/lib"); - if (directory_exists("/games/roguelik")) - return("/games/roguelik"); - if (directory_exists(md_gethomedir())) - return(md_gethomedir()); - return(""); -} - char * md_getrealname(int uid) { diff --git a/xrogue/main.c b/xrogue/main.c index e0e1527..2e251f8 100644 --- a/xrogue/main.c +++ b/xrogue/main.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include "mach_dep.h" @@ -44,6 +45,7 @@ main(int argc, char *argv[], char *envp[]) */ strncpy(home, md_gethomedir(), LINELEN); + home[LINELEN-1] = '\0'; /* Get default save file */ strcpy(file_name, home); @@ -51,8 +53,8 @@ main(int argc, char *argv[], char *envp[]) /* Get default score file */ #ifdef SCOREFILE - strncpy(score_file, SCOREFILE, LINELEN); - score_file[LINELEN-1] = '\0'; + strncpy(score_file, SCOREFILE, PATH_MAX); + score_file[PATH_MAX-1] = '\0'; #else strcpy(score_file, md_getroguedir()); diff --git a/xrogue/options.c b/xrogue/options.c index f8a2a06..bbd89af 100644 --- a/xrogue/options.c +++ b/xrogue/options.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "rogue.h" #define NUM_OPTS (sizeof optlist / sizeof (OPTION)) @@ -524,7 +525,7 @@ get_str_prot(char *opt, WINDOW *win) int get_score(char *optstr, WINDOW *win) { - char old_score_file[LINELEN]; + char old_score_file[PATH_MAX]; int status; if (use_savedir) diff --git a/xrogue/rogue.c b/xrogue/rogue.c index 81fe412..82c40da 100644 --- a/xrogue/rogue.c +++ b/xrogue/rogue.c @@ -18,6 +18,7 @@ #include #include +#include #include "rogue.h" /* @@ -90,7 +91,7 @@ char *ws_guess[MAXSTICKS]; /* Players guess at what wand is */ char *m_guess[MAXMM]; /* Players guess at what MM is */ char *ws_type[MAXSTICKS]; /* Is it a wand or a staff */ char file_name[LINELEN]; /* Save file name */ -char score_file[LINELEN]; /* Score file name */ +char score_file[PATH_MAX]; /* Score file name */ char home[LINELEN]; /* User's home directory */ WINDOW *cw; /* Window that the player sees */ WINDOW *hw; /* Used for the help command */ diff --git a/xrogue/state.c b/xrogue/state.c index 68aee34..da0d2e2 100644 --- a/xrogue/state.c +++ b/xrogue/state.c @@ -3301,7 +3301,7 @@ directory_exists(char *dirname) char * md_getroguedir(void) { - static char path[1024]; + static char path[PATH_MAX-20]; char *end,*home; if ( (home = getenv("ROGUEHOME")) != NULL) @@ -3310,14 +3310,17 @@ md_getroguedir(void) { strncpy(path, home, PATH_MAX - 20); - end = &path[strlen(path)-1]; + if (path[PATH_MAX-21] == '\0') + { + end = &path[strlen(path)-1]; - while( (end >= path) && ((*end == '/') || (*end == '\\'))) - *end-- = '\0'; + while( (end >= path) && ((*end == '/') || (*end == '\\'))) + *end-- = '\0'; - if (directory_exists(path)) - return(path); + if (directory_exists(path)) + return(path); + } } }