summaryrefslogtreecommitdiffstats
path: root/libelf
diff options
context:
space:
mode:
Diffstat (limited to 'libelf')
-rw-r--r--libelf/ChangeLog7
-rw-r--r--libelf/elf32_updatenull.c5
-rw-r--r--libelf/elf_getdata.c14
3 files changed, 26 insertions, 0 deletions
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index a7983a0a..0b9b4781 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,5 +1,12 @@
2015-05-12 Mark Wielaard <mjw@redhat.com>
+ * elf32_updatenull.c (updatenull_wrlock): Check that sh_addralign
+ is a powerof2.
+ * elf_getdata.c (__libelf_set_rawdata_wrlock): Clamp large d_aligns
+ to the elf image offset.
+
+2015-05-12 Mark Wielaard <mjw@redhat.com>
+
* elf32_newphdr.c (newphdr): Call __libelf_seterrno with
ELF_E_INVALID_INDEX before failing. Check whether section zero shdr
actually exists if we need to put extended phnum in section zero.
diff --git a/libelf/elf32_updatenull.c b/libelf/elf32_updatenull.c
index d873a309..a0de80e1 100644
--- a/libelf/elf32_updatenull.c
+++ b/libelf/elf32_updatenull.c
@@ -202,6 +202,11 @@ __elfw2(LIBELFBITS,updatenull_wrlock) (Elf *elf, int *change_bop, size_t shnum)
assert (shdr != NULL);
ElfW2(LIBELFBITS,Word) sh_entsize = shdr->sh_entsize;
ElfW2(LIBELFBITS,Word) sh_align = shdr->sh_addralign ?: 1;
+ if (unlikely (! powerof2 (sh_align)))
+ {
+ __libelf_seterrno (ELF_E_INVALID_ALIGN);
+ return -1;
+ }
/* Set the sh_entsize value if we can reliably detect it. */
switch (shdr->sh_type)
diff --git a/libelf/elf_getdata.c b/libelf/elf_getdata.c
index e8f022f9..8567da1e 100644
--- a/libelf/elf_getdata.c
+++ b/libelf/elf_getdata.c
@@ -301,6 +301,20 @@ __libelf_set_rawdata_wrlock (Elf_Scn *scn)
else
scn->rawdata.d.d_type = shtype_map[LIBELF_EV_IDX][TYPEIDX (type)];
scn->rawdata.d.d_off = 0;
+
+ /* Make sure the alignment makes sense. d_align should be aligned both
+ in the section (trivially true since d_off is zero) and in the file.
+ Unfortunately we cannot be too strict because there are ELF files
+ out there that fail this requirement. We will try to fix those up
+ in elf_update when writing out the image. But for very large
+ alignment values this can bloat the image considerably. So here
+ just check and clamp the alignment value to not be bigger than the
+ actual offset of the data in the file. Given that there is always
+ at least an ehdr this will only trigger for alignment values > 64
+ which should be uncommon. */
+ align = align ?: 1;
+ if (align > offset)
+ align = offset;
scn->rawdata.d.d_align = align;
if (elf->class == ELFCLASS32
|| (offsetof (struct Elf, state.elf32.ehdr)