From 84b88781a0c39f7379ed85f74dc03c4e868a171f Mon Sep 17 00:00:00 2001 From: shennetsind Date: Sat, 17 Jan 2015 15:59:12 -0200 Subject: 10 Distinct fixes Addressing out of bounds read-write. Special Thanks to 4144, Haruna! Signed-off-by: shennetsind --- src/char/pincode.c | 10 +++++----- src/common/console.c | 4 ++-- src/common/socket.c | 1 + src/login/login.c | 2 +- src/map/battle.c | 2 +- src/map/battleground.c | 2 +- src/map/clif.c | 2 +- src/map/map.c | 44 ++++++++++++++++++++++---------------------- src/map/pc.c | 4 ++-- src/map/skill.c | 3 ++- src/tool/mapcache.c | 2 +- 11 files changed, 39 insertions(+), 37 deletions(-) diff --git a/src/char/pincode.c b/src/char/pincode.c index a3843ff53..e0ee9557d 100644 --- a/src/char/pincode.c +++ b/src/char/pincode.c @@ -44,7 +44,7 @@ void pincode_handle ( int fd, struct char_session_data* sd ) { void pincode_check(int fd, struct char_session_data* sd) { char pin[5] = "\0\0\0\0"; - strncpy(pin, (char*)RFIFOP(fd, 6), 4+1); + safestrncpy(pin, (char*)RFIFOP(fd, 6), sizeof(pin)); pincode->decrypt(sd->pincode_seed, pin); if( pincode->compare( fd, sd, pin ) ){ struct online_char_data* character; @@ -70,12 +70,12 @@ int pincode_compare(int fd, struct char_session_data* sd, char* pin) { void pincode_change(int fd, struct char_session_data* sd) { char oldpin[5] = "\0\0\0\0", newpin[5] = "\0\0\0\0"; - strncpy(oldpin, (char*)RFIFOP(fd,6), sizeof(oldpin)); + safestrncpy(oldpin, (char*)RFIFOP(fd,6), sizeof(oldpin)); pincode->decrypt(sd->pincode_seed,oldpin); if( !pincode->compare( fd, sd, oldpin ) ) return; - strncpy(newpin, (char*)RFIFOP(fd,10), sizeof(newpin)); + safestrncpy(newpin, (char*)RFIFOP(fd,10), sizeof(newpin)); pincode->decrypt(sd->pincode_seed,newpin); pincode->update( sd->account_id, newpin ); strncpy(sd->pincode, newpin, sizeof(sd->pincode)); @@ -85,10 +85,10 @@ void pincode_change(int fd, struct char_session_data* sd) { void pincode_setnew(int fd, struct char_session_data* sd) { char newpin[5] = "\0\0\0\0"; - strncpy(newpin, (char*)RFIFOP(fd,6), sizeof(newpin)); + safestrncpy(newpin, (char*)RFIFOP(fd,6), sizeof(newpin)); pincode->decrypt(sd->pincode_seed,newpin); pincode->update( sd->account_id, newpin ); - strncpy(sd->pincode, newpin, sizeof(sd->pincode)); + safestrncpy(sd->pincode, newpin, sizeof(sd->pincode)); pincode->sendstate( fd, sd, PINCODE_ASK ); } diff --git a/src/common/console.c b/src/common/console.c index 0b1b9cf93..d9567a313 100644 --- a/src/common/console.c +++ b/src/common/console.c @@ -311,12 +311,12 @@ void console_parse_list_subs(struct CParseEntry *cmd, unsigned char depth) { for( i = 0; i < cmd->next_count; i++ ) { if( cmd->u.next[i]->next_count ) { memset(msg, '-', depth); - snprintf(msg + depth,CP_CMD_LENGTH * 2, " '"CL_WHITE"%s"CL_RESET"'",cmd->u.next[i]->cmd); + snprintf(msg + depth,( CP_CMD_LENGTH * 2 ) - depth, " '"CL_WHITE"%s"CL_RESET"'",cmd->u.next[i]->cmd); ShowInfo("%s subs\n",msg); console->input->parse_list_subs(cmd->u.next[i],depth + 1); } else { memset(msg, '-', depth); - snprintf(msg + depth,CP_CMD_LENGTH * 2, " %s",cmd->u.next[i]->cmd); + snprintf(msg + depth,(CP_CMD_LENGTH * 2) - depth, " %s",cmd->u.next[i]->cmd); ShowInfo("%s\n",msg); } } diff --git a/src/common/socket.c b/src/common/socket.c index c0864c9b3..2ab37109c 100644 --- a/src/common/socket.c +++ b/src/common/socket.c @@ -1319,6 +1319,7 @@ int socket_getips(uint32* ips, int max) if( sIoctl(fd, SIOCGIFCONF, &ic) == -1 ) { ShowError("socket_getips: SIOCGIFCONF failed!\n"); + sClose(fd); return 0; } else diff --git a/src/login/login.c b/src/login/login.c index e5f565644..ec5b2bb7c 100644 --- a/src/login/login.c +++ b/src/login/login.c @@ -722,7 +722,7 @@ void login_fromchar_parse_change_pincode(int fd) struct mmo_account acc; if( accounts->load_num(accounts, &acc, RFIFOL(fd,2) ) ) { - strncpy( acc.pincode, (char*)RFIFOP(fd,6), 5 ); + safestrncpy( acc.pincode, (char*)RFIFOP(fd,6), sizeof(acc.pincode) ); acc.pincode_change = ((unsigned int)time( NULL )); accounts->save(accounts, &acc); } diff --git a/src/map/battle.c b/src/map/battle.c index edb5fd69f..998fad0af 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -325,7 +325,7 @@ int64 battle_attr_fix(struct block_list *src, struct block_list *target, int64 d if (atk_elem < 0 || atk_elem >= ELE_MAX) atk_elem = rnd()%ELE_MAX; - if (def_type < 0 || def_type > ELE_MAX || + if (def_type < 0 || def_type >= ELE_MAX || def_lv < 1 || def_lv > 4) { ShowError("battle_attr_fix: unknown attr type: atk=%d def_type=%d def_lv=%d\n",atk_elem,def_type,def_lv); return damage; diff --git a/src/map/battleground.c b/src/map/battleground.c index 94a6f0626..eb9f605ad 100644 --- a/src/map/battleground.c +++ b/src/map/battleground.c @@ -825,7 +825,7 @@ enum BATTLEGROUNDS_QUEUE_ACK bg_canqueue(struct map_session_data *sd, struct bg_ return BGQA_NOT_PARTY_GUILD_LEADER; if( count < arena->min_team_players ) { - char response[100]; + char response[117]; if( count != p->party.count && p->party.count >= arena->min_team_players ) sprintf(response, "Can't apply: not enough members in your team/party that have not entered the queue in individual mode, minimum is %d",arena->min_team_players); else diff --git a/src/map/clif.c b/src/map/clif.c index 9db3cee03..4e55a515b 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -17670,7 +17670,7 @@ void clif_parse_CashShopBuy(int fd, struct map_session_data *sd) { short tab = RFIFOW(fd, 18 + ( i * 10 )); enum CASH_SHOP_BUY_RESULT result = CSBR_UNKNOWN; - if( tab < 0 || tab > CASHSHOP_TAB_MAX ) + if( tab < 0 || tab >= CASHSHOP_TAB_MAX ) continue; for( j = 0; j < clif->cs.item_count[tab]; j++ ) { diff --git a/src/map/map.c b/src/map/map.c index 2bebd3c55..8332d4371 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -3722,38 +3722,38 @@ int inter_config_read(char *cfgName) { continue; /* table names */ if(strcmpi(w1,"item_db_db")==0) - strcpy(map->item_db_db,w2); + safestrncpy(map->item_db_db, w2, sizeof(map->item_db_db)); else if(strcmpi(w1,"mob_db_db")==0) - strcpy(map->mob_db_db, w2); + safestrncpy(map->mob_db_db, w2, sizeof(map->mob_db_db)); else if (strcmpi(w1, "mob_db_re_db") == 0) - strcpy(map->mob_db_re_db, w2); + safestrncpy(map->mob_db_re_db, w2, sizeof(map->mob_db_re_db)); else if(strcmpi(w1,"item_db2_db")==0) - strcpy(map->item_db2_db,w2); + safestrncpy(map->item_db2_db, w2, sizeof(map->item_db2_db)); else if(strcmpi(w1,"item_db_re_db")==0) - strcpy(map->item_db_re_db,w2); + safestrncpy(map->item_db_re_db, w2, sizeof(map->item_db_re_db)); else if(strcmpi(w1,"mob_db2_db")==0) - strcpy(map->mob_db2_db, w2); + safestrncpy(map->mob_db2_db, w2, sizeof(map->mob_db2_db)); else if(strcmpi(w1, "mob_skill_db_db") == 0) - strcpy(map->mob_skill_db_db, w2); + safestrncpy(map->mob_skill_db_db, w2, sizeof(map->mob_skill_db_db)); else if(strcmpi(w1, "mob_skill_db_re_db") == 0) - strcpy(map->mob_skill_db_re_db, w2); + safestrncpy(map->mob_skill_db_re_db, w2, sizeof(map->mob_skill_db_re_db)); else if(strcmpi(w1,"mob_skill_db2_db")==0) - strcpy(map->mob_skill_db2_db,w2); + safestrncpy(map->mob_skill_db2_db, w2, sizeof(map->mob_skill_db2_db)); else if(strcmpi(w1,"interreg_db")==0) - strcpy(map->interreg_db,w2); + safestrncpy(map->interreg_db, w2, sizeof(map->interreg_db)); /* map sql stuff */ else if(strcmpi(w1,"map_server_ip")==0) - strcpy(map->server_ip, w2); + safestrncpy(map->server_ip, w2, sizeof(map->server_ip)); else if(strcmpi(w1,"map_server_port")==0) map->server_port=atoi(w2); else if(strcmpi(w1,"map_server_id")==0) - strcpy(map->server_id, w2); + safestrncpy(map->server_id, w2, sizeof(map->server_id)); else if(strcmpi(w1,"map_server_pw")==0) - strcpy(map->server_pw, w2); + safestrncpy(map->server_pw, w2, sizeof(map->server_pw)); else if(strcmpi(w1,"map_server_db")==0) - strcpy(map->server_db, w2); + safestrncpy(map->server_db, w2, sizeof(map->server_db)); else if(strcmpi(w1,"default_codepage")==0) - strcpy(map->default_codepage, w2); + safestrncpy(map->default_codepage, w2, sizeof(map->default_codepage)); else if(strcmpi(w1,"use_sql_item_db")==0) { map->db_use_sql_item_db = config_switch(w2); ShowStatus ("Using item database as SQL: '%s'\n", w2); @@ -3767,22 +3767,22 @@ int inter_config_read(char *cfgName) { ShowStatus ("Using monster skill database as SQL: '%s'\n", w2); } else if(strcmpi(w1,"autotrade_merchants_db")==0) - strcpy(map->autotrade_merchants_db, w2); + safestrncpy(map->autotrade_merchants_db, w2, sizeof(map->autotrade_merchants_db)); else if(strcmpi(w1,"autotrade_data_db")==0) - strcpy(map->autotrade_data_db, w2); + safestrncpy(map->autotrade_data_db, w2, sizeof(map->autotrade_data_db)); else if(strcmpi(w1,"npc_market_data_db")==0) - strcpy(map->npc_market_data_db, w2); + safestrncpy(map->npc_market_data_db, w2, sizeof(map->npc_market_data_db)); /* sql log db */ else if(strcmpi(w1,"log_db_ip")==0) - strcpy(logs->db_ip, w2); + safestrncpy(logs->db_ip, w2, sizeof(logs->db_ip)); else if(strcmpi(w1,"log_db_id")==0) - strcpy(logs->db_id, w2); + safestrncpy(logs->db_id, w2, sizeof(logs->db_id)); else if(strcmpi(w1,"log_db_pw")==0) - strcpy(logs->db_pw, w2); + safestrncpy(logs->db_pw, w2, sizeof(logs->db_pw)); else if(strcmpi(w1,"log_db_port")==0) logs->db_port = atoi(w2); else if(strcmpi(w1,"log_db_db")==0) - strcpy(logs->db_name, w2); + safestrncpy(logs->db_name, w2, sizeof(logs->db_name)); /* mapreg */ else if( mapreg->config_read(w1,w2) ) continue; diff --git a/src/map/pc.c b/src/map/pc.c index 09c406a7c..283bffc7a 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -3497,7 +3497,7 @@ int pc_bonus4(struct map_session_data *sd,int type,int type2,int type3,int type4 break; case SP_SET_DEF_RACE: //bonus4 bSetDefRace,n,x,r,y; - if( type2 > RC_MAX ) { + if( type2 >= RC_MAX ) { ShowWarning("pc_bonus4 (DEF_SET): %d is not supported.\n", type2); break; } @@ -3509,7 +3509,7 @@ int pc_bonus4(struct map_session_data *sd,int type,int type2,int type3,int type4 break; case SP_SET_MDEF_RACE: //bonus4 bSetMDefRace,n,x,r,y; - if( type2 > RC_MAX ) { + if( type2 >= RC_MAX ) { ShowWarning("pc_bonus4 (MDEF_SET): %d is not supported.\n", type2); break; } diff --git a/src/map/skill.c b/src/map/skill.c index 53be5541c..749f06799 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -11592,7 +11592,7 @@ int skill_unit_onplace(struct skill_unit *src, struct block_list *bl, int64 tick } else if( sc && battle->check_target(&sg->unit->bl,bl,sg->target_flag) > 0 ) { int sec = skill->get_time2(sg->skill_id,sg->skill_lv); if( status->change_start(ss, bl,type,10000,sg->skill_lv,1,sg->group_id,0,sec,SCFLAG_FIXEDRATE) ) { - const struct TimerData* td = sc->data[type]?timer->get(sc->data[type]->timer):NULL; + const struct TimerData* td = sce?timer->get(sce->timer):NULL; if( td ) sec = DIFF_TICK32(td->tick, tick); map->moveblock(bl, src->bl.x, src->bl.y, tick); @@ -18923,6 +18923,7 @@ bool skill_parse_row_changematerialdb(char* split[], int columns, int current) { if( current >= MAX_SKILL_PRODUCE_DB ) { ShowError("skill_changematerial_db: Maximum amount of entries reached (%d), increase MAX_SKILL_PRODUCE_DB\n",MAX_SKILL_PRODUCE_DB); + return false; } skill->changematerial_db[current].itemid = skill_id; diff --git a/src/tool/mapcache.c b/src/tool/mapcache.c index 2ead5edbb..59d70b62d 100644 --- a/src/tool/mapcache.c +++ b/src/tool/mapcache.c @@ -129,7 +129,7 @@ void cache_map(char *name, struct map_data *m) encode_zip(write_buf, &len, m->cells, m->xs*m->ys); // Fill the map header - strncpy(info.name, name, MAP_NAME_LENGTH); + safestrncpy(info.name, name, MAP_NAME_LENGTH); if (strlen(name) > MAP_NAME_LENGTH) // It does not hurt to warn that there are maps with name longer than allowed. ShowWarning("Map name '%s' (length %"PRIuS") is too long. Truncating to '%s' (lentgh %d).\n", name, strlen(name), info.name, MAP_NAME_LENGTH); -- cgit v1.2.3-60-g2f50