From 5c329415a530e3258eb523620a6fc5e0ed66fd52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 31 Aug 2026 12:54:06 +0200 Subject: [PATCH] PSPLoaders: bound the UMD_DATA.BIN read InitMemorySizeForGame read all of disc0:/UMD_DATA.BIN into a vector and then copied it into a string, with no size limit, from an image we don't control - and the DISC_ID that gets us here is equally forgeable, it just has to match one of the 16 g_HDRemasters entries. A real UMD_DATA.BIN is a few dozen bytes; anything larger is a mistake or an attack, so check the size before reading. --- Core/PSPLoaders.cpp | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/Core/PSPLoaders.cpp b/Core/PSPLoaders.cpp index f6d0a5090a..72fe344601 100644 --- a/Core/PSPLoaders.cpp +++ b/Core/PSPLoaders.cpp @@ -160,11 +160,21 @@ void InitMemorySizeForGame() { } if (umdData.empty()) { - std::vector umdDataBin; - // .data() rather than &umdDataBin[0] - the file can legitimately be empty, and - // indexing an empty vector is undefined. - if (pspFileSystem.ReadEntireFile("disc0:/UMD_DATA.BIN", umdDataBin) >= 0) { - umdData = std::string((const char *)umdDataBin.data(), umdDataBin.size()); + // A real UMD_DATA.BIN is a few dozen bytes - it's just the disc ID line matched below. + // Check the size first: this comes off the disc image, which is not something we trust, + // and ReadEntireFile has no limit of its own - it would resize a vector to whatever the + // image claims, and the string copy after it doubles that. + const s64 MAX_UMD_DATA_SIZE = 4096; + const PSPFileInfo info = pspFileSystem.GetFileInfo("disc0:/UMD_DATA.BIN"); + if (info.exists && info.size > MAX_UMD_DATA_SIZE) { + WARN_LOG(Log::Loader, "Ignoring implausibly large UMD_DATA.BIN (%lld bytes)", (long long)info.size); + } else if (info.exists) { + std::vector umdDataBin; + // .data() rather than &umdDataBin[0] - the file can legitimately be empty, and + // indexing an empty vector is undefined. + if (pspFileSystem.ReadEntireFile("disc0:/UMD_DATA.BIN", umdDataBin) >= 0) { + umdData = std::string((const char *)umdDataBin.data(), umdDataBin.size()); + } } }