Fix format overflow issues (#52)

Replace a few sprintf calls with snprintf to prevent buffer overflow.
Added error messages to the logs where buffer size prevents a room,
object, mobile, or quest from being saved to disk.
This commit is contained in:
Kevin Fischer 2018-07-15 10:52:28 -05:00 committed by wyld-sw
parent bf941bc9b2
commit ad88f94a46
6 changed files with 70 additions and 46 deletions

View file

@ -368,7 +368,7 @@ int write_mobile_record(mob_vnum mvnum, struct char_data *mob, FILE *fd)
strip_cr(strncpy(ldesc, GET_LDESC(mob), MAX_STRING_LENGTH - 1)); strip_cr(strncpy(ldesc, GET_LDESC(mob), MAX_STRING_LENGTH - 1));
strip_cr(strncpy(ddesc, GET_DDESC(mob), MAX_STRING_LENGTH - 1)); strip_cr(strncpy(ddesc, GET_DDESC(mob), MAX_STRING_LENGTH - 1));
sprintf(buf, "#%d\n" int n = snprintf(buf, MAX_STRING_LENGTH, "#%d\n"
"%s%c\n" "%s%c\n"
"%s%c\n" "%s%c\n"
"%s%c\n" "%s%c\n"
@ -380,7 +380,7 @@ int write_mobile_record(mob_vnum mvnum, struct char_data *mob, FILE *fd)
ddesc, STRING_TERMINATOR ddesc, STRING_TERMINATOR
); );
if(n > MAX_STRING_LENGTH) {
fprintf(fd, "%s", convert_from_tabs(buf)); fprintf(fd, "%s", convert_from_tabs(buf));
fprintf(fd, "%d %d %d %d %d %d %d %d %d E\n" fprintf(fd, "%d %d %d %d %d %d %d %d %d E\n"
@ -406,10 +406,15 @@ int write_mobile_record(mob_vnum mvnum, struct char_data *mob, FILE *fd)
script_save_to_disk(fd, mob, MOB_TRIGGER); script_save_to_disk(fd, mob, MOB_TRIGGER);
#if CONFIG_GENOLC_MOBPROG #if CONFIG_GENOLC_MOBPROG
if (write_mobile_mobprog(mvnum, mob, fd) < 0) if (write_mobile_mobprog(mvnum, mob, fd) < 0)
log("SYSERR: GenOLC: Error writing MobProgs for mobile #%d.", mvnum); log("SYSERR: GenOLC: Error writing MobProgs for mobile #%d.", mvnum);
#endif #endif
} else {
mudlog(BRF,LVL_BUILDER,TRUE,
"SYSERR: Could not save mobile #%d due to size (%d > maximum of %d)",
mvnum, n, MAX_STRING_LENGTH);
}
return TRUE; return TRUE;
} }

View file

@ -210,7 +210,7 @@ int save_objects(zone_rnum zone_num)
} else } else
*buf = '\0'; *buf = '\0';
sprintf(buf2, int n = snprintf(buf2, MAX_STRING_LENGTH,
"#%d\n" "#%d\n"
"%s~\n" "%s~\n"
"%s~\n" "%s~\n"
@ -223,6 +223,13 @@ int save_objects(zone_rnum zone_num)
(obj->description && *obj->description) ? obj->description : "undefined", (obj->description && *obj->description) ? obj->description : "undefined",
buf); buf);
if(n >= MAX_STRING_LENGTH) {
mudlog(BRF,LVL_BUILDER,TRUE,
"SYSERR: Could not save object #%d due to size (%d > maximum of %d).",
GET_OBJ_VNUM(obj), n, MAX_STRING_LENGTH);
continue;
}
fprintf(fp, "%s", convert_from_tabs(buf2)); fprintf(fp, "%s", convert_from_tabs(buf2));
sprintascii(ebuf1, GET_OBJ_EXTRA(obj)[0]); sprintascii(ebuf1, GET_OBJ_EXTRA(obj)[0]);

View file

@ -366,13 +366,13 @@ ACMD(do_export_zone)
f = fix_filename(zone_name); f = fix_filename(zone_name);
/* Remove the old copy. */ /* Remove the old copy. */
sprintf(sysbuf, "rm %s%s.tar.gz", path, f); snprintf(sysbuf, MAX_STRING_LENGTH, "rm %s%s.tar.gz", path, f);
/* Tar the new copy. */ /* Tar the new copy. */
sprintf(sysbuf, "tar -cf %s%s.tar %sqq.info %sqq.wld %sqq.zon %sqq.mob %sqq.obj %sqq.trg %sqq.shp", path, f, path, path, path, path, path, path, path); snprintf(sysbuf, MAX_STRING_LENGTH, "tar -cf %s%s.tar %sqq.info %sqq.wld %sqq.zon %sqq.mob %sqq.obj %sqq.trg %sqq.shp", path, f, path, path, path, path, path, path, path);
/* Gzip it. */ /* Gzip it. */
sprintf(sysbuf, "gzip %s%s.tar", path, f); snprintf(sysbuf, MAX_STRING_LENGTH, "gzip %s%s.tar", path, f);
send_to_char(ch, "Files tar'ed to \"%s%s.tar.gz\"\r\n", path, f); send_to_char(ch, "Files tar'ed to \"%s%s.tar.gz\"\r\n", path, f);
} }

View file

@ -220,7 +220,7 @@ int save_quests(zone_rnum zone_num)
strip_cr(quest_quit); strip_cr(quest_quit);
/* Save the quest details to the file. */ /* Save the quest details to the file. */
sprintascii(quest_flags, QST_FLAGS(rnum)); sprintascii(quest_flags, QST_FLAGS(rnum));
sprintf(buf, int n = snprintf(buf, MAX_STRING_LENGTH,
"#%d\n" "#%d\n"
"%s%c\n" "%s%c\n"
"%s%c\n" "%s%c\n"
@ -250,9 +250,14 @@ int save_quests(zone_rnum zone_num)
QST_QUANTITY(rnum), QST_GOLD(rnum), QST_EXP(rnum), QST_OBJ(rnum) QST_QUANTITY(rnum), QST_GOLD(rnum), QST_EXP(rnum), QST_OBJ(rnum)
); );
if(n < MAX_STRING_LENGTH) {
fprintf(sf, "%s", convert_from_tabs(buf)); fprintf(sf, "%s", convert_from_tabs(buf));
num_quests++; num_quests++;
} else {
mudlog(BRF,LVL_BUILDER,TRUE,
"SYSERR: Could not save quest #%d due to size (%d > maximum of %d).",
QST_NUM(rnum), n, MAX_STRING_LENGTH);
}
} }
} }
/* Write the final line and close it. */ /* Write the final line and close it. */

View file

@ -302,7 +302,7 @@ int save_rooms(zone_rnum rzone)
strip_cr(buf); strip_cr(buf);
/* Save the numeric and string section of the file. */ /* Save the numeric and string section of the file. */
sprintf(buf2, "#%d\n" int n = snprintf(buf2, MAX_STRING_LENGTH, "#%d\n"
"%s%c\n" "%s%c\n"
"%s%c\n" "%s%c\n"
"%d %d %d %d %d %d\n", "%d %d %d %d %d %d\n",
@ -313,6 +313,13 @@ int save_rooms(zone_rnum rzone)
room->room_flags[3], room->sector_type room->room_flags[3], room->sector_type
); );
if(n >= MAX_STRING_LENGTH) {
mudlog(BRF,LVL_BUILDER,TRUE,
"SYSERR: Could not save room #%d due to size (%d > maximum of %d).",
room->number, n, MAX_STRING_LENGTH);
continue;
}
fprintf(sf, "%s", convert_from_tabs(buf2)); fprintf(sf, "%s", convert_from_tabs(buf2));
/* Now you write out the exits for the room. */ /* Now you write out the exits for the room. */

View file

@ -1196,7 +1196,7 @@ static int Crash_load_objs(struct char_data *ch) {
if (!(fl = fopen(filename, "r"))) { if (!(fl = fopen(filename, "r"))) {
if (errno != ENOENT) { /* if it fails, NOT because of no file */ if (errno != ENOENT) { /* if it fails, NOT because of no file */
sprintf(buf, "SYSERR: READING OBJECT FILE %s (5)", filename); snprintf(buf, MAX_STRING_LENGTH, "SYSERR: READING OBJECT FILE %s (5)", filename);
perror(buf); perror(buf);
send_to_char(ch, "\r\n********************* NOTICE *********************\r\n" send_to_char(ch, "\r\n********************* NOTICE *********************\r\n"
"There was a problem loading your objects from disk.\r\n" "There was a problem loading your objects from disk.\r\n"