From patchwork Tue Mar 1 12:54:04 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Di Chen X-Patchwork-Id: 51469 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id AB6B93858C39 for ; Tue, 1 Mar 2022 12:54:32 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org AB6B93858C39 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1646139272; bh=Fj4AnJDYO6jxvGvDTuNnyMYtSCr6oG9N+clX6gmXeEM=; h=Date:Subject:To:List-Id:List-Unsubscribe:List-Archive:List-Help: List-Subscribe:From:Reply-To:From; b=PYr+QRqjTJj7Z7gFWf/3KowO5hUBlkAEvJPucN9NTmvawzo6h61kX+hvV9BGBkOQB IrtYIqh0N9emvhTACVzxk/AJ2+Ss4HATEnWjh3SHWY9MdMmUGc89KFZXhszyepTiSt GCUi6hpfKGa9EcDoHMgG+EQZaH9oLKVUvhAO53JI= X-Original-To: elfutils-devel@sourceware.org Delivered-To: elfutils-devel@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id E3A6E3858D39 for ; Tue, 1 Mar 2022 12:54:21 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org E3A6E3858D39 Received: from mail-ej1-f69.google.com (mail-ej1-f69.google.com [209.85.218.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-627-epOqeSqgMa66P_O2jV4_IQ-1; Tue, 01 Mar 2022 07:54:17 -0500 X-MC-Unique: epOqeSqgMa66P_O2jV4_IQ-1 Received: by mail-ej1-f69.google.com with SMTP id m4-20020a170906160400b006be3f85906eso6795106ejd.23 for ; Tue, 01 Mar 2022 04:54:17 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=sTlXAVUQKLIBFkCrweLtTmvw3GRU27rrj4ZYRrLNHO8=; b=Ju9huPsHUHV5ug6U3vq3KF0dN8EfuhqBTVumuBYXSYWl/kXf4aJ9FfzdZpn0tWKWCG BeRsszTfzfatqb/+xaaj0flhE7O31NE1TLVKPDJgYWcqYz/9cuKPuCGc8ggCsgtLlTHz AHz98r/RtS5i2N4wGifPWLyA+Mz/EpygCSJRCHcz0Umh5MXOVzWU7RIdzQiuzok4Va9D uHM2AerZxQswFjCL/MMuca9u6UtQYcQGmvbSBcSRQzLDqB4cFRsVDdKPlRUs0TRK+dVO 1Yppk/DRsTsiOi8YKJrv6BZomJy53UCUaE4ke8pZmX01Mu4eu+anbncEg66lzOL9ShWW 95Jg== X-Gm-Message-State: AOAM53274itgqGmNMIuYKNTrsCx094kq6NIeyGx2/E/n+nK5KzAu246M IIMxuvr6KjVF3jo4aBscMuVWsZIPgKp0iSR5AJQW59zvgofWIAK2Fm00VYvvVYVR8ZnsRQPGB0B llVx3cQHsodYolB6i9bpHB+NNAaFHNYL+1ja7JYyiDw== X-Received: by 2002:aa7:df86:0:b0:413:2d4a:5358 with SMTP id b6-20020aa7df86000000b004132d4a5358mr24124938edy.21.1646139256245; Tue, 01 Mar 2022 04:54:16 -0800 (PST) X-Google-Smtp-Source: ABdhPJwTwDPxr0t5OXZKZn4omVPmGWva+cLJAsgpd3bvWw+4nTzlscQxhnOXRdO587tGCB/xOmz5+gdFNKg0Lw5jttw= X-Received: by 2002:aa7:df86:0:b0:413:2d4a:5358 with SMTP id b6-20020aa7df86000000b004132d4a5358mr24124926edy.21.1646139255887; Tue, 01 Mar 2022 04:54:15 -0800 (PST) MIME-Version: 1.0 Date: Tue, 1 Mar 2022 20:54:04 +0800 Message-ID: Subject: [PATCH] readelf: PR28928 - wrong dynamic section entry number To: elfutils-devel@sourceware.org X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-13.7 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, HEXHASH_WORD, HTML_MESSAGE, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H5, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-Content-Filtered-By: Mailman/MimeDel 2.1.29 X-BeenThere: elfutils-devel@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Elfutils-devel mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-Patchwork-Original-From: Di Chen via Elfutils-devel From: Di Chen Reply-To: Di Chen Errors-To: elfutils-devel-bounces+patchwork=sourceware.org@sourceware.org Sender: "Elfutils-devel" commit 978663c5323cf402cd35b8614e41f24b587cbdd8 (HEAD -> dichen/DT_NULL, origin/dichen/DT_NULL) Author: Di Chen Date: Tue Mar 1 20:44:38 2022 +0800 readelf: PR28928 - wrong dynamic section entry number when using `$ eu-readelf -d {file}` to get the number of dynamic section entris, It wrongly counts the padding DT_NULLs as dynamic section entries. However, DT_NULL Marks end of dynamic section. They should not be counted as dynamic section entries. https://sourceware.org/bugzilla/show_bug.cgi?id=28928 Signed-off-by: Di Chen PLTGOT 0x00000000000019c8 @@ -60,11 +60,6 @@ Dynamic segment contains 28 entries: VERNEED 0x0000000000000498 VERNEEDNUM 2 NULL - NULL - NULL - NULL - NULL - NULL EOF exit 0 Signed-off-by: Di Chen diff --git a/src/readelf.c b/src/readelf.c index 93fb5989..1bec3aa6 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -296,6 +296,7 @@ static void print_shdr (Ebl *ebl, GElf_Ehdr *ehdr); static void print_phdr (Ebl *ebl, GElf_Ehdr *ehdr); static void print_scngrp (Ebl *ebl); static void print_dynamic (Ebl *ebl); +static void handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr); static void print_relocs (Ebl *ebl, GElf_Ehdr *ehdr); static void handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr); @@ -1781,16 +1782,54 @@ print_dt_posflag_1 (int class, GElf_Xword d_val) [dichen@arpeggio elfutils]$ git format-patch -1 HEAD 0001-readelf-PR28928-wrong-dynamic-section-entry-number.patch [dichen@arpeggio elfutils]$ vim 0001-readelf-PR28928-wrong-dynamic-section-entry-number.patch [dichen@arpeggio elfutils]$ cat 0001-readelf-PR28928-wrong-dynamic-section-entry-number.patch From 978663c5323cf402cd35b8614e41f24b587cbdd8 Mon Sep 17 00:00:00 2001 From: Di Chen Date: Tue, 1 Mar 2022 20:44:38 +0800 Subject: [PATCH] readelf: PR28928 - wrong dynamic section entry number when using `$ eu-readelf -d {file}` to get the number of dynamic section entris, It wrongly counts the padding DT_NULLs as dynamic section entries. However, DT_NULL Marks end of dynamic section. They should not be counted as dynamic section entries. https://sourceware.org/bugzilla/show_bug.cgi?id=28928 Signed-off-by: Di Chen --- src/readelf.c | 49 ++++++++++++++++++++++++++++++++++++------ tests/alldts.c | 5 +++-- tests/run-alldts.sh | 2 +- tests/run-readelf-d.sh | 7 +----- 4 files changed, 48 insertions(+), 15 deletions(-) diff --git a/src/readelf.c b/src/readelf.c index 93fb5989..1bec3aa6 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -296,6 +296,7 @@ static void print_shdr (Ebl *ebl, GElf_Ehdr *ehdr); static void print_phdr (Ebl *ebl, GElf_Ehdr *ehdr); static void print_scngrp (Ebl *ebl); static void print_dynamic (Ebl *ebl); +static void handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr); static void print_relocs (Ebl *ebl, GElf_Ehdr *ehdr); static void handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr); @@ -1781,16 +1782,54 @@ print_dt_posflag_1 (int class, GElf_Xword d_val) } +static GElf_Phdr * +get_dyn_phdr (Elf *elf) +{ + GElf_Phdr *phdr = NULL; + for (size_t i = 0; i < phnum; ++i) { + GElf_Phdr phdr_mem; + phdr = gelf_getphdr(elf, i, &phdr_mem); + if (phdr->p_type == PT_DYNAMIC) { + break; + } + } + return phdr; +} + + +static size_t +get_dyn_scnents (Elf *elf, GElf_Phdr * dyn_phdr) +{ + Elf_Data *data = elf_getdata_rawchunk( + elf, dyn_phdr->p_offset, dyn_phdr->p_filesz, ELF_T_DYN); + GElf_Dyn *dyn; + size_t dyn_idx = 0; + do + { + GElf_Dyn dyn_mem; + dyn = gelf_getdyn(data, dyn_idx, &dyn_mem); + ++dyn_idx; + } while (dyn->d_tag != DT_NULL); + + return dyn_idx; +} + + static void handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) { int class = gelf_getclass (ebl->elf); + GElf_Phdr *dyn_phdr; GElf_Shdr glink_mem; GElf_Shdr *glink; Elf_Data *data; size_t cnt; size_t shstrndx; - size_t sh_entsize; + size_t dyn_scnents; + + /* Calculate the dynamic section entry number */ + dyn_phdr = get_dyn_phdr (ebl->elf); + dyn_scnents = get_dyn_scnents (ebl->elf, dyn_phdr); /* Get the data of the section. */ data = elf_getdata (scn, NULL); @@ -1802,8 +1841,6 @@ handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) error (EXIT_FAILURE, 0, _("cannot get section header string table index")); - sh_entsize = gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT); - glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem); if (glink == NULL) error (EXIT_FAILURE, 0, _("invalid sh_link value in section %zu"), @@ -1813,15 +1850,15 @@ handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) \nDynamic segment contains %lu entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", "\ \nDynamic segment contains %lu entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", - shdr->sh_size / sh_entsize), - (unsigned long int) (shdr->sh_size / sh_entsize), + dyn_scnents), + (unsigned long int) dyn_scnents, class == ELFCLASS32 ? 10 : 18, shdr->sh_addr, shdr->sh_offset, (int) shdr->sh_link, elf_strptr (ebl->elf, shstrndx, glink->sh_name)); fputs_unlocked (_(" Type Value\n"), stdout); - for (cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt) + for (cnt = 0; cnt < dyn_scnents; ++cnt) { GElf_Dyn dynmem; GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dynmem); diff --git a/tests/alldts.c b/tests/alldts.c index 3e9f9fe6..d0fe4f24 100644 --- a/tests/alldts.c +++ b/tests/alldts.c @@ -44,7 +44,7 @@ main (void) Dwelf_Strent *shstrtabse; const Elf32_Sword dtflags[] = { - DT_NULL, DT_NEEDED, DT_PLTRELSZ, DT_PLTGOT, + DT_NEEDED, DT_PLTRELSZ, DT_PLTGOT, DT_HASH, DT_STRTAB, DT_SYMTAB, DT_RELA, DT_RELASZ, DT_RELAENT, DT_STRSZ, DT_SYMENT, DT_INIT, DT_FINI, DT_SONAME, DT_RPATH, @@ -61,7 +61,8 @@ main (void) DT_GNU_LIBLIST, DT_CONFIG, DT_DEPAUDIT, DT_AUDIT, DT_PLTPAD, DT_MOVETAB, DT_SYMINFO, DT_RELACOUNT, DT_RELCOUNT, DT_FLAGS_1, DT_VERDEF, DT_VERDEFNUM, - DT_VERNEED, DT_VERNEEDNUM, DT_AUXILIARY, DT_FILTER + DT_VERNEED, DT_VERNEEDNUM, DT_AUXILIARY, DT_FILTER, + DT_NULL }; const int ndtflags = sizeof (dtflags) / sizeof (dtflags[0]); diff --git a/tests/run-alldts.sh b/tests/run-alldts.sh index 6a9a9ece..bd750a35 100755 --- a/tests/run-alldts.sh +++ b/tests/run-alldts.sh @@ -27,7 +27,6 @@ testrun_compare ${abs_top_builddir}/src/readelf -d testfile-alldts <<\EOF Dynamic segment contains 66 entries: Addr: 0x000001a0 Offset: 0x000078 Link to section: [ 0] '' Type Value - NULL NEEDED Shared library: [(null)] PLTRELSZ 3735928559 (bytes) PLTGOT 0xdeadbeef @@ -93,6 +92,7 @@ Dynamic segment contains 66 entries: VERNEEDNUM 3735928559 AUXILIARY 0xdeadbeef FILTER 0xdeadbeef + NULL EOF exit 0 diff --git a/tests/run-readelf-d.sh b/tests/run-readelf-d.sh index d0b6ed24..69b01c49 100755 --- a/tests/run-readelf-d.sh +++ b/tests/run-readelf-d.sh @@ -34,7 +34,7 @@ testfiles testlib_dynseg.so testrun_compare ${abs_top_builddir}/src/readelf -d testlib_dynseg.so <<\EOF -Dynamic segment contains 28 entries: +Dynamic segment contains 23 entries: Addr: 0x00000000000017e0 Offset: 0x0007e0 Link to section: [ 3] '.dynstr' Type Value