From ffa4075be808aeb03906775fb331a1413fa8fc2b Mon Sep 17 00:00:00 2001 From: rooklz <175737347+rooklz@users.noreply.github.com> Date: Fri, 30 Oct 2026 22:13:07 +0000 Subject: [PATCH] test(relinker): pin EH udata4 funcrel overflow via LSDA path --- .../tests/UnwindRecordBoundsTests.cpp | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/core/relinker/relinker/tests/UnwindRecordBoundsTests.cpp b/core/relinker/relinker/tests/UnwindRecordBoundsTests.cpp index 372345c673..6093b53d2f 100644 --- a/core/relinker/relinker/tests/UnwindRecordBoundsTests.cpp +++ b/core/relinker/relinker/tests/UnwindRecordBoundsTests.cpp @@ -242,6 +242,34 @@ int main() { lebRejected = std::string(error.what()).find("overflowing LEB128 value") != std::string::npos; } Require(lebRejected); - std::cout << "26 unwind record cases passed\n"; + std::vector lsdaUdata4Bytes(0x400, 0); + Io::WriteU32(lsdaUdata4Bytes, 0x200, 25); + lsdaUdata4Bytes[0x208] = 1; + std::copy(std::begin(ciePrefix), std::end(ciePrefix), lsdaUdata4Bytes.begin() + 0x209); + lsdaUdata4Bytes[0x212] = 0; + Io::WriteU64(lsdaUdata4Bytes, 0x213, 0x1000); + lsdaUdata4Bytes[0x21B] = 0x43; + lsdaUdata4Bytes[0x21C] = 0; + Io::WriteU32(lsdaUdata4Bytes, 0x220, 29); + Io::WriteU32(lsdaUdata4Bytes, 0x224, 0x24); + Io::WriteU64(lsdaUdata4Bytes, 0x228, 0xFFFFFFFFFFFFF000ULL); + Io::WriteU64(lsdaUdata4Bytes, 0x230, 0x20); + lsdaUdata4Bytes[0x238] = 4; + Io::WriteU32(lsdaUdata4Bytes, 0x239, 0x1000); + lsdaUdata4Bytes[0x300] = 1; + lsdaUdata4Bytes[0x302] = 3; + Io::WriteU64(lsdaUdata4Bytes, 0x304, 0x200); + Io::WriteU32(lsdaUdata4Bytes, 0x30C, 1); + Io::WriteU64(lsdaUdata4Bytes, 0x310, 0xFFFFFFFFFFFFF000ULL); + Io::WriteU64(lsdaUdata4Bytes, 0x318, 0x220); + Domain::ProgramHeader lsdaUdata4Load{}; lsdaUdata4Load.Type = 1; lsdaUdata4Load.Flags = 4; lsdaUdata4Load.FileSize = lsdaUdata4Bytes.size(); lsdaUdata4Load.MemorySize = lsdaUdata4Bytes.size(); lsdaUdata4Load.Alignment = 8; + Domain::ProgramHeader lsdaUdata4Eh = lsdaUdata4Load; lsdaUdata4Eh.Type = 0x6474E550; lsdaUdata4Eh.Offset = 0x300; lsdaUdata4Eh.MappedAddress = 0x300; lsdaUdata4Eh.FileSize = 32; lsdaUdata4Eh.MemorySize = 32; lsdaUdata4Eh.Alignment = 4; + bool lsdaUdata4Rejected = false; + try { Relinker::UnusedNidFilter::ReadExceptionFunctions(lsdaUdata4Bytes, {lsdaUdata4Load, lsdaUdata4Eh}, {}, {}); } + catch (const Domain::RelinkerException& error) { + lsdaUdata4Rejected = std::string(error.what()).find("unwind pointer address overflowed") != std::string::npos; + } + Require(lsdaUdata4Rejected); + std::cout << "27 unwind record cases passed\n"; } catch (const std::exception& error) { std::cerr << error.what() << '\n'; return 1; } }