Synopsis: rogue vulnerability NetBSD versions: 1.6, 1.5.3, 1.5.2, 1.5.1, 1.5 Thanks to: stanojr, Simon Burge Reported in NetBSD Security Advisory: NetBSD-SA2002-021 Index: inventory.c =================================================================== RCS file: /cvsroot/basesrc/games/rogue/inventory.c,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- inventory.c 2002/07/07 09:35:08 1.7 +++ inventory.c 2002/10/01 14:18:57 1.8 @@ -421,14 +421,14 @@ mix_colors() { short i, j, k; - char *t; + char t[MAX_ID_TITLE_LEN]; for (i = 0; i <= 32; i++) { j = get_rand(0, (POTIONS - 1)); k = get_rand(0, (POTIONS - 1)); - t = id_potions[j].title; - id_potions[j].title = id_potions[k].title; - id_potions[k].title = t; + memcpy(t, id_potions[j].title, MAX_ID_TITLE_LEN); + memcpy(id_potions[j].title, id_potions[k].title, MAX_ID_TITLE_LEN); + memcpy(id_potions[k].title, t, MAX_ID_TITLE_LEN); } } Index: message.c =================================================================== RCS file: /cvsroot/basesrc/games/rogue/message.c,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- message.c 2000/07/10 10:19:27 1.8 +++ message.c 2002/10/01 14:18:57 1.9 @@ -64,7 +64,7 @@ char msgs[NMESSAGES][DCOLS] = {"", "", "", "", ""}; short msg_col = 0, imsg = -1; boolean msg_cleared = 1, rmsg = 0; -char hunger_str[8] = ""; +char hunger_str[HUNGER_STR_LEN] = ""; const char *more = "-more-"; void Index: rogue.h =================================================================== RCS file: /cvsroot/basesrc/games/rogue/rogue.h,v retrieving revision 1.12 retrieving revision 1.13 diff -u -r1.12 -r1.13 --- rogue.h 2001/02/05 01:04:25 1.12 +++ rogue.h 2002/10/01 14:18:57 1.13 @@ -192,9 +192,10 @@ #define MAX_OPT_LEN 40 +#define MAX_ID_TITLE_LEN 64 struct id { short value; - char *title; + char title[MAX_ID_TITLE_LEN]; char *real; unsigned short id_status; }; @@ -658,7 +659,7 @@ void rand_place __P((object *)); void read_pack __P((object *, FILE *, boolean)); void read_scroll __P((void)); -void read_string __P((char *, FILE *)); +void read_string __P((char *, FILE *, size_t)); void recursive_deadend __P((short, const short *, short, short)); boolean reg_move __P((void)); void relight __P((void)); @@ -763,8 +764,9 @@ extern boolean trap_door; extern boolean wizard; extern char hit_message[]; -extern char hunger_str[]; -extern char login_name[]; +#define HUNGER_STR_LEN 8 +extern char hunger_str[HUNGER_STR_LEN]; +extern char login_name[MAX_OPT_LEN]; extern const char *byebye_string; extern const char *curse_message; extern const char *error_file; Index: save.c =================================================================== RCS file: /cvsroot/basesrc/games/rogue/save.c,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- save.c 1999/09/18 19:38:54 1.7 +++ save.c 2002/10/01 14:18:58 1.8 @@ -102,8 +102,8 @@ } } } - if ( ((fp = fopen(sfile, "w")) == NULL) || - ((file_id = md_get_file_id(sfile)) == -1)) { + if (((fp = fopen(sfile, "w")) == NULL) || + ((file_id = md_get_file_id(sfile)) == -1)) { message("problem accessing the save file", 0); return; } @@ -166,8 +166,8 @@ int new_file_id, saved_file_id; fp = NULL; - if ( ((new_file_id = md_get_file_id(fname)) == -1) || - ((fp = fopen(fname, "r")) == NULL)) { + if (((new_file_id = md_get_file_id(fname)) == -1) || + ((fp = fopen(fname, "r")) == NULL)) { clean_up("cannot open file"); } if (md_link_count(fname) > 1) { @@ -177,10 +177,10 @@ r_read(fp, (char *) &detect_monster, sizeof(detect_monster)); r_read(fp, (char *) &cur_level, sizeof(cur_level)); r_read(fp, (char *) &max_level, sizeof(max_level)); - read_string(hunger_str, fp); + read_string(hunger_str, fp, sizeof hunger_str); - (void) strcpy(tbuf, login_name); - read_string(login_name, fp); + (void) strlcpy(tbuf, login_name, sizeof tbuf); + read_string(login_name, fp, sizeof login_name); if (strcmp(tbuf, login_name)) { clean_up("you're not the original player"); } @@ -269,9 +269,9 @@ *new_obj = read_obj; if (is_rogue) { if (new_obj->in_use_flags & BEING_WORN) { - do_wear(new_obj); + do_wear(new_obj); } else if (new_obj->in_use_flags & BEING_WIELDED) { - do_wield(new_obj); + do_wield(new_obj); } else if (new_obj->in_use_flags & (ON_EITHER_HAND)) { do_put_on(new_obj, ((new_obj->in_use_flags & ON_LEFT_HAND) ? 1 : 0)); @@ -326,7 +326,7 @@ r_read(fp, (char *) &(id_table[i].value), sizeof(short)); r_read(fp, (char *) &(id_table[i].id_status), sizeof(unsigned short)); - read_string(id_table[i].title, fp); + read_string(id_table[i].title, fp, MAX_ID_TITLE_LEN); } } } @@ -345,13 +345,16 @@ } void -read_string(s, fp) +read_string(s, fp, len) char *s; FILE *fp; + size_t len; { short n; r_read(fp, (char *) &n, sizeof(short)); + if (n > len) + clean_up("read_string: corrupt game file"); r_read(fp, s, n); xxxx(s, n); }