libelf: Correct alignment of ELF_T_GNUHASH data for ELFCLASS64

Message ID 20220323002735.208471-1-mark@klomp.org
State Committed
Headers
Series libelf: Correct alignment of ELF_T_GNUHASH data for ELFCLASS64 |

Commit Message

Mark Wielaard March 23, 2022, 12:27 a.m. UTC
  ELF_T_GNUHASH data is just 32bit words for ELFCLASS32. But for
ELFCLASS64 it is a mix of 32bit and 64bit words. In the
elf_cvt_gnuhash function we rely on the alignment of the whole to be
64bit word aligned, even though the first 4 words are
32bits. Otherwise we might try to convert an unaligned 64bit word.

Signed-off-by: Mark Wielaard <mark@klomp.org>
---
 libelf/ChangeLog     |  5 +++++
 libelf/elf_getdata.c | 16 ++++++++++------
 2 files changed, 15 insertions(+), 6 deletions(-)
  

Patch

diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index ea204e2b..5ea1e41e 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,3 +1,8 @@ 
+2022-03-22  Mark Wielaard  <mark@klomp.org>
+
+	* elf_getdata.c (__libelf_type_aligns): ELF_T_GNUHASH has different
+	alignment for ELFCLASS32 and ELFCLASS64.
+
 2022-03-20  Mark Wielaard  <mark@klomp.org>
 
 	* version_xlate.h (elf_cvt_Verdef): Make sure aux_offset and
diff --git a/libelf/elf_getdata.c b/libelf/elf_getdata.c
index 475c6ded..a704aae3 100644
--- a/libelf/elf_getdata.c
+++ b/libelf/elf_getdata.c
@@ -1,5 +1,6 @@ 
 /* Return the next data element from the section after possibly converting it.
    Copyright (C) 1998-2005, 2006, 2007, 2015, 2016 Red Hat, Inc.
+   Copyright (C) 2022 Mark J. Wielaard <mark@klomp.org>
    This file is part of elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 1998.
 
@@ -77,7 +78,6 @@  static const Elf_Type shtype_map[TYPEIDX (SHT_HISUNW) + 1] =
 const uint_fast8_t __libelf_type_aligns[ELFCLASSNUM - 1][ELF_T_NUM] =
   {
 # define TYPE_ALIGNS(Bits)						      \
-    {									      \
       [ELF_T_ADDR] = __alignof__ (ElfW2(Bits,Addr)),			      \
       [ELF_T_EHDR] = __alignof__ (ElfW2(Bits,Ehdr)),			      \
       [ELF_T_HALF] = __alignof__ (ElfW2(Bits,Half)),			      \
@@ -100,13 +100,17 @@  const uint_fast8_t __libelf_type_aligns[ELFCLASSNUM - 1][ELF_T_NUM] =
       [ELF_T_MOVE] = __alignof__ (ElfW2(Bits,Move)),			      \
       [ELF_T_LIB] = __alignof__ (ElfW2(Bits,Lib)),			      \
       [ELF_T_NHDR] = __alignof__ (ElfW2(Bits,Nhdr)),			      \
-      [ELF_T_GNUHASH] = __alignof__ (Elf32_Word),			      \
       [ELF_T_AUXV] = __alignof__ (ElfW2(Bits,auxv_t)),			      \
       [ELF_T_CHDR] = __alignof__ (ElfW2(Bits,Chdr)),			      \
-      [ELF_T_NHDR8] = 8 /* Special case for GNU Property note.  */	      \
-    }
-      [ELFCLASS32 - 1] = TYPE_ALIGNS (32),
-      [ELFCLASS64 - 1] = TYPE_ALIGNS (64),
+      [ELF_T_NHDR8] = 8 /* Special case for GNU Property note.  */
+    [ELFCLASS32 - 1] =  {
+	TYPE_ALIGNS (32),
+	[ELF_T_GNUHASH] = __alignof__ (Elf32_Word),
+    },
+    [ELFCLASS64 - 1] = {
+	TYPE_ALIGNS (64),
+	[ELF_T_GNUHASH] = __alignof__ (Elf64_Xword),
+    },
 # undef TYPE_ALIGNS
   };