From ef5639bfbbeb7d83bd66e3faf3e88e4aa1e05a6e Mon Sep 17 00:00:00 2001 From: Lioncash Date: Sat, 13 Oct 2018 08:12:00 -0400 Subject: [PATCH] key_manager: Don't assume file seeks and reads will always succeed Given the filesystem should always be assumed to be volatile, we should check and bail out if a seek operation isn't successful. This'll prevent potentially writing/returning garbage data from the function in rare cases. This also allows removing a check to see if an offset is within the bounds of a file before perfoming a seek operation. If a seek is attempted beyond the end of a file, it will fail, so this essentially combines two checks into one in one place. --- src/core/crypto/key_manager.cpp | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/core/crypto/key_manager.cpp b/src/core/crypto/key_manager.cpp index 4ade67d236..14d53bef9a 100644 --- a/src/core/crypto/key_manager.cpp +++ b/src/core/crypto/key_manager.cpp @@ -147,30 +147,38 @@ boost::optional DeriveSDSeed() { "rb+"); if (!save_43.IsOpen()) return boost::none; + const FileUtil::IOFile sd_private( FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir) + "/Nintendo/Contents/private", "rb+"); if (!sd_private.IsOpen()) return boost::none; std::array private_seed{}; - if (sd_private.ReadBytes(private_seed.data(), private_seed.size()) != 0x10) + if (sd_private.ReadBytes(private_seed.data(), private_seed.size()) != private_seed.size()) { return boost::none; + } std::array buffer{}; std::size_t offset = 0; for (; offset + 0x10 < save_43.GetSize(); ++offset) { - save_43.Seek(offset, SEEK_SET); + if (!save_43.Seek(offset, SEEK_SET)) { + return boost::none; + } + save_43.ReadBytes(buffer.data(), buffer.size()); - if (buffer == private_seed) + if (buffer == private_seed) { break; + } } - if (offset + 0x10 >= save_43.GetSize()) + if (!save_43.Seek(offset + 0x10, SEEK_SET)) { return boost::none; + } Key128 seed{}; - save_43.Seek(offset + 0x10, SEEK_SET); - save_43.ReadBytes(seed.data(), seed.size()); + if (save_43.ReadBytes(seed.data(), seed.size()) != seed.size()) { + return boost::none; + } return seed; } @@ -233,7 +241,9 @@ std::vector GetTicketblob(const FileUtil::IOFile& ticket_save) { return {}; std::vector buffer(ticket_save.GetSize()); - ticket_save.ReadBytes(buffer.data(), buffer.size()); + if (ticket_save.ReadBytes(buffer.data(), buffer.size()) != buffer.size()) { + return {}; + } std::vector out; u32 magic{};