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 <m...@klomp.org> --- libelf/ChangeLog | 5 +++++ libelf/elf_getdata.c | 16 ++++++++++------ 2 files changed, 15 insertions(+), 6 deletions(-) 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 <m...@klomp.org> + + * elf_getdata.c (__libelf_type_aligns): ELF_T_GNUHASH has different + alignment for ELFCLASS32 and ELFCLASS64. + 2022-03-20 Mark Wielaard <m...@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 <m...@klomp.org> This file is part of elfutils. Written by Ulrich Drepper <drep...@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 }; -- 2.30.2