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.
This commit is contained in:
		| @@ -147,30 +147,38 @@ boost::optional<Key128> DeriveSDSeed() { | |||||||
|                                    "rb+"); |                                    "rb+"); | ||||||
|     if (!save_43.IsOpen()) |     if (!save_43.IsOpen()) | ||||||
|         return boost::none; |         return boost::none; | ||||||
|  |  | ||||||
|     const FileUtil::IOFile sd_private( |     const FileUtil::IOFile sd_private( | ||||||
|         FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir) + "/Nintendo/Contents/private", "rb+"); |         FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir) + "/Nintendo/Contents/private", "rb+"); | ||||||
|     if (!sd_private.IsOpen()) |     if (!sd_private.IsOpen()) | ||||||
|         return boost::none; |         return boost::none; | ||||||
|  |  | ||||||
|     std::array<u8, 0x10> private_seed{}; |     std::array<u8, 0x10> 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; |         return boost::none; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     std::array<u8, 0x10> buffer{}; |     std::array<u8, 0x10> buffer{}; | ||||||
|     std::size_t offset = 0; |     std::size_t offset = 0; | ||||||
|     for (; offset + 0x10 < save_43.GetSize(); ++offset) { |     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()); |         save_43.ReadBytes(buffer.data(), buffer.size()); | ||||||
|         if (buffer == private_seed) |         if (buffer == private_seed) { | ||||||
|             break; |             break; | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (offset + 0x10 >= save_43.GetSize()) |     if (!save_43.Seek(offset + 0x10, SEEK_SET)) { | ||||||
|         return boost::none; |         return boost::none; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     Key128 seed{}; |     Key128 seed{}; | ||||||
|     save_43.Seek(offset + 0x10, SEEK_SET); |     if (save_43.ReadBytes(seed.data(), seed.size()) != seed.size()) { | ||||||
|     save_43.ReadBytes(seed.data(), seed.size()); |         return boost::none; | ||||||
|  |     } | ||||||
|     return seed; |     return seed; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -233,7 +241,9 @@ std::vector<TicketRaw> GetTicketblob(const FileUtil::IOFile& ticket_save) { | |||||||
|         return {}; |         return {}; | ||||||
|  |  | ||||||
|     std::vector<u8> buffer(ticket_save.GetSize()); |     std::vector<u8> buffer(ticket_save.GetSize()); | ||||||
|     ticket_save.ReadBytes(buffer.data(), buffer.size()); |     if (ticket_save.ReadBytes(buffer.data(), buffer.size()) != buffer.size()) { | ||||||
|  |         return {}; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     std::vector<TicketRaw> out; |     std::vector<TicketRaw> out; | ||||||
|     u32 magic{}; |     u32 magic{}; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user