Merge pull request #5483 from leoetlino/max-tmd-size
Check TMD sizes using the actual constant
This commit is contained in:
commit
aa33fabded
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue