Skip to content

Commit

Permalink
rtld: Workaround Morello LLVM lld bug with local-caprelocs=elf
Browse files Browse the repository at this point in the history
Morello LLVM's lld always emits PLT-related .dynamic entries when ELF
local caprelocs are used even if the PLT is empty.  This confuses rtld
which tries to treat the start of the binary as a GOT PLT.  In
particular, rtld itself ends up with an empty PLT and so rtld tries to
write to its ELF header which crashes since the page is mapped
read-only.

Workaround this by ignoring DT_JMPREL and DT_PLTGOT entries whose
value is 0.  The PLT GOT and PLT relocation table can never be at the
start of a valid binary.
  • Loading branch information
bsdjhb committed Jan 8, 2025
1 parent 7ec64fb commit 8a811da
Showing 1 changed file with 10 additions and 0 deletions.
10 changes: 10 additions & 0 deletions libexec/rtld-elf/rtld.c
Original file line number Diff line number Diff line change
Expand Up @@ -1485,6 +1485,11 @@ digest_dynamic1(Obj_Entry *obj, int early, const Elf_Dyn **dyn_rpath,
break;

case DT_JMPREL:
#ifdef __aarch64__
/* Ignore empty PLT entries for Morello. */
if (dynp->d_un.d_ptr == 0)
break;
#endif
obj->pltrel = (const Elf_Rel *)
(obj->relocbase + dynp->d_un.d_ptr);
break;
Expand Down Expand Up @@ -1643,6 +1648,11 @@ digest_dynamic1(Obj_Entry *obj, int early, const Elf_Dyn **dyn_rpath,
break;

case DT_PLTGOT:
#ifdef __aarch64__
/* Ignore empty PLT entries for Morello. */
if (dynp->d_un.d_ptr == 0)
break;
#endif
obj->pltgot = (uintptr_t *)(obj->relocbase + dynp->d_un.d_ptr);
break;

Expand Down

0 comments on commit 8a811da

Please sign in to comment.