Fix ld.so PLT relocations by relocating lazily before is_me check
Previously, relocate() returned early for self.is_me before calling lazy_relocate(), assuming ld.so had no lazy relocations to process. However, ld.so is itself PIE and relies on lazy PLT relocations internally, so its own PLT entries need the load base added to them (see the PLT/Resolve::Lazy branch in lazy_relocate()). Skipping this step left ld.so's PLT stubs pointing at unrelocated addresses. Once ld.so was loaded at a non-zero base, any internal call through the PLT jumped to an invalid address, triggering a synchronous exception during early boot (observed as crashes in nvmed/redoxfs before switchroot completed on AArch64). Signed-off-by: Luiz Fernando Becher de Araujo <luiz.becher.araujo@gmail.com> (cherry picked from commit 72c0078d5de565743c99a07fcff6557361d91694)
This commit is contained in:
+5
-3
@@ -1245,13 +1245,15 @@ impl DSO {
|
||||
self.static_relocate(&global_scope, reloc)?;
|
||||
}
|
||||
|
||||
// ld.so is itself PIE and uses lazy PLT relocations internally,
|
||||
// so its own PLT entries must be adjusted by the load base before
|
||||
// use.
|
||||
self.lazy_relocate(&global_scope, resolve)?;
|
||||
|
||||
if self.is_me {
|
||||
// TODO: assert that ld.so have no lazy relocations.
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
self.lazy_relocate(&global_scope, resolve)?;
|
||||
|
||||
let ph = ph.unwrap();
|
||||
|
||||
// Protect pages
|
||||
|
||||
Reference in New Issue
Block a user