Prevent out-of-bounds array indexing when displaying/selecting netplay rooms in menus

This commit is contained in:
jdgleaver 2020-01-28 12:42:26 +00:00
parent f72e127f5f
commit f538e04fd2
4 changed files with 45 additions and 89 deletions

View File

@ -5065,44 +5065,43 @@ static int action_ok_netplay_connect_room(const char *path,
{
#ifdef HAVE_NETWORKING
char tmp_hostname[4115];
unsigned offset = idx - 4;
unsigned room_index = type - MENU_SETTINGS_NETPLAY_ROOMS_START;
tmp_hostname[0] = '\0';
if (room_index >= (unsigned)netplay_room_count)
return menu_cbs_exit();
if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL))
generic_action_ok_command(CMD_EVENT_NETPLAY_DEINIT);
netplay_driver_ctl(RARCH_NETPLAY_CTL_ENABLE_CLIENT, NULL);
if (netplay_room_list[offset].host_method == NETPLAY_HOST_METHOD_MITM)
{
if (netplay_room_list[room_index].host_method == NETPLAY_HOST_METHOD_MITM)
snprintf(tmp_hostname,
sizeof(tmp_hostname),
"%s|%d",
netplay_room_list[offset].mitm_address,
netplay_room_list[offset].mitm_port);
}
netplay_room_list[room_index].mitm_address,
netplay_room_list[room_index].mitm_port);
else
{
snprintf(tmp_hostname,
sizeof(tmp_hostname),
"%s|%d",
netplay_room_list[offset].address,
netplay_room_list[offset].port);
}
netplay_room_list[room_index].address,
netplay_room_list[room_index].port);
#if 0
RARCH_LOG("[lobby] connecting to: %s with game: %s/%08x\n",
tmp_hostname,
netplay_room_list[offset].gamename,
netplay_room_list[offset].gamecrc);
netplay_room_list[room_index].gamename,
netplay_room_list[room_index].gamecrc);
#endif
task_push_netplay_crc_scan(
netplay_room_list[offset].gamecrc,
netplay_room_list[offset].gamename,
netplay_room_list[room_index].gamecrc,
netplay_room_list[room_index].gamename,
tmp_hostname,
netplay_room_list[offset].corename,
netplay_room_list[offset].subsystem_name);
netplay_room_list[room_index].corename,
netplay_room_list[room_index].subsystem_name);
#else
return -1;
@ -5151,9 +5150,6 @@ default_action_ok_dl_push(action_ok_push_content_list, FILEBROWSER_SELECT_FILE,
default_action_ok_dl_push(action_ok_push_scan_file, FILEBROWSER_SCAN_FILE, ACTION_OK_DL_CONTENT_LIST, settings->paths.directory_menu_content)
#ifdef HAVE_NETWORKING
/* TODO/FIXME - globals - remove */
static struct netplay_host_list *lan_hosts = NULL;
extern int lan_room_count;
#ifndef INET6_ADDRSTRLEN
#define INET6_ADDRSTRLEN 46
@ -5198,8 +5194,9 @@ static void netplay_refresh_rooms_cb(retro_task_t *task,
unsigned i = 0;
unsigned j = 0;
file_list_t *list = menu_entries_get_selection_buf_ptr(0);
lan_room_count = 0;
struct netplay_host_list *lan_hosts = NULL;
int lan_room_count = 0;
bool refresh = false;
#ifndef RARCH_CONSOLE
netplay_discovery_driver_ctl(RARCH_NETPLAY_DISCOVERY_CTL_LAN_GET_RESPONSES, &lan_hosts);
@ -5267,7 +5264,8 @@ static void netplay_refresh_rooms_cb(retro_task_t *task,
netplay_room_count += lan_room_count;
}
menu_displaylist_netplay_refresh_rooms(list);
menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh);
menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL);
}
}
@ -5298,6 +5296,20 @@ static void netplay_lan_scan_callback(retro_task_t *task,
const char *label = NULL;
const char *path = NULL;
/* TODO/FIXME: I have no idea what this is supposed to be
* doing...
* As it stands, this function will never get past the
* following sanity check (i.e. netplay_lan_scan_callback()
* will never be called when we are viewing the 'lan scan
* settings' list, since this list doesn't even exist...).
* Moreover, any menu entries that get added here
* (menu_entries_append_enum()) will be erased by the
* subsequent netplay_refresh_rooms_cb() callback - and
* menu entries should never be added outside of
* menu_displaylist.c anyway.
* This is some legacy garbage, and someone who understands
* netplay needs to rip it all out. */
menu_entries_get_last_stack(&path, &label, &menu_type, &enum_idx, NULL);
/* Don't push the results if we left the LAN scan menu */

View File

@ -135,44 +135,6 @@ static int action_select_input_desc_kbd(const char *path,
return action_right_input_desc_kbd(type, label, true);
}
#ifdef HAVE_NETWORKING
static int action_select_netplay_connect_room(const char *path,
const char *label, unsigned type,
size_t idx, size_t entry_idx)
{
char tmp_hostname[4115];
unsigned offset = idx - 4;
tmp_hostname[0] = '\0';
if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL))
command_event(CMD_EVENT_NETPLAY_DEINIT, NULL);
netplay_driver_ctl(RARCH_NETPLAY_CTL_ENABLE_CLIENT, NULL);
if (netplay_room_list[offset].host_method == NETPLAY_HOST_METHOD_MITM)
snprintf(tmp_hostname,
sizeof(tmp_hostname),
"%s|%d",
netplay_room_list[offset].mitm_address,
netplay_room_list[offset].mitm_port);
else
snprintf(tmp_hostname,
sizeof(tmp_hostname),
"%s|%d",
netplay_room_list[offset].address,
netplay_room_list[offset].port);
task_push_netplay_crc_scan(
netplay_room_list[offset].gamecrc,
netplay_room_list[offset].gamename,
tmp_hostname,
netplay_room_list[offset].corename,
netplay_room_list[offset].subsystem_name);
return 0;
}
#endif
static int menu_cbs_init_bind_select_compare_type(
menu_file_list_cbs_t *cbs, unsigned type)
{
@ -216,14 +178,6 @@ int menu_cbs_init_bind_select(menu_file_list_cbs_t *cbs,
BIND_ACTION_SELECT(cbs, action_select_default);
#ifdef HAVE_NETWORKING
if (cbs->enum_idx == MENU_ENUM_LABEL_CONNECT_NETPLAY_ROOM)
{
BIND_ACTION_SELECT(cbs, action_select_netplay_connect_room);
return 0;
}
#endif
if ((type >= MENU_SETTINGS_CORE_OPTION_START) &&
(type < MENU_SETTINGS_CHEEVOS_START))
{

View File

@ -970,20 +970,18 @@ static int action_bind_sublabel_netplay_room(
const char *frontend = NULL;
const char *na = NULL;
const char *subsystem = NULL;
unsigned room_index = type - MENU_SETTINGS_NETPLAY_ROOMS_START;
/* This offset may cause issues if any entries are added to this menu */
unsigned offset = i - 4;
if (room_index >= (unsigned)netplay_room_count)
return menu_cbs_exit();
if (i < 1 || offset > (unsigned)netplay_room_count)
return -1;
ra_version = netplay_room_list[offset].retroarch_version;
corename = netplay_room_list[offset].corename;
gamename = netplay_room_list[offset].gamename;
core_ver = netplay_room_list[offset].coreversion;
gamecrc = netplay_room_list[offset].gamecrc;
frontend = netplay_room_list[offset].frontend;
subsystem = netplay_room_list[offset].subsystem_name;
ra_version = netplay_room_list[room_index].retroarch_version;
corename = netplay_room_list[room_index].corename;
gamename = netplay_room_list[room_index].gamename;
core_ver = netplay_room_list[room_index].coreversion;
gamecrc = netplay_room_list[room_index].gamecrc;
frontend = netplay_room_list[room_index].frontend;
subsystem = netplay_room_list[room_index].subsystem_name;
na = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE);
if (string_is_empty(subsystem) || string_is_equal(subsystem, "N/A"))

View File

@ -107,11 +107,6 @@ static char new_lbl_entry[4096] = {0};
static char new_entry[4096] = {0};
static enum msg_hash_enums new_type = MSG_UNKNOWN;
#ifdef HAVE_NETWORKING
/* TODO/FIXME - globals - remove */
int lan_room_count = 0;
#endif
#define menu_displaylist_parse_settings_enum(list, label, parse_type, add_empty_entry) menu_displaylist_parse_settings_internal_enum(list, parse_type, add_empty_entry, menu_setting_find_enum(label), label, true)
#define menu_displaylist_parse_settings(list, label, parse_type, add_empty_entry, entry_type) menu_displaylist_parse_settings_internal_enum(list, parse_type, add_empty_entry, menu_setting_find(label), entry_type, false)
@ -7318,7 +7313,6 @@ unsigned menu_displaylist_netplay_refresh_rooms(file_list_t *list)
{
char s[8300];
int i = 0;
int room_type = 0;
unsigned count = 0;
s[0] = '\0';
@ -7406,13 +7400,11 @@ unsigned menu_displaylist_netplay_refresh_rooms(file_list_t *list)
"Internet (Relay)" : "Internet"),
netplay_room_list[i].nickname, country);
room_type = netplay_room_list[i].lan ? MENU_ROOM_LAN : (netplay_room_list[i].host_method == NETPLAY_HOST_METHOD_MITM ? MENU_ROOM_RELAY : MENU_ROOM);
if (menu_entries_append_enum(list,
s,
msg_hash_to_str(MENU_ENUM_LABEL_CONNECT_NETPLAY_ROOM),
MENU_ENUM_LABEL_CONNECT_NETPLAY_ROOM,
room_type, 0, 0))
(unsigned)(MENU_SETTINGS_NETPLAY_ROOMS_START + i), 0, 0))
count++;
}