mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 05:48:12 +00:00
LibELF: Fail gracefully when IFUNC resolver's object has textrels
.text sections of objects that contain textrels have to be writable during the relocation procedure. Because of this, we would segfault if we tried to execute IFUNC resolvers defined in them. Let's print a meaningful error message instead. Additionally, a warning is now printed when we load objects with textrels, as in the future, additional security mitigations might interfere with them being loaded.
This commit is contained in:
parent
08c459e495
commit
7aca408993
1 changed files with 13 additions and 1 deletions
|
@ -162,6 +162,7 @@ bool DynamicLoader::load_stage_2(unsigned flags)
|
|||
VERIFY(flags & RTLD_GLOBAL);
|
||||
|
||||
if (m_dynamic_object->has_text_relocations()) {
|
||||
dbgln("\033[33mWarning:\033[0m Dynamic object {} has text relocations", m_dynamic_object->filename());
|
||||
for (auto& text_segment : m_text_segments) {
|
||||
VERIFY(text_segment.address().get() != 0);
|
||||
|
||||
|
@ -488,8 +489,13 @@ DynamicLoader::RelocationResult DynamicLoader::do_relocation(const ELF::DynamicO
|
|||
symbol_location = VirtualAddress { (FlatPtr)0 };
|
||||
} else {
|
||||
symbol_location = res.value().address;
|
||||
if (res.value().type == STT_GNU_IFUNC)
|
||||
if (res.value().type == STT_GNU_IFUNC) {
|
||||
if (res.value().dynamic_object != nullptr && res.value().dynamic_object->has_text_relocations()) {
|
||||
dbgln("\033[31mError:\033[0m Refusing to call IFUNC resolver defined in an object with text relocations.");
|
||||
return RelocationResult::Failed;
|
||||
}
|
||||
symbol_location = call_ifunc_resolver(symbol_location);
|
||||
}
|
||||
}
|
||||
VERIFY(symbol_location != m_dynamic_object->base_address());
|
||||
*patch_ptr = symbol_location.get();
|
||||
|
@ -562,6 +568,12 @@ DynamicLoader::RelocationResult DynamicLoader::do_relocation(const ELF::DynamicO
|
|||
resolver = m_dynamic_object->base_address().offset(relocation.addend());
|
||||
else
|
||||
resolver = m_dynamic_object->base_address().offset(*patch_ptr);
|
||||
|
||||
if (m_dynamic_object->has_text_relocations()) {
|
||||
dbgln("\033[31mError:\033[0m Refusing to call IFUNC resolver defined in an object with text relocations.");
|
||||
return RelocationResult::Failed;
|
||||
}
|
||||
|
||||
*patch_ptr = call_ifunc_resolver(resolver).get();
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue