From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by finch.gentoo.org (Postfix) with ESMTPS id 455841382C5 for ; Sat, 24 Feb 2018 10:16:54 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 51744E07B3; Sat, 24 Feb 2018 10:16:53 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id 1AE86E07B3 for ; Sat, 24 Feb 2018 10:16:52 +0000 (UTC) Received: from oystercatcher.gentoo.org (unknown [IPv6:2a01:4f8:202:4333:225:90ff:fed9:fc84]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id 9E86E335C0C for ; Sat, 24 Feb 2018 10:16:51 +0000 (UTC) Received: from localhost.localdomain (localhost [IPv6:::1]) by oystercatcher.gentoo.org (Postfix) with ESMTP id 306B71FE for ; Sat, 24 Feb 2018 10:16:50 +0000 (UTC) From: "Sergei Trofimovich" To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Sergei Trofimovich" Message-ID: <1518984645.e7b8f34f4557d7071a955ccab813ec41aeeb966b.slyfox@gentoo> Subject: [gentoo-commits] proj/pax-utils:master commit in: / X-VCS-Repository: proj/pax-utils X-VCS-Files: scanelf.c X-VCS-Directories: / X-VCS-Committer: slyfox X-VCS-Committer-Name: Sergei Trofimovich X-VCS-Revision: e7b8f34f4557d7071a955ccab813ec41aeeb966b X-VCS-Branch: master Date: Sat, 24 Feb 2018 10:16:50 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org X-Archives-Salt: 3a52c9f9-4b97-4909-b3f8-bc1a016b5503 X-Archives-Hash: 3bb434579cd2e9e4a76c6c0fd137f7f8 commit: e7b8f34f4557d7071a955ccab813ec41aeeb966b Author: Sergei Trofimovich gentoo org> AuthorDate: Sun Feb 18 20:10:45 2018 +0000 Commit: Sergei Trofimovich gentoo org> CommitDate: Sun Feb 18 20:10:45 2018 +0000 URL: https://gitweb.gentoo.org/proj/pax-utils.git/commit/?id=e7b8f34f scanelf.c: fix TEXTREL parsing for files with non-zero load address In bug #566118 scanelf failed to decode TEXTRELs on gcc binaries where program headers have absolute addresses: $ dumpelf ia64_bug_gcc/cc1plus /* Dynamic tag #25 'DT_RELA' 0x2099518 */ { .d_tag = 0x7 , .d_un = { .d_val = 0x4000000000104B08 , .d_ptr = 0x4000000000104B08 , }, }, /* Section Header #8 '.rela.dyn' 0x20AA610 */ { .sh_type = 4 , /* [SHT_RELA] */ .sh_addr = 0x4000000000104B08 , .sh_offset = 1067784 , /* (bytes) */ }, Before the change scanelf assumed DT_RELA.d_ptr is a relative offset. This is not true in general case but good-enough for DSOs as they have zero load address. This change extends the check for executables. To make addresses relative again we find load address of first byte from program header with 'p_offset'. /* Program Header #2 0xB0 */ { .p_type = 1 , /* [PT_LOAD] */ .p_offset = 0 , /* (bytes into file) */ .p_vaddr = 0x4000000000000000 , /* (virtual addr at runtime) */ .p_paddr = 0x4000000000000000 , /* (physical addr at runtime) */ }, Bug: https://bugs.gentoo.org/566118 Signed-off-by: Sergei Trofimovich gentoo.org> scanelf.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/scanelf.c b/scanelf.c index a054408..530edfb 100644 --- a/scanelf.c +++ b/scanelf.c @@ -579,6 +579,8 @@ static char *scanelf_file_textrels(elfobj *elf, char *found_textrels, char *foun Elf ## B ## _Rela *rela; \ Elf ## B ## _Dyn *dyn, *drel, *drelsz, *drelent, *dpltrel; \ uint32_t pltrel; \ + Elf ## B ## _Addr load_address = 0; \ + Elf ## B ## _Addr file_offset; \ \ /* Walk all the dynamic tags to find relocation info */ \ drel = drelsz = drelent = dpltrel = NULL; \ @@ -605,27 +607,40 @@ static char *scanelf_file_textrels(elfobj *elf, char *found_textrels, char *foun warnf("ELF is missing relocation information"); \ break; \ } \ + phdr = PHDR ## B(elf->phdr); \ + /* Lookup load base: byte 0 is mapped at load_address */ \ + for (i = 0; i < EGET(ehdr->e_phnum); ++i) { \ + /* Only care about loadable segments. */ \ + if (EGET(phdr[i].p_type) != PT_LOAD) \ + continue; \ + /* We search for the first program header to map into memory */ \ + if (EGET(phdr[i].p_offset) != 0) \ + continue; \ + load_address = EGET(phdr[i].p_vaddr); \ + } \ switch (EGET(dpltrel->d_un.d_val)) { \ case DT_REL: \ - if (!VALID_RANGE(elf, EGET(drel->d_un.d_val), sizeof (drel->d_un.d_val))) { \ + file_offset = EGET(drel->d_un.d_val) - load_address; \ + if (!VALID_RANGE(elf, file_offset, sizeof (drel->d_un.d_val))) { \ rel = NULL; \ rela = NULL; \ warn("%s: DT_REL is out of file range", elf->filename); \ break; \ } \ - rel = REL##B(elf->vdata + EGET(drel->d_un.d_val)); \ + rel = REL##B(elf->vdata + file_offset); \ rela = NULL; \ pltrel = DT_REL; \ break; \ case DT_RELA: \ - if (!VALID_RANGE(elf, EGET(drel->d_un.d_val), sizeof (drel->d_un.d_val))) { \ + file_offset = EGET(drel->d_un.d_val) - load_address; \ + if (!VALID_RANGE(elf, file_offset, sizeof (drel->d_un.d_val))) { \ rel = NULL; \ rela = NULL; \ warn("%s: DT_RELA is out of file range", elf->filename); \ break; \ } \ rel = NULL; \ - rela = RELA##B(elf->vdata + EGET(drel->d_un.d_val)); \ + rela = RELA##B(elf->vdata + file_offset); \ pltrel = DT_RELA; \ break; \ default: \ @@ -639,7 +654,6 @@ static char *scanelf_file_textrels(elfobj *elf, char *found_textrels, char *foun rmax = EGET(drelsz->d_un.d_val) / EGET(drelent->d_un.d_val); \ \ /* search the program segments for relocations */ \ - phdr = PHDR ## B(elf->phdr); \ for (i = 0; i < EGET(ehdr->e_phnum); ++i) { \ Elf ## B ## _Addr vaddr = EGET(phdr[i].p_vaddr); \ uint ## B ## _t memsz = EGET(phdr[i].p_memsz); \