libelf: Correctly setup alignment of SHF_COMPRESSED section data.
authorMark Wielaard <mark@klomp.org>
Tue, 13 Nov 2018 20:18:09 +0000 (21:18 +0100)
committerMark Wielaard <mark@klomp.org>
Tue, 13 Nov 2018 20:30:17 +0000 (21:30 +0100)
We didn't set the alignment of SHF_COMPRESSED sections correctly.
Those sections start with an Elf(32|64)_Chdr. Make sure sh_addralign
is setup to be able to read such a struct directly. Likewise don't
trust the alignment set on any SHF_COMPRESSED section, but always
make the (raw) compressed data aligned correctly for the reading the
Elf(32|64)_Chdr directly.

Signed-off-by: Mark Wielaard <mark@klomp.org>
libelf/ChangeLog
libelf/elf_compress.c
libelf/elf_getdata.c

index ab078cb..93820d1 100644 (file)
@@ -1,3 +1,10 @@
+2018-11-13  Mark Wielaard  <mark@klomp.org>
+
+       * elf_getdata.c (__libelf_set_rawdata_wrlock): Explicitly set the
+       alignment of SHF_COMPRESSED data to the alignment of ELF_T_CHDR.
+       * elf_compress.c (elf_compress): After compression set sh_addralign
+       to the alignment of ELF_T_CHDR.
+
 2018-11-09  Mark Wielaard  <mark@klomp.org>
 
        * elf_compress_gnu.c (elf_compress_gnu): Use elf_getdata.
index d96245d..be9eeab 100644 (file)
@@ -455,14 +455,14 @@ elf_compress (Elf_Scn *scn, int type, unsigned int flags)
        {
          Elf32_Shdr *shdr = elf32_getshdr (scn);
          shdr->sh_size = new_size;
-         shdr->sh_addralign = 1;
+         shdr->sh_addralign = __libelf_type_align (ELFCLASS32, ELF_T_CHDR);
          shdr->sh_flags |= SHF_COMPRESSED;
        }
       else
        {
          Elf64_Shdr *shdr = elf64_getshdr (scn);
          shdr->sh_size = new_size;
-         shdr->sh_addralign = 1;
+         shdr->sh_addralign = __libelf_type_align (ELFCLASS64, ELF_T_CHDR);
          shdr->sh_flags |= SHF_COMPRESSED;
        }
 
index 2043bba..639a798 100644 (file)
@@ -268,9 +268,15 @@ __libelf_set_rawdata_wrlock (Elf_Scn *scn)
       /* First a test whether the section is valid at all.  */
       size_t entsize;
 
-      /* Compressed data has a header, but then compressed data.  */
+      /* Compressed data has a header, but then compressed data.
+        Make sure to set the alignment of the header explicitly,
+        don't trust the file alignment for the section, it is
+        often wrong.  */
       if ((flags & SHF_COMPRESSED) != 0)
-       entsize = 1;
+       {
+         entsize = 1;
+         align = __libelf_type_align (elf->class, ELF_T_CHDR);
+       }
       else if (type == SHT_HASH)
        {
          GElf_Ehdr ehdr_mem;