From f739fe09029484b5eecfd2f9c8928ae42941466c Mon Sep 17 00:00:00 2001 From: Martin Michelsen Date: Fri, 21 Feb 2020 15:34:51 -0800 Subject: [PATCH] fix some ep3 command leaks --- ReceiveCommands.cc | 8 +++++++- ReceiveSubcommands.cc | 22 +++++++++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/ReceiveCommands.cc b/ReceiveCommands.cc index 172dca1d..8387d068 100644 --- a/ReceiveCommands.cc +++ b/ReceiveCommands.cc @@ -1596,11 +1596,17 @@ void process_create_game_dc_gc(shared_ptr s, shared_ptr c, check_size(size, sizeof(Cmd)); const auto* cmd = reinterpret_cast(data); + // only allow EC from Ep3 clients + bool client_is_ep3 = c->flags & ClientFlag::Episode3Games; + if ((command == 0xEC) && !client_is_ep3) { + return; + } + uint8_t episode = cmd->episode; if (c->version == GameVersion::DC) { episode = 1; } - if (c->flags & ClientFlag::Episode3Games) { + if (client_is_ep3) { episode = 0xFF; } diff --git a/ReceiveSubcommands.cc b/ReceiveSubcommands.cc index 1216c2c2..1e285a14 100644 --- a/ReceiveSubcommands.cc +++ b/ReceiveSubcommands.cc @@ -58,6 +58,12 @@ void forward_subcommand(shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const PSOSubcommand* p, size_t count) { + // if the command is an Ep3-only command, make sure an Ep3 client sent it + bool command_is_ep3 = (command & 0xF0) == 0xC0; + if (command_is_ep3 && !(c->flags & ClientFlag::Episode3Games)) { + return; + } + if (command_is_private(command)) { if (flag >= l->max_clients) { return; @@ -66,9 +72,23 @@ void forward_subcommand(shared_ptr l, shared_ptr c, if (!target) { return; } + if (command_is_ep3 && !(target->flags & ClientFlag::Episode3Games)) { + return; + } send_command(target, command, flag, p, count * 4); + } else { - send_command_excluding_client(l, c, command, flag, p, count * 4); + if (command_is_ep3) { + for (auto& target : l->clients) { + if (!target || (target == c) || !(target->flags & ClientFlag::Episode3Games)) { + continue; + } + send_command(target, command, flag, p, count * 4); + } + + } else { + send_command_excluding_client(l, c, command, flag, p, count * 4); + } } }