patch: fix loading patchelf'ed libraries (RB#10231)

This commit is contained in:
Mikhail Novosyolov 2020-04-06 05:18:58 +03:00
parent 53604b97f1
commit 721db032d6
2 changed files with 91 additions and 1 deletions

View file

@ -0,0 +1,85 @@
[PATCH] ldconfig: file truncated while reading soname after patchelf [BZ #23964]
The way loadaddr is computed from the first LOAD segment in process_elf_file
assumes .dynstr is also contained in that segment. That is not necessarily
true, especially for libraries that have been touched by patchelf.
With this patch, the address read from the dynamic segment is checked against
all applicable segments instead of only the first one.
[BZ #23964]
* elf/readelflib.c: Fix resolving of loadaddr for .dynstr vaddr.
---
elf/readelflib.c | 33 ++++++++++++++++-----------------
1 file changed, 16 insertions(+), 17 deletions(-)
diff --git a/elf/readelflib.c b/elf/readelflib.c
index 5a1e2dc2df..bc1195c175 100644
--- a/elf/readelflib.c
+++ b/elf/readelflib.c
@@ -98,11 +98,6 @@ process_elf_file (const char *file_name, const char *lib, int *flag,
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 +171,6 @@ process_elf_file (const char *file_name, const char *lib, int *flag,
}
}
- if (loadaddr == (ElfW(Addr)) -1)
- {
- /* Very strange. */
- loadaddr = 0;
- }
/* Now we can read the dynamic sections. */
if (dynamic_size == 0)
@@ -190,22 +180,31 @@ process_elf_file (const char *file_name, const char *lib, int *flag,
check_ptr (dynamic_segment);
/* Find the string table. */
- dynamic_strings = NULL;
for (dyn_entry = dynamic_segment; dyn_entry->d_tag != DT_NULL;
++dyn_entry)
{
check_ptr (dyn_entry);
if (dyn_entry->d_tag == DT_STRTAB)
- {
- dynamic_strings = (char *) (file_contents + dyn_entry->d_un.d_val - loadaddr);
- check_ptr (dynamic_strings);
- break;
- }
+ break;
}
- if (dynamic_strings == NULL)
+ for (i = 0, segment = elf_pheader;i < elf_header->e_phnum; i++, segment++)
+ {
+ ElfW(Addr) vaddr = dyn_entry->d_un.d_ptr;
+ if (segment->p_type == PT_LOAD &&
+ vaddr >= segment->p_vaddr &&
+ vaddr < segment->p_vaddr + segment->p_filesz)
+ {
+ loadaddr = segment->p_vaddr - segment->p_offset;
+ break;
+ }
+ }
+ if (loadaddr == (ElfW(Addr)) -1)
return 1;
+ dynamic_strings = (char *) (file_contents + dyn_entry->d_un.d_val - loadaddr);
+ check_ptr (dynamic_strings);
+
/* Now read the DT_NEEDED and DT_SONAME entries. */
for (dyn_entry = dynamic_segment; dyn_entry->d_tag != DT_NULL;
++dyn_entry)
--
2.19.2

View file

@ -57,7 +57,7 @@ Summary: The GNU libc libraries
Name: glibc
Epoch: 6
Version: 2.24
Release: 9
Release: 11
License: LGPLv2+ and LGPLv2+ with exceptions and GPLv2+
Group: System/Libraries
Url: http://www.eglibc.org/
@ -217,6 +217,10 @@ Patch205: glibc-2.24-CVE-2017-16997.patch
Patch206: glibc-2.24-CVE-2017-15670.patch
Patch208: glibc-2.24-CVE-2017-15804.patch
# https://sourceware.org/bugzilla/show_bug.cgi?id=23964
# https://bugzilla.rosalinux.ru/show_bug.cgi?id=10231#c5
Patch210: glibc-ldconfig-patchelf-truncated.patch
BuildRequires: autoconf2.5
BuildRequires: gettext
BuildRequires: kernel-headers
@ -906,6 +910,7 @@ cp -a crypt_blowfish-%{crypt_bf_ver}/*.[chS] crypt/
%patch205 -p1
%patch206 -p1
%patch208 -p1
%patch210 -p1
%if %{with selinux}
# XXX kludge to build nscd with selinux support as it added -nostdinc