diff --git a/glibc.changes b/glibc.changes index 27e5317..de5cd95 100644 --- a/glibc.changes +++ b/glibc.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Thu Oct 10 14:39:24 UTC 2019 - Andreas Schwab + +- ldconfig-dynstr.patch: ldconfig: handle .dynstr located in separate + segment (bsc#1153149, BZ #25087) + ------------------------------------------------------------------- Mon Sep 23 14:00:09 UTC 2019 - Andreas Schwab diff --git a/glibc.spec b/glibc.spec index 6ae155e..3cc8e75 100644 --- a/glibc.spec +++ b/glibc.spec @@ -271,6 +271,8 @@ Patch1001: riscv-vfork.patch Patch2000: fix-locking-in-_IO_cleanup.patch # PATCH-FIX-UPSTREAM Avoid concurrency problem in ldconfig (BZ #23973) Patch2001: ldconfig-concurrency.patch +# PATCH-FIX-UPSTREAM ldconfig: handle .dynstr located in separate segment (BZ #25087) +Patch2002: ldconfig-dynstr.patch # Non-glibc patches # PATCH-FIX-OPENSUSE Remove debianisms from manpages @@ -473,6 +475,7 @@ makedb: A program to create a database for nss %patch2000 -p1 %patch2001 -p1 +%patch2002 -p1 %patch3000 diff --git a/ldconfig-dynstr.patch b/ldconfig-dynstr.patch new file mode 100644 index 0000000..654d044 --- /dev/null +++ b/ldconfig-dynstr.patch @@ -0,0 +1,86 @@ +ldconfig: handle .dynstr located in separate segment (bug 25087) + +To determine the load offset of the DT_STRTAB section search for the +segment containing it, instead of using the load offset of the first +segment. + + [BZ #25087] + * elf/readelflib.c (process_elf_file): Use containing segment for + DT_STRTAB load offset. +--- + elf/readelflib.c | 34 +++++++++++++++++++++------------- + 1 file changed, 21 insertions(+), 13 deletions(-) + +Index: glibc-2.30/elf/readelflib.c +=================================================================== +--- glibc-2.30.orig/elf/readelflib.c ++++ glibc-2.30/elf/readelflib.c +@@ -45,7 +45,6 @@ process_elf_file (const char *file_name, + { + int i; + unsigned int j; +- ElfW(Addr) loadaddr; + unsigned int dynamic_addr; + size_t dynamic_size; + char *program_interpreter; +@@ -87,7 +86,6 @@ process_elf_file (const char *file_name, + libc5/libc6. */ + *flag = FLAG_ELF; + +- loadaddr = -1; + dynamic_addr = 0; + dynamic_size = 0; + program_interpreter = NULL; +@@ -98,11 +96,6 @@ process_elf_file (const char *file_name, + + switch (segment->p_type) + { +- case PT_LOAD: +- if (loadaddr == (ElfW(Addr)) -1) +- loadaddr = segment->p_vaddr - segment->p_offset; +- break; +- + case PT_DYNAMIC: + if (dynamic_addr) + error (0, 0, _("more than one dynamic segment\n")); +@@ -176,11 +169,6 @@ process_elf_file (const char *file_name, + } + + } +- if (loadaddr == (ElfW(Addr)) -1) +- { +- /* Very strange. */ +- loadaddr = 0; +- } + + /* Now we can read the dynamic sections. */ + if (dynamic_size == 0) +@@ -197,7 +185,27 @@ process_elf_file (const char *file_name, + check_ptr (dyn_entry); + if (dyn_entry->d_tag == DT_STRTAB) + { +- dynamic_strings = (char *) (file_contents + dyn_entry->d_un.d_val - loadaddr); ++ /* Find the file offset of the segment containing the dynamic ++ string table. */ ++ ElfW(Off) loadoff = -1; ++ for (i = 0, segment = elf_pheader; ++ i < elf_header->e_phnum; i++, segment++) ++ { ++ if (segment->p_type == PT_LOAD ++ && dyn_entry->d_un.d_val >= segment->p_vaddr ++ && dyn_entry->d_un.d_val < segment->p_vaddr + segment->p_filesz) ++ { ++ loadoff = segment->p_vaddr - segment->p_offset; ++ break; ++ } ++ } ++ if (loadoff == (ElfW(Off)) -1) ++ { ++ /* Very strange. */ ++ loadoff = 0; ++ } ++ ++ dynamic_strings = (char *) (file_contents + dyn_entry->d_un.d_val - loadoff); + check_ptr (dynamic_strings); + break; + }