File 0001-libelf-Fixup-SHF_COMPRESSED-sh_addralign-in-elf_upda.patch of Package elfutils.28668
From 55c5c9a568ed707bcea1388bf3a525212d8cf4b8 Mon Sep 17 00:00:00 2001
From: Mark Wielaard <mark@klomp.org>
Date: Wed, 19 Aug 2020 23:41:24 +0200
Subject: [PATCH] libelf: Fixup SHF_COMPRESSED sh_addralign in elf_update if
necessary.
In elf_getdata.c we have the following to compensate for possibly
bad sh_addralign values of compressed sections:
/* 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;
align = __libelf_type_align (elf->class, ELF_T_CHDR);
}
Which makes sure the d_data alignment is correct for the Chdr struct
at the start of the compressed section.
But this means that if a user just reads such a compressed section
without changing it, and then tries to write it out again using
elf_update they get an error message about d_align and sh_addralign
being out of sync.
We already correct obviously incorrect sh_entsize fields.
Do the same for the sh_addralign field of a SHF_COMPRESSED section.
Signed-off-by: Mark Wielaard <mark@klomp.org>
---
libelf/ChangeLog | 5 +++++
libelf/elf32_updatenull.c | 12 ++++++++++++
2 files changed, 17 insertions(+)
Index: elfutils-0.177/libelf/elf32_updatenull.c
===================================================================
--- elfutils-0.177.orig/libelf/elf32_updatenull.c
+++ elfutils-0.177/libelf/elf32_updatenull.c
@@ -267,6 +267,18 @@ __elfw2(LIBELFBITS,updatenull_wrlock) (E
update_if_changed (shdr->sh_entsize, sh_entsize,
scn->shdr_flags);
+ /* Likewise for the alignment of a compressed section.
+ For a SHF_COMPRESSED section set the correct
+ sh_addralign value, which must match the d_align of
+ the data (see __libelf_set_rawdata in elf_getdata.c). */
+ if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
+ {
+ sh_align = __libelf_type_align (ELFW(ELFCLASS,LIBELFBITS),
+ ELF_T_CHDR);
+ update_if_changed (shdr->sh_addralign, sh_align,
+ scn->shdr_flags);
+ }
+
if (scn->data_read == 0
&& __libelf_set_rawdata_wrlock (scn) != 0)
/* Something went wrong. The error value is already set. */