public inbox for elfutils@sourceware.org
 help / color / mirror / Atom feed
From: Mark Wielaard <mark@klomp.org>
To: Gavin Li <gavin@matician.com>
Cc: elfutils-devel@sourceware.org
Subject: Re: [PATCH] libdwfl: Read no more than required to parse dynamic sections
Date: Thu, 1 Dec 2022 00:14:41 +0100	[thread overview]
Message-ID: <Y4fj4W4nzSIw52Iw@wildebeest.org> (raw)
In-Reply-To: <CACB127+eBsXE49p+m6oE7Yb1u5gmfVPXgfuf+VNR5QDNqNZZog@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 467 bytes --]

Hi Gavin,

On Tue, Nov 29, 2022 at 01:48:42PM -0800, Gavin Li wrote:
> I think for the purposes of reading small segments (like PT_DYNAMIC
> and PT_NOTE), we should ignore *buffer_available altogether.

Thanks for walking me through the code. I think you are right and none
of the buffer_available checks are necessary. So I removed them all. I
also adjusted the commit message a bit. Could you look at this patch
and let me know if this works for you?

Cheers,

Mark

[-- Attachment #2: 0001-libdwfl-Read-no-more-than-required-in-dwfl_segment_r.patch --]
[-- Type: text/x-diff, Size: 3866 bytes --]

From 59f1b49c1a1163ebde891196c1b24e3f4225915b Mon Sep 17 00:00:00 2001
From: Gavin Li <gavin@matician.com>
Date: Wed, 30 Nov 2022 18:26:19 +0100
Subject: [PATCH] libdwfl: Read no more than required in
 dwfl_segment_report_module

Since read_portion and the standard dwfl_elf_phdr_memory_callback
functions make sure to read at least minread bytes there is no need
for dwfl_segment_report_module to check and adjust the data to the
actual buffer size read. Reading beyond the end of the expected data
size (if the buffer read is much larger) actually causes issues when
passing the data to elfXX_xlatetom() because it is possible that
src->d_size is not a multiple of recsize (for ELF_T_DYN, recsize is 16
while the minimum required alignment is 8), causing elfXX_xlatetom()
to return ELF_E_INVALID_DATA.

Signed-off-by: Gavin Li <gavin@matician.com>
Signed-off-by: Mark Wielaard <mark@klomp.org>
---
 libdwfl/ChangeLog                    |  6 ++++++
 libdwfl/dwfl_segment_report_module.c | 28 +++-------------------------
 2 files changed, 9 insertions(+), 25 deletions(-)

diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 6dd84a6f..68527327 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,9 @@
+2022-11-28  Gavin Li  <gavin@matician.com>
+	    Mark Wielaard  <mark@klomp.org>
+
+	* dwfl_segment_report_module.c (dwfl_segment_report_module): Remove
+	data size check after read_portion memory_callback.
+
 2022-10-21  Yonggang Luo  <luoyonggang@gmail.com>
 
 	* argp-std.c: Don't include unistd.h.
diff --git a/libdwfl/dwfl_segment_report_module.c b/libdwfl/dwfl_segment_report_module.c
index 287fc002..6a7b77f0 100644
--- a/libdwfl/dwfl_segment_report_module.c
+++ b/libdwfl/dwfl_segment_report_module.c
@@ -441,18 +441,8 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
 		    start + phoff, xlatefrom.d_size))
     goto out;
 
-  /* ph_buffer_size will be zero if we got everything from the initial
-     buffer, otherwise it will be the size of the new buffer that
-     could be read.  */
-  if (ph_buffer_size != 0)
-    {
-      phnum = ph_buffer_size / phentsize;
-      if (phnum == 0)
-	goto out;
-      xlatefrom.d_size = ph_buffer_size;
-    }
-
   xlatefrom.d_buf = ph_buffer;
+  xlatefrom.d_size = xlatefrom.d_size;
 
   bool class32 = ei_class == ELFCLASS32;
   size_t phdr_size = class32 ? sizeof (Elf32_Phdr) : sizeof (Elf64_Phdr);
@@ -533,18 +523,12 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
               /* We calculate from the p_offset of the note segment,
                because we don't yet know the bias for its p_vaddr.  */
               const GElf_Addr note_vaddr = start + offset;
-              void *data;
-              size_t data_size;
+              void *data = NULL;
+              size_t data_size = 0;
               if (read_portion (&read_state, &data, &data_size,
 				start, segment, note_vaddr, filesz))
                 continue; /* Next header */
 
-              /* data_size will be zero if we got everything from the initial
-                 buffer, otherwise it will be the size of the new buffer that
-                 could be read.  */
-              if (data_size != 0)
-                filesz = data_size;
-
 	      if (filesz > SIZE_MAX / sizeof (Elf32_Nhdr))
 		continue;
 
@@ -821,12 +805,6 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
       && ! read_portion (&read_state, &dyn_data, &dyn_data_size,
 			 start, segment, dyn_vaddr, dyn_filesz))
     {
-      /* dyn_data_size will be zero if we got everything from the initial
-         buffer, otherwise it will be the size of the new buffer that
-         could be read.  */
-      if (dyn_data_size != 0)
-	dyn_filesz = dyn_data_size;
-
       if ((dyn_filesz / dyn_entsize) == 0
 	  || dyn_filesz > (SIZE_MAX / dyn_entsize))
 	goto out;
-- 
2.30.2


  reply	other threads:[~2022-11-30 23:14 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-29  6:26 gavin
2022-11-29 15:25 ` Mark Wielaard
2022-11-29 21:48   ` Gavin Li
2022-11-30 23:14     ` Mark Wielaard [this message]
2022-12-01 21:13       ` Gavin Li
2022-12-13 16:49         ` Mark Wielaard

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Y4fj4W4nzSIw52Iw@wildebeest.org \
    --to=mark@klomp.org \
    --cc=elfutils-devel@sourceware.org \
    --cc=gavin@matician.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).