Merge "Restore protection flags for ifunc during relocs."
This commit is contained in:
commit
f16c6e17b2
@ -1999,9 +1999,32 @@ bool soinfo::relocate(const VersionTracker& version_tracker, ElfRelIteratorT&& r
|
|||||||
DL_ERR("unknown weak reloc type %d @ %p (%zu)", type, rel, idx);
|
DL_ERR("unknown weak reloc type %d @ %p (%zu)", type, rel, idx);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else { // We got a definition.
|
||||||
// We got a definition.
|
#if !defined(__LP64__)
|
||||||
|
// When relocating dso with text_relocation .text segment is
|
||||||
|
// not executable. We need to restore elf flags before resolving
|
||||||
|
// STT_GNU_IFUNC symbol.
|
||||||
|
bool protect_segments = has_text_relocations &&
|
||||||
|
lsi == this &&
|
||||||
|
ELF_ST_TYPE(s->st_info) == STT_GNU_IFUNC;
|
||||||
|
if (protect_segments) {
|
||||||
|
if (phdr_table_protect_segments(phdr, phnum, load_bias) < 0) {
|
||||||
|
DL_ERR("can't protect segments for \"%s\": %s",
|
||||||
|
get_realpath(), strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
sym_addr = lsi->resolve_symbol_address(s);
|
sym_addr = lsi->resolve_symbol_address(s);
|
||||||
|
#if !defined(__LP64__)
|
||||||
|
if (protect_segments) {
|
||||||
|
if (phdr_table_unprotect_segments(phdr, phnum, load_bias) < 0) {
|
||||||
|
DL_ERR("can't unprotect loadable segments for \"%s\": %s",
|
||||||
|
get_realpath(), strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
count_relocation(kRelocSymbol);
|
count_relocation(kRelocSymbol);
|
||||||
}
|
}
|
||||||
@ -2038,7 +2061,32 @@ bool soinfo::relocate(const VersionTracker& version_tracker, ElfRelIteratorT&& r
|
|||||||
TRACE_TYPE(RELO, "RELO IRELATIVE %16p <- %16p\n",
|
TRACE_TYPE(RELO, "RELO IRELATIVE %16p <- %16p\n",
|
||||||
reinterpret_cast<void*>(reloc),
|
reinterpret_cast<void*>(reloc),
|
||||||
reinterpret_cast<void*>(load_bias + addend));
|
reinterpret_cast<void*>(load_bias + addend));
|
||||||
*reinterpret_cast<ElfW(Addr)*>(reloc) = call_ifunc_resolver(load_bias + addend);
|
{
|
||||||
|
#if !defined(__LP64__)
|
||||||
|
// When relocating dso with text_relocation .text segment is
|
||||||
|
// not executable. We need to restore elf flags for this
|
||||||
|
// particular call.
|
||||||
|
if (has_text_relocations) {
|
||||||
|
if (phdr_table_protect_segments(phdr, phnum, load_bias) < 0) {
|
||||||
|
DL_ERR("can't protect segments for \"%s\": %s",
|
||||||
|
get_realpath(), strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
ElfW(Addr) ifunc_addr = call_ifunc_resolver(load_bias + addend);
|
||||||
|
#if !defined(__LP64__)
|
||||||
|
// Unprotect it afterwards...
|
||||||
|
if (has_text_relocations) {
|
||||||
|
if (phdr_table_unprotect_segments(phdr, phnum, load_bias) < 0) {
|
||||||
|
DL_ERR("can't unprotect loadable segments for \"%s\": %s",
|
||||||
|
get_realpath(), strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
*reinterpret_cast<ElfW(Addr)*>(reloc) = ifunc_addr;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#if defined(__aarch64__)
|
#if defined(__aarch64__)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user