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(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"
@ -380,36 +380,41 @@ int write_mobile_record(mob_vnum mvnum, struct char_data *mob, FILE *fd)
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"
"%d %d %d %dd%d+%d %dd%d+%d\n",
MOB_FLAGS(mob)[0], MOB_FLAGS(mob)[1],
MOB_FLAGS(mob)[2], MOB_FLAGS(mob)[3],
AFF_FLAGS(mob)[0], AFF_FLAGS(mob)[1],
AFF_FLAGS(mob)[2], AFF_FLAGS(mob)[3],
GET_ALIGNMENT(mob),
GET_LEVEL(mob), 20 - GET_HITROLL(mob), GET_AC(mob) / 10, GET_HIT(mob),
GET_MANA(mob), GET_MOVE(mob), GET_NDD(mob), GET_SDD(mob),
GET_DAMROLL(mob));
fprintf(fd, "%d %d %d %d %d %d %d %d %d E\n"
"%d %d %d %dd%d+%d %dd%d+%d\n",
MOB_FLAGS(mob)[0], MOB_FLAGS(mob)[1],
MOB_FLAGS(mob)[2], MOB_FLAGS(mob)[3],
AFF_FLAGS(mob)[0], AFF_FLAGS(mob)[1],
AFF_FLAGS(mob)[2], AFF_FLAGS(mob)[3],
GET_ALIGNMENT(mob),
GET_LEVEL(mob), 20 - GET_HITROLL(mob), GET_AC(mob) / 10, GET_HIT(mob),
GET_MANA(mob), GET_MOVE(mob), GET_NDD(mob), GET_SDD(mob),
GET_DAMROLL(mob));
fprintf(fd, "%d %d\n"
"%d %d %d\n",
GET_GOLD(mob), GET_EXP(mob),
GET_POS(mob), GET_DEFAULT_POS(mob), GET_SEX(mob)
);
fprintf(fd, "%d %d\n"
"%d %d %d\n",
GET_GOLD(mob), GET_EXP(mob),
GET_POS(mob), GET_DEFAULT_POS(mob), GET_SEX(mob)
);
if (write_mobile_espec(mvnum, mob, fd) < 0)
log("SYSERR: GenOLC: Error writing E-specs for mobile #%d.", mvnum);
if (write_mobile_espec(mvnum, mob, fd) < 0)
log("SYSERR: GenOLC: Error writing E-specs for mobile #%d.", mvnum);
script_save_to_disk(fd, mob, MOB_TRIGGER);
script_save_to_disk(fd, mob, MOB_TRIGGER);
#if CONFIG_GENOLC_MOBPROG
if (write_mobile_mobprog(mvnum, mob, fd) < 0)
log("SYSERR: GenOLC: Error writing MobProgs for mobile #%d.", mvnum);
#endif
#if CONFIG_GENOLC_MOBPROG
if (write_mobile_mobprog(mvnum, mob, fd) < 0)
log("SYSERR: GenOLC: Error writing MobProgs for mobile #%d.", mvnum);
#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;
}

View file

@ -205,12 +205,12 @@ int save_objects(zone_rnum zone_num)
for (counter = genolc_zone_bottom(zone_num); counter <= zone_table[zone_num].top; counter++) {
if ((realcounter = real_object(counter)) != NOTHING) {
if ((obj = &obj_proto[realcounter])->action_description) {
strncpy(buf, obj->action_description, sizeof(buf) - 1);
strip_cr(buf);
strncpy(buf, obj->action_description, sizeof(buf) - 1);
strip_cr(buf);
} else
*buf = '\0';
*buf = '\0';
sprintf(buf2,
int n = snprintf(buf2, MAX_STRING_LENGTH,
"#%d\n"
"%s~\n"
"%s~\n"
@ -223,6 +223,13 @@ int save_objects(zone_rnum zone_num)
(obj->description && *obj->description) ? obj->description : "undefined",
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));
sprintascii(ebuf1, GET_OBJ_EXTRA(obj)[0]);

View file

@ -366,13 +366,13 @@ ACMD(do_export_zone)
f = fix_filename(zone_name);
/* 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. */
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. */
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);
}

View file

@ -220,7 +220,7 @@ int save_quests(zone_rnum zone_num)
strip_cr(quest_quit);
/* Save the quest details to the file. */
sprintascii(quest_flags, QST_FLAGS(rnum));
sprintf(buf,
int n = snprintf(buf, MAX_STRING_LENGTH,
"#%d\n"
"%s%c\n"
"%s%c\n"
@ -246,13 +246,18 @@ int save_quests(zone_rnum zone_num)
QST_PREREQ(rnum) == NOTHING ? -1 : QST_PREREQ(rnum),
QST_POINTS(rnum), QST_PENALTY(rnum), QST_MINLEVEL(rnum),
QST_MAXLEVEL(rnum), QST_TIME(rnum),
QST_RETURNMOB(rnum) == NOBODY ? -1 : QST_RETURNMOB(rnum),
QST_QUANTITY(rnum), QST_GOLD(rnum), QST_EXP(rnum), QST_OBJ(rnum)
QST_RETURNMOB(rnum) == NOBODY ? -1 : QST_RETURNMOB(rnum),
QST_QUANTITY(rnum), QST_GOLD(rnum), QST_EXP(rnum), QST_OBJ(rnum)
);
fprintf(sf, "%s", convert_from_tabs(buf));
num_quests++;
if(n < MAX_STRING_LENGTH) {
fprintf(sf, "%s", convert_from_tabs(buf));
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. */

View file

@ -302,7 +302,7 @@ int save_rooms(zone_rnum rzone)
strip_cr(buf);
/* 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"
"%d %d %d %d %d %d\n",
@ -313,6 +313,13 @@ int save_rooms(zone_rnum rzone)
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));
/* 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 (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);
send_to_char(ch, "\r\n********************* NOTICE *********************\r\n"
"There was a problem loading your objects from disk.\r\n"