[PATCH] libelf: Make sure conversion functions work on aligned data for type.

Mark Wielaard mjw at redhat.com
Wed Jun 3 16:54:36 UTC 2015


The gelf_xlate conversion functions work on properly aligned ELF data
types.  If elf_get data needs to do conversion and ! ALLOW_UNALIGNED
and the rawdata_base isn't aligned properly for the section type, then
provide an aligned copy of the data.

Found with --enable-sanitize-undefined  in run-test-archive64.sh on x86_64.

Signed-off-by: Mark Wielaard <mjw at redhat.com>
---
 libelf/ChangeLog     |  5 +++++
 libelf/elf_getdata.c | 26 ++++++++++++++++++++++++--
 2 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index fd2fc53..c57c6a2 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,5 +1,10 @@
 2015-06-02  Mark Wielaard  <mjw at redhat.com>
 
+	* elf_getdata.c (convert_data): Make sure source data is properly
+	aligned for type before calling actual conversion function.
+
+2015-06-02  Mark Wielaard  <mjw at redhat.com>
+
 	* elf_begin.c (file_read_elf): Split checks for ehdr and shdr
 	alignment, drop phdr alignment check.
 
diff --git a/libelf/elf_getdata.c b/libelf/elf_getdata.c
index 8567da1..1a4981e 100644
--- a/libelf/elf_getdata.c
+++ b/libelf/elf_getdata.c
@@ -1,5 +1,5 @@
 /* Return the next data element from the section after possibly converting it.
-   Copyright (C) 1998-2005, 2006, 2007 Red Hat, Inc.
+   Copyright (C) 1998-2005, 2006, 2007, 2015 Red Hat, Inc.
    This file is part of elfutils.
    Written by Ulrich Drepper <drepper at redhat.com>, 1998.
 
@@ -144,6 +144,25 @@ convert_data (Elf_Scn *scn, int version __attribute__ ((unused)), int eclass,
 	  return;
 	}
 
+      /* Make sure the source is correctly aligned for the conversion
+	 function to directly access the data elements.  */
+      char *rawdata_source;
+      if (ALLOW_UNALIGNED ||
+	  ((((size_t) (char *) scn->rawdata_base)) & (align - 1)) == 0)
+	rawdata_source = scn->rawdata_base;
+      else
+	{
+	  rawdata_source = (char *) malloc (size);
+	  if (rawdata_source == NULL)
+	    {
+	      __libelf_seterrno (ELF_E_NOMEM);
+	      return;
+	    }
+
+	  /* The copy will be appropriately aligned for direct access.  */
+	  memcpy (rawdata_source, scn->rawdata_base, size);
+	}
+
       /* Get the conversion function.  */
 #if EV_NUM != 2
       fp = __elf_xfctstom[version - 1][__libelf_version - 1][eclass - 1][type];
@@ -151,7 +170,10 @@ convert_data (Elf_Scn *scn, int version __attribute__ ((unused)), int eclass,
       fp = __elf_xfctstom[0][0][eclass - 1][type];
 #endif
 
-      fp (scn->data_base, scn->rawdata_base, size, 0);
+      fp (scn->data_base, rawdata_source, size, 0);
+
+      if (rawdata_source != scn->rawdata_base)
+	free (rawdata_source);
     }
 
   scn->data_list.data.d.d_buf = scn->data_base;
-- 
2.1.0



More information about the elfutils-devel mailing list