From 3140086c60118834fb673bc0b07bcda007520f62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Sat, 21 Dec 2019 13:31:34 +0100 Subject: [PATCH] file_sys: Handle patch applying failures This changes ApplyCodePatch to return a ResultStatus, which makes it possible to determine whether patch applying has failed. Previously, only a boolean was returned, and false was returned when no patch was found OR when a patch was found but applying it failed. This also changes AppLoader_NCCH to return an error if patching fails because the executable is likely to be left in an inconsistent state and we should not proceed booting in that case. --- src/core/file_sys/ncch_container.cpp | 12 +++++++----- src/core/file_sys/ncch_container.h | 4 ++-- src/core/loader/ncch.cpp | 6 ++++-- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/core/file_sys/ncch_container.cpp b/src/core/file_sys/ncch_container.cpp index 0412fa288..ec6bb3827 100644 --- a/src/core/file_sys/ncch_container.cpp +++ b/src/core/file_sys/ncch_container.cpp @@ -507,20 +507,22 @@ Loader::ResultStatus NCCHContainer::LoadSectionExeFS(const char* name, std::vect return Loader::ResultStatus::ErrorNotUsed; } -bool NCCHContainer::ApplyCodePatch(std::vector& code) const { +Loader::ResultStatus NCCHContainer::ApplyCodePatch(std::vector& code) const { const std::string override_ips = filepath + ".exefsdir/code.ips"; FileUtil::IOFile ips_file{override_ips, "rb"}; if (!ips_file) - return false; + return Loader::ResultStatus::ErrorNotUsed; std::vector ips(ips_file.GetSize()); if (ips_file.ReadBytes(ips.data(), ips.size()) != ips.size()) - return false; + return Loader::ResultStatus::Error; LOG_INFO(Service_FS, "File {} patching code.bin", override_ips); - Patch::ApplyIpsPatch(ips, code); - return true; + if (!Patch::ApplyIpsPatch(ips, code)) + return Loader::ResultStatus::Error; + + return Loader::ResultStatus::Success; } Loader::ResultStatus NCCHContainer::LoadOverrideExeFSSection(const char* name, diff --git a/src/core/file_sys/ncch_container.h b/src/core/file_sys/ncch_container.h index 8752ffe39..f06ee8ef6 100644 --- a/src/core/file_sys/ncch_container.h +++ b/src/core/file_sys/ncch_container.h @@ -274,9 +274,9 @@ public: /** * Apply a patch for .code (if it exists). * This should only be called after allocating .bss. - * @return bool true if a patch was applied, false otherwise + * @return ResultStatus success if a patch was applied, ErrorNotUsed if no patch was found */ - bool ApplyCodePatch(std::vector& code) const; + Loader::ResultStatus ApplyCodePatch(std::vector& code) const; /** * Checks whether the NCCH container contains an ExeFS diff --git a/src/core/loader/ncch.cpp b/src/core/loader/ncch.cpp index 07edad796..2e688e011 100644 --- a/src/core/loader/ncch.cpp +++ b/src/core/loader/ncch.cpp @@ -100,8 +100,10 @@ ResultStatus AppLoader_NCCH::LoadExec(std::shared_ptr& process) overlay_ncch->exheader_header.codeset_info.data.num_max_pages * Memory::PAGE_SIZE + bss_page_size; - // Apply any IPS patch now that the entire codeset (including .bss) has been allocated - overlay_ncch->ApplyCodePatch(code); + // Apply patches now that the entire codeset (including .bss) has been allocated + const ResultStatus patch_result = overlay_ncch->ApplyCodePatch(code); + if (patch_result != ResultStatus::Success && patch_result != ResultStatus::ErrorNotUsed) + return patch_result; codeset->entrypoint = codeset->CodeSegment().addr; codeset->memory = std::move(code);