diff --git a/core/relinker/CMakeLists.txt b/core/relinker/CMakeLists.txt index 29e22477a1..d73be4811a 100644 --- a/core/relinker/CMakeLists.txt +++ b/core/relinker/CMakeLists.txt @@ -807,6 +807,12 @@ if(BUILD_TESTING) ${CMAKE_CURRENT_SOURCE_DIR}/relinker/tests/test_guest_absolute_symbols.py $) add_test(NAME guest_module_identity COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/relinker/tests/test_guest_module_identity.py $) + add_test(NAME linux_guest_zero_address_exports COMMAND ${Python3_EXECUTABLE} + ${CMAKE_CURRENT_SOURCE_DIR}/relinker/tests/test_linux_guest_zero_address_exports.py + $ $) + set_property(TEST linux_guest_zero_address_exports APPEND PROPERTY LABELS relinker) + set_tests_properties(linux_guest_zero_address_exports PROPERTIES TIMEOUT 30) + add_asan_test_options(linux_guest_zero_address_exports verify_asan_link_order=0) add_test(NAME guest_unused_import_dependencies COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/relinker/tests/test_guest_unused_import_dependencies.py $ $) diff --git a/core/relinker/elfpatcher/src/linux/LinuxGuestModuleWriter.cpp b/core/relinker/elfpatcher/src/linux/LinuxGuestModuleWriter.cpp index ab4dfbdd46..d349044c2b 100644 --- a/core/relinker/elfpatcher/src/linux/LinuxGuestModuleWriter.cpp +++ b/core/relinker/elfpatcher/src/linux/LinuxGuestModuleWriter.cpp @@ -64,6 +64,17 @@ std::vector GuestModuleWriter::WriteLinux(const Relinker::GuestIma needsTlsResolver = true; } } + for (std::size_t index = 1; index < image.Symbols.size(); ++index) { + const auto& symbol = image.Symbols[index]; + if (symbol.Value != 0 || symbol.Section == 0 || symbol.Section >= 0xff00 || (symbol.Info >> 4) == 0 || + (symbol.Info & 15) != 2 || symbol.Visibility == 1 || symbol.Visibility == 2) continue; + const auto thunk = address(); + if (thunk > static_cast(std::numeric_limits::max()) - 5) + throw Domain::RelinkerException("Guest export at address 0 exceeds relative branch range"); + bytes.push_back(0xe9); + Io::AppendU32(bytes, static_cast(-static_cast(thunk + 5))); + Io::WriteU64(symbols, index * 24 + 8, thunk); + } std::vector needed; for (const auto& dependency : dependencies) needed.push_back(addString(dependency)); if (needsTlsResolver) needed.push_back(addString("ld-linux-x86-64.so.2")); diff --git a/core/relinker/relinker/tests/test_linux_guest_zero_address_exports.py b/core/relinker/relinker/tests/test_linux_guest_zero_address_exports.py new file mode 100644 index 0000000000..c6ca0bcbde --- /dev/null +++ b/core/relinker/relinker/tests/test_linux_guest_zero_address_exports.py @@ -0,0 +1,119 @@ +import os +from pathlib import Path +import platform +import shutil +import struct +import subprocess +import sys +import tempfile + +from test_guest_deferred_dependencies import page_aligned +from test_guest_export_lookup import guest_symbols +from test_guest_intel_trampolines import main_fixture +from test_guest_symbol_names import dynamic_tags, file_offset, symbol_name +from test_windows_import_modules import consumer, provider + + +def at_address_zero(image): + struct.pack_into("` at startup for each such module that an import of the executable names, whether or not the title loads it later; an import without a module name is not reported. macOS still starts it at startup.