diff --git a/rpcs3/Crypto/unself.cpp b/rpcs3/Crypto/unself.cpp index fe4f8e3f6fda..eb6a2c72c86d 100644 --- a/rpcs3/Crypto/unself.cpp +++ b/rpcs3/Crypto/unself.cpp @@ -627,7 +627,20 @@ bool SCEDecrypter::LoadMetadata(const u8 erk[32], const u8 riv[16]) { aes_context aes; std::vector metadata_info(sizeof(meta_info)); - std::vector metadata_headers(sce_hdr.se_hsize - (sizeof(sce_hdr) + sce_hdr.se_meta + sizeof(meta_info))); + constexpr usz sizeof_meta_and_header = sizeof(meta_info) + sizeof(sce_hdr); + const usz metadata_offset = static_cast(sce_hdr.se_meta); + + if (metadata_offset > usz{umax} - sizeof_meta_and_header || + sce_hdr.se_hsize < sizeof_meta_and_header + metadata_offset || + sce_hdr.se_hsize - (sizeof_meta_and_header + metadata_offset) < sizeof(meta_hdr) || + sce_hdr.se_hsize > sce_f.size()) + { + self_log.error("Invalid SCE metadata header size!"); + return false; + } + + const usz metadata_headers_offset = sizeof_meta_and_header + metadata_offset; + std::vector metadata_headers(sce_hdr.se_hsize - metadata_headers_offset); // Locate and read the encrypted metadata info. sce_f.seek(sce_hdr.se_meta + sizeof(sce_hdr)); @@ -1123,7 +1136,20 @@ bool SELFDecrypter::LoadMetadata(const u8* klic_key) { aes_context aes; std::vector metadata_info(sizeof(meta_info)); - std::vector metadata_headers(sce_hdr.se_hsize - (sizeof(sce_hdr) + sce_hdr.se_meta + sizeof(meta_info))); + constexpr usz sizeof_meta_and_header = sizeof(meta_info) + sizeof(sce_hdr); + const usz metadata_offset = static_cast(sce_hdr.se_meta); + + if (metadata_offset > usz{umax} - sizeof_meta_and_header || + sce_hdr.se_hsize < sizeof_meta_and_header + metadata_offset || + sce_hdr.se_hsize - (sizeof_meta_and_header + metadata_offset) < sizeof(meta_hdr) || + sce_hdr.se_hsize > self_f.size()) + { + self_log.error("Invalid SELF metadata header size!"); + return false; + } + + const usz metadata_headers_offset = sizeof_meta_and_header + metadata_offset; + std::vector metadata_headers(sce_hdr.se_hsize - metadata_headers_offset); // Locate and read the encrypted metadata info. self_f.seek(sce_hdr.se_meta + sizeof(sce_hdr));