Check TMD sizes using the actual constant

0x49e4 is the actual maximum TMD size (which is checked against in ES).
IsValidTMDSize is added to ESFormats to avoid duplicating the constant.
This commit is contained in:
Léo Lam 2017-05-26 11:23:11 +02:00
parent f4190ab1c4
commit b5a2f34a37
5 changed files with 18 additions and 7 deletions

View File

@ -57,6 +57,11 @@ bool Content::IsShared() const
return (type & 0x8000) != 0;
}
bool IsValidTMDSize(size_t size)
{
return size <= 0x49e4;
}
TMDReader::TMDReader(const std::vector<u8>& bytes) : m_bytes(bytes)
{
}

View File

@ -130,6 +130,8 @@ struct Ticket
static_assert(sizeof(Ticket) == 0x2A4, "Ticket has the wrong size");
#pragma pack(pop)
bool IsValidTMDSize(size_t size);
class TMDReader final
{
public:

View File

@ -91,6 +91,9 @@ IPCCommandResult ES::ImportTmd(Context& context, const IOCtlVRequest& request)
if (!request.HasNumberOfValidVectors(1, 0))
return GetDefaultReply(ES_EINVAL);
if (!IOS::ES::IsValidTMDSize(request.in_vectors[0].size))
return GetDefaultReply(ES_EINVAL);
std::vector<u8> tmd(request.in_vectors[0].size);
Memory::CopyFromEmu(tmd.data(), request.in_vectors[0].address, request.in_vectors[0].size);
return GetDefaultReply(ImportTmd(context, tmd));
@ -131,6 +134,9 @@ IPCCommandResult ES::ImportTitleInit(Context& context, const IOCtlVRequest& requ
if (!request.HasNumberOfValidVectors(4, 0))
return GetDefaultReply(ES_EINVAL);
if (!IOS::ES::IsValidTMDSize(request.in_vectors[0].size))
return GetDefaultReply(ES_EINVAL);
std::vector<u8> tmd(request.in_vectors[0].size);
Memory::CopyFromEmu(tmd.data(), request.in_vectors[0].address, request.in_vectors[0].size);
return GetDefaultReply(ImportTitleInit(context, tmd));

View File

@ -41,7 +41,7 @@ CVolumeWAD::CVolumeWAD(std::unique_ptr<IBlobReader> reader) : m_reader(std::move
m_opening_bnr_offset =
m_tmd_offset + Common::AlignUp(m_tmd_size, 0x40) + Common::AlignUp(m_data_size, 0x40);
if (m_tmd_size > 1024 * 1024 * 4)
if (!IOS::ES::IsValidTMDSize(m_tmd_size))
{
ERROR_LOG(DISCIO, "TMD is too large: %u bytes", m_tmd_size);
return;

View File

@ -81,13 +81,11 @@ CVolumeWiiCrypted::CVolumeWiiCrypted(std::unique_ptr<IBlobReader> reader)
if (!m_pReader->ReadSwapped(partition_offset + 0x2a8, &tmd_address))
continue;
tmd_address <<= 2;
if (tmd_size > 1024 * 1024 * 4)
if (!IOS::ES::IsValidTMDSize(tmd_size))
{
// The size is checked so that a malicious or corrupt ISO
// can't force Dolphin to allocate up to 4 GiB of memory.
// 4 MiB should be much bigger than the size of TMDs and much smaller
// than the amount of RAM in a computer that can run Dolphin.
PanicAlert("TMD > 4 MiB");
// This check is normally done by ES in ES_DiVerify, but that would happen too late
// (after allocating the buffer), so we do the check here.
PanicAlert("Invalid TMD size");
continue;
}
std::vector<u8> tmd_buffer(tmd_size);