Skip to content

Commit

Permalink
libsel4utils: Fix TLS page fault if PT_PHDR exists
Browse files Browse the repository at this point in the history
PT_PHDR is emitted by ld.lld but not ld.bfd. This segment should only
exist if the program header *is* part of the program memory image itself
(which is not the case in seL4, as it copies the program header in the
sack). This is important as muslc’s TLS init is relying on the existence
of PT_PHDR to get the base address of the image in memory and from that,
it calculates the TLS base for the source ELF. The calculation will be
wrong in seL4 as the program header is copied in the stack; thus it may
trigger a page fault if the new TLS base is not mapped, or affects the
integrity of programs relying on TLS variables (e.g., those with
__thread).

By setting PT_PHDR's segment to PT_NULL, muslc will skip this search and
won't do any relocations for the TLS segment which is part of the
loaded ELF image itself, thus getting the correct mapped address.

Sponsored by: DARPA.

Signed-off-by: Hesham Almatary <[email protected]>
  • Loading branch information
heshamelmatary committed Jan 16, 2024
1 parent f344301 commit 880f991
Showing 1 changed file with 13 additions and 0 deletions.
13 changes: 13 additions & 0 deletions libsel4utils/src/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -271,9 +271,22 @@ int sel4utils_spawn_process_v(sel4utils_process_t *process, vka_t *vka, vspace_t
int error;
int envc = 0;
char *envp[] = {};
Elf_Phdr *phdr = process->elf_phdrs;

uintptr_t initial_stack_pointer = (uintptr_t) process->thread.stack_top - sizeof(seL4_Word);

/* If PT_PHDR exists in the program headers, assign PT_NULL to it.
* This is because muslc libc searches for PT_PHDR and if found,
* it assumes it's part of the ELF image and relocates the entire
* subsequent program header segments according to PT_PHDR's base. This is
* wrong and will trigger mapping errors.
*/
for (int i = 0; i < process->num_elf_phdrs; i++, phdr++) {
if (phdr->p_type == PT_PHDR) {
phdr->p_type = PT_NULL;
}
}

/* Copy the elf headers */
uintptr_t at_phdr;
error = sel4utils_stack_write(vspace, &process->vspace, vka, process->elf_phdrs,
Expand Down

0 comments on commit 880f991

Please sign in to comment.