public inbox for elfutils@sourceware.org
 help / color / mirror / Atom feed
From: Mark Wielaard <mark@klomp.org>
To: elfutils-devel@sourceware.org
Cc: Mark Wielaard <mark@klomp.org>
Subject: [PATCH] libelf: Don't overflow offsets in elf_cvt_Verneed and elf_cvt_Verdef
Date: Sun, 20 Mar 2022 22:29:40 +0100	[thread overview]
Message-ID: <20220320212940.155193-1-mark@klomp.org> (raw)

The conversion functions for Verdef and Verneed keep offsets to the next
structure. Make sure that following vd_aux, vda_next, vd_next, vn_aux,
vna_next and vn_next don't overflow (and wrap around) the offsets.

Signed-off-by: Mark Wielaard <mark@klomp.org>
---
 libelf/ChangeLog       |  7 ++++++
 libelf/version_xlate.h | 56 ++++++++++++++++++++++++++++++++++++------
 2 files changed, 55 insertions(+), 8 deletions(-)

diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index f6b47c68..ea204e2b 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,3 +1,10 @@
+2022-03-20  Mark Wielaard  <mark@klomp.org>
+
+	* version_xlate.h (elf_cvt_Verdef): Make sure aux_offset and
+	def_offset don't overflow.
+	(elf_cvt_Verneed): Make sure aux_offset and need_offset don't
+	overflow.
+
 2022-03-18  Mark Wielaard  <mark@klomp.org>
 
 	* version_xlate.h (elf_cvt_Verdef): Check alignment of def_offset
diff --git a/libelf/version_xlate.h b/libelf/version_xlate.h
index b7bd301d..97f3b730 100644
--- a/libelf/version_xlate.h
+++ b/libelf/version_xlate.h
@@ -87,10 +87,16 @@ elf_cvt_Verdef (void *dest, const void *src, size_t len, int encode)
 	  ddest->vd_aux = bswap_32 (dsrc->vd_aux);
 	  ddest->vd_next = bswap_32 (dsrc->vd_next);
 
+	  if (ddest->vd_aux > len - def_offset)
+	    return;
 	  aux_offset = def_offset + ddest->vd_aux;
 	}
       else
-	aux_offset = def_offset + dsrc->vd_aux;
+	{
+	  if (dsrc->vd_aux > len - def_offset)
+	    return;
+	  aux_offset = def_offset + dsrc->vd_aux;
+	}
 
       /* Handle all the auxiliary records belonging to this definition.  */
       do
@@ -107,19 +113,29 @@ elf_cvt_Verdef (void *dest, const void *src, size_t len, int encode)
 	  asrc = (GElf_Verdaux *) ((char *) src + aux_offset);
 
 	  if (encode)
-	    aux_offset += asrc->vda_next;
+	    {
+	      if (asrc->vda_next > len - aux_offset)
+		return;
+	      aux_offset += asrc->vda_next;
+	    }
 
 	  adest->vda_name = bswap_32 (asrc->vda_name);
 	  adest->vda_next = bswap_32 (asrc->vda_next);
 
 	  if (! encode)
-	    aux_offset += adest->vda_next;
+	    {
+	      if (adest->vda_next > len - aux_offset)
+		return;
+	      aux_offset += adest->vda_next;
+	    }
 	}
       while (asrc->vda_next != 0);
 
       /* Encode now if necessary.  */
       if (encode)
 	{
+	  if (dsrc->vd_next > len - def_offset)
+	    return;
 	  def_offset += dsrc->vd_next;
 
 	  ddest->vd_version = bswap_16 (dsrc->vd_version);
@@ -131,7 +147,11 @@ elf_cvt_Verdef (void *dest, const void *src, size_t len, int encode)
 	  ddest->vd_next = bswap_32 (dsrc->vd_next);
 	}
       else
-	def_offset += ddest->vd_next;
+	{
+	  if (ddest->vd_next > len - def_offset)
+	    return;
+	  def_offset += ddest->vd_next;
+	}
     }
   while (dsrc->vd_next != 0);
 }
@@ -188,10 +208,16 @@ elf_cvt_Verneed (void *dest, const void *src, size_t len, int encode)
 	  ndest->vn_aux = bswap_32 (nsrc->vn_aux);
 	  ndest->vn_next = bswap_32 (nsrc->vn_next);
 
+	  if (ndest->vn_aux > len - need_offset)
+	    return;
 	  aux_offset = need_offset + ndest->vn_aux;
 	}
       else
-	aux_offset = need_offset + nsrc->vn_aux;
+	{
+	  if (nsrc->vn_aux > len - need_offset)
+	    return;
+	  aux_offset = need_offset + nsrc->vn_aux;
+	}
 
       /* Handle all the auxiliary records belonging to this requirement.  */
       do
@@ -208,7 +234,11 @@ elf_cvt_Verneed (void *dest, const void *src, size_t len, int encode)
 	  asrc = (GElf_Vernaux *) ((char *) src + aux_offset);
 
 	  if (encode)
-	    aux_offset += asrc->vna_next;
+	    {
+	      if (asrc->vna_next > len - aux_offset)
+		return;
+	      aux_offset += asrc->vna_next;
+	    }
 
 	  adest->vna_hash = bswap_32 (asrc->vna_hash);
 	  adest->vna_flags = bswap_16 (asrc->vna_flags);
@@ -217,13 +247,19 @@ elf_cvt_Verneed (void *dest, const void *src, size_t len, int encode)
 	  adest->vna_next = bswap_32 (asrc->vna_next);
 
 	  if (! encode)
-	    aux_offset += adest->vna_next;
+	    {
+	      if (adest->vna_next > len - aux_offset)
+		return;
+	      aux_offset += adest->vna_next;
+	    }
 	}
       while (asrc->vna_next != 0);
 
       /* Encode now if necessary.  */
       if (encode)
 	{
+	  if (nsrc->vn_next > len - need_offset)
+	    return;
 	  need_offset += nsrc->vn_next;
 
 	  ndest->vn_version = bswap_16 (nsrc->vn_version);
@@ -233,7 +269,11 @@ elf_cvt_Verneed (void *dest, const void *src, size_t len, int encode)
 	  ndest->vn_next = bswap_32 (nsrc->vn_next);
 	}
       else
-	need_offset += ndest->vn_next;
+	{
+	  if (ndest->vn_next > len - need_offset)
+	    return;
+	  need_offset += ndest->vn_next;
+	}
     }
   while (nsrc->vn_next != 0);
 }
-- 
2.30.2


                 reply	other threads:[~2022-03-20 21:32 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=20220320212940.155193-1-mark@klomp.org \
    --to=mark@klomp.org \
    --cc=elfutils-devel@sourceware.org \
    /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).