summaryrefslogtreecommitdiffstats
path: root/libelf
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2015-06-16 14:05:35 +0200
committerMark Wielaard <mjw@redhat.com>2015-06-19 12:16:41 +0200
commit0d01165e665fd51da69de1aebed64fdb5b5f04e1 (patch)
tree2d80eacca5fff97203a8320402b0b4297e45e957 /libelf
parente7a69d5d353e2366260c3b4e1f72978532167619 (diff)
downloadandroid_external_elfutils-0d01165e665fd51da69de1aebed64fdb5b5f04e1.tar.gz
android_external_elfutils-0d01165e665fd51da69de1aebed64fdb5b5f04e1.tar.bz2
android_external_elfutils-0d01165e665fd51da69de1aebed64fdb5b5f04e1.zip
libelf: Always call ftruncate before posix_fallocate to set the right size.
When elf_update.c (write_file) doesn't know the current maximum file length it might have to reduce the file size. posix_fallocate can only extend the file. So always call ftruncate before that to set the file size and making sure the backing store is fully there. Add test cases for checking strip in place (eu-strip without -o) actually reduces the file size. But only for non-ET_REL files. We might not be able to strip ET_REL files (except when they are kernel modules) because they might contain "dangling" symbol table entries. https://bugzilla.redhat.com/show_bug.cgi?id=1232206 Signed-off-by: Mark Wielaard <mjw@redhat.com>
Diffstat (limited to 'libelf')
-rw-r--r--libelf/ChangeLog5
-rw-r--r--libelf/elf_update.c7
2 files changed, 10 insertions, 2 deletions
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index 30017cd7..2d240074 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,3 +1,8 @@
+2015-06-16 Mark Wielaard <mjw@redhat.com>
+
+ * elf_update.c (write_file): Always also use ftruncate before
+ posix_fallocate to make sure file has the right size.
+
2015-06-04 Mark Wielaard <mjw@redhat.com>
* elf_getdata.c (__libelf_type_aligns): Add entries for ELF_T_EHDR,
diff --git a/libelf/elf_update.c b/libelf/elf_update.c
index 9e34c466..9eb007bd 100644
--- a/libelf/elf_update.c
+++ b/libelf/elf_update.c
@@ -60,15 +60,18 @@ write_file (Elf *elf, off_t size, int change_bo, size_t shnum)
new file. We truncate the file later in this case.
Note we use posix_fallocate to make sure the file content is really
- there. Using ftruncate might mean the file is extended, but space
+ there. Only using ftruncate might mean the file is extended, but space
isn't allocated yet. This might cause a SIGBUS once we write into
the mmapped space and the disk is full. Using fallocate might fail
on some file systems. posix_fallocate is required to extend the file
and allocate enough space even if the underlying filesystem would
- normally return EOPNOTSUPP. */
+ normally return EOPNOTSUPP. Note that we do also need to ftruncate
+ in case the maximum_size isn't known and the file needs to be shorter
+ because posix_fallocate can only extend. */
if (elf->parent == NULL
&& (elf->maximum_size == ~((size_t) 0)
|| (size_t) size > elf->maximum_size)
+ && unlikely (ftruncate (elf->fildes, size) != 0)
&& unlikely (posix_fallocate (elf->fildes, 0, size) != 0))
{
__libelf_seterrno (ELF_E_WRITE_ERROR);