From 32e8b47a33fb92ba6129a057ea8614346d2c2fe8 Mon Sep 17 00:00:00 2001 From: gibbed Date: Sun, 15 Nov 2020 13:22:04 -0600 Subject: [PATCH] [Kernel] Enforce *. in wildcard matching. Supersedes #1675. --- src/xenia/kernel/xboxkrnl/xboxkrnl_io.cc | 31 +++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_io.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_io.cc index a9aeb36bd..143e75496 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_io.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_io.cc @@ -1,4 +1,4 @@ -/** +/** ****************************************************************************** * Xenia : Xbox 360 Emulator Research Project * ****************************************************************************** @@ -41,10 +41,23 @@ struct CreateOptions { static bool IsValidPath(const std::string_view s, bool is_pattern) { // TODO(gibbed): validate path components individually + bool got_asterisk = false; for (const auto& c : s) { if (c <= 31 || c >= 127) { return false; } + if (got_asterisk) { + // * must be followed by a . (*.) + // + // Viva Piñata: Party Animals (4D530819) has a bug in its game code where + // it attempts to FindFirstFile() with filters of "Game:\\*_X3.rkv", + // "Game:\\m*_X3.rkv", and "Game:\\w*_X3.rkv" and will infinite loop if + // the path filter is allowed. + if (c != '.') { + return false; + } + got_asterisk = false; + } switch (c) { case '"': // case '*': @@ -59,18 +72,30 @@ static bool IsValidPath(const std::string_view s, bool is_pattern) { case '|': { return false; } - case '*': + case '*': { + // Pattern-specific (for NtQueryDirectoryFile) + if (!is_pattern) { + return false; + } + got_asterisk = true; + break; + } case '?': { // Pattern-specific (for NtQueryDirectoryFile) if (!is_pattern) { return false; } + break; } default: { break; } } } + if (got_asterisk) { + // * must be followed by a . (*.) + return false; + } return true; } @@ -425,7 +450,7 @@ dword_result_t NtQueryDirectoryFile( // Enforce that the path is ASCII. if (!IsValidPath(name, true)) { - return X_STATUS_OBJECT_NAME_INVALID; + return X_STATUS_INVALID_PARAMETER; } if (file) {