Core/Boot: Check bounds in Load_BS2().

This commit is contained in:
Admiral H. Curtiss 2023-12-05 22:34:35 +01:00
parent a65246ec3f
commit fff538e563
No known key found for this signature in database
GPG key ID: F051B4C4044F33FB

View file

@ -5,6 +5,7 @@
#include <algorithm>
#include <array>
#include <cmath>
#include <cstring>
#include <memory>
#include <numeric>
@ -399,12 +400,20 @@ bool CBoot::Load_BS2(Core::System& system, const std::string& boot_rom_filename)
constexpr u32 PAL_v1_0 = 0x4F319F43;
constexpr u32 PAL_v1_2 = 0xAD1B7F16;
// Load the whole ROM dump
std::string data;
if (!File::ReadFileToString(boot_rom_filename, data))
return false;
// Load the IPL ROM dump, limited to 2MiB which is the size of the official IPLs.
constexpr size_t max_ipl_size = 2 * 1024 * 1024;
std::vector<u8> data;
{
File::IOFile file(boot_rom_filename, "rb");
if (!file)
return false;
const u32 ipl_hash = Common::ComputeCRC32(data);
data.resize(static_cast<size_t>(std::min<u64>(file.GetSize(), max_ipl_size)));
if (!file.ReadArray(data.data(), data.size()))
return false;
}
const u32 ipl_hash = Common::ComputeCRC32(data.data(), data.size());
bool known_ipl = false;
bool pal_ipl = false;
switch (ipl_hash)
@ -433,15 +442,26 @@ bool CBoot::Load_BS2(Core::System& system, const std::string& boot_rom_filename)
}
// Run the descrambler over the encrypted section containing BS1/BS2
ExpansionInterface::CEXIIPL::Descrambler((u8*)data.data() + 0x100, 0x1AFE00);
if (data.size() > 0x100)
{
ExpansionInterface::CEXIIPL::Descrambler(
data.data() + 0x100, static_cast<u32>(std::min<size_t>(data.size() - 0x100, 0x1AFE00)));
}
// TODO: Execution is supposed to start at 0xFFF00000, not 0x81200000;
// copying the initial boot code to 0x81200000 is a hack.
// For now, HLE the first few instructions and start at 0x81200150
// to work around this.
auto& memory = system.GetMemory();
memory.CopyToEmu(0x01200000, data.data() + 0x100, 0x700);
memory.CopyToEmu(0x01300000, data.data() + 0x820, 0x1AFE00);
if (data.size() > 0x100)
{
memory.CopyToEmu(0x01200000, data.data() + 0x100, std::min<size_t>(data.size() - 0x100, 0x700));
}
if (data.size() > 0x820)
{
memory.CopyToEmu(0x01300000, data.data() + 0x820,
std::min<size_t>(data.size() - 0x820, 0x1AFE00));
}
auto& ppc_state = system.GetPPCState();
ppc_state.gpr[3] = 0xfff0001f;