diff --git a/libexec/rtld-elf/map_object.c b/libexec/rtld-elf/map_object.c --- a/libexec/rtld-elf/map_object.c +++ b/libexec/rtld-elf/map_object.c @@ -93,8 +93,6 @@ Elf_Addr bss_vlimit; caddr_t bss_addr; Elf_Word stack_flags; - Elf_Addr relro_page; - size_t relro_size; Elf_Addr note_start; Elf_Addr note_end; char *note_map; @@ -114,8 +112,6 @@ nsegs = -1; phdyn = phinterp = phtls = NULL; phdr_vaddr = 0; - relro_page = 0; - relro_size = 0; note_start = 0; note_end = 0; note_map = NULL; @@ -161,11 +157,6 @@ stack_flags = phdr->p_flags; break; - case PT_GNU_RELRO: - relro_page = phdr->p_vaddr; - relro_size = phdr->p_memsz; - break; - case PT_NOTE: if (phdr->p_offset > page_size || phdr->p_offset + phdr->p_filesz > page_size) { @@ -323,9 +314,6 @@ obj->tlsinit = mapbase + phtls->p_vaddr; } obj->stack_flags = stack_flags; - obj->relro_page = obj->relocbase + rtld_trunc_page(relro_page); - obj->relro_size = rtld_trunc_page(relro_page + relro_size) - - rtld_trunc_page(relro_page); if (note_start < note_end) digest_notes(obj, note_start, note_end); if (note_map != NULL) diff --git a/libexec/rtld-elf/rtld.h b/libexec/rtld-elf/rtld.h --- a/libexec/rtld-elf/rtld.h +++ b/libexec/rtld-elf/rtld.h @@ -165,9 +165,6 @@ size_t tlsalign; /* Alignment of static TLS block */ size_t tlspoffset; /* p_offset of the static TLS block */ - caddr_t relro_page; - size_t relro_size; - /* Items from the dynamic section. */ Elf_Addr *pltgot; /* PLT or GOT, depending on architecture */ const Elf_Rel *rel; /* Relocation entries */ diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -1672,12 +1672,6 @@ obj->stack_flags = ph->p_flags; break; - case PT_GNU_RELRO: - obj->relro_page = obj->relocbase + rtld_trunc_page(ph->p_vaddr); - obj->relro_size = rtld_trunc_page(ph->p_vaddr + ph->p_memsz) - - rtld_trunc_page(ph->p_vaddr); - break; - case PT_NOTE: note_start = (Elf_Addr)obj->relocbase + ph->p_vaddr; note_end = note_start + ph->p_filesz; @@ -2369,11 +2363,6 @@ case PT_GNU_STACK: obj->stack_flags = ph->p_flags; break; - case PT_GNU_RELRO: - obj->relro_page = obj->relocbase + - rtld_trunc_page(ph->p_vaddr); - obj->relro_size = rtld_round_page(ph->p_memsz); - break; case PT_NOTE: note_start = (Elf_Addr)obj->relocbase + ph->p_vaddr; note_end = note_start + ph->p_filesz; @@ -3328,7 +3317,7 @@ lockstate) == -1) return (-1); - if (!obj->mainprog && obj_enforce_relro(obj) == -1) + if (obj != rtldobj && !obj->mainprog && obj_enforce_relro(obj) == -1) return (-1); /* @@ -5909,12 +5898,26 @@ static int obj_remap_relro(Obj_Entry *obj, int prot) { + const Elf_Phdr *ph; + caddr_t relro_page; + size_t relro_size; - if (obj->relro_size > 0 && mprotect(obj->relro_page, obj->relro_size, - prot) == -1) { - _rtld_error("%s: Cannot set relro protection to %#x: %s", - obj->path, prot, rtld_strerror(errno)); - return (-1); + for (ph = obj->phdr; (const char *)ph < (const char *)obj->phdr + + obj->phsize; ph++) { + switch (ph->p_type) { + case PT_GNU_RELRO: + relro_page = obj->relocbase + + rtld_trunc_page(ph->p_vaddr); + relro_size = + rtld_round_page(ph->p_vaddr + ph->p_memsz) - + rtld_trunc_page(ph->p_vaddr); + if (mprotect(relro_page, relro_size, prot) == -1) { + _rtld_error("%s: Cannot set relro protection to %#x: %s", + obj->path, prot, rtld_strerror(errno)); + return (-1); + } + break; + } } return (0); }