From 0c6765e6a607c9722b49a58d58ddeac9612841b2 Mon Sep 17 00:00:00 2001 From: boykopovar Date: Sat, 26 Sep 2026 15:19:40 +0300 Subject: [PATCH] fix(relinker): ignore non-loadable SCE segments outside file bounds --- core/relinker/relinker/src/guest/GuestImageReader.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/core/relinker/relinker/src/guest/GuestImageReader.cpp b/core/relinker/relinker/src/guest/GuestImageReader.cpp index 816196a26..5b3a8abc8 100644 --- a/core/relinker/relinker/src/guest/GuestImageReader.cpp +++ b/core/relinker/relinker/src/guest/GuestImageReader.cpp @@ -6,13 +6,18 @@ #include #include #include +#include namespace Relinker { GuestImage GuestImageReader::Read(const std::filesystem::path& path, std::vector bytes) const { const auto fail = [&](const std::string& message) { throw Domain::RelinkerException(path.string() + ": " + message); }; const auto range = [&](std::uint64_t offset, std::uint64_t size) { - if (offset > bytes.size() || size > bytes.size() - offset) fail("ELF range exceeds file"); + if (offset > bytes.size() || size > bytes.size() - offset) { + std::ostringstream message; + message << "ELF range exceeds file: offset=0x" << std::hex << offset << ", size=0x" << size << ", fileSize=0x" << bytes.size(); + fail(message.str()); + } }; range(0, 64); if (Io::ReadU32(bytes, 0) != 0x464c457f || bytes[4] != 2 || bytes[5] != 1 || bytes[6] != 1 || Io::ReadU16(bytes, 18) != 62 || Io::ReadU32(bytes, 20) != 1) fail("Expected little-endian ELF64 x86-64"); @@ -28,7 +33,10 @@ GuestImage GuestImageReader::Read(const std::filesystem::path& path, std::vector const Domain::ProgramHeader* dynlib = nullptr; const Domain::ProgramHeader* tls = nullptr; std::map loads; + constexpr std::uint32_t sceComment = 0x6fffff00; + constexpr std::uint32_t sceLibVersion = 0x6fffff01; for (const auto& header : image.Headers) { + if (header.Type == sceComment || header.Type == sceLibVersion) continue; range(header.Offset, header.FileSize); if (header.Type == 1) { if (header.FileSize > header.MemorySize || header.MemorySize > std::numeric_limits::max() - header.MappedAddress || (header.Flags & ~7u) != 0) fail("Invalid load segment");