]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
libelf: Always call ftruncate before posix_fallocate to set the right size.
authorMark Wielaard <mjw@redhat.com>
Tue, 16 Jun 2015 12:05:35 +0000 (14:05 +0200)
committerMark Wielaard <mjw@redhat.com>
Fri, 19 Jun 2015 10:16:41 +0000 (12:16 +0200)
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>
libelf/ChangeLog
libelf/elf_update.c
tests/ChangeLog
tests/run-strip-test.sh

index 30017cd7a46672cd4ef5c20cb2f910aeb8f8f661..2d2400748d32924738e09868d89733d846c96894 100644 (file)
@@ -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,
index 9e34c4662230f7897424a74450905d15afd64671..9eb007bde30e103dbc9a509de04a7c39cb62c89d 100644 (file)
@@ -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);
index 19878ac464edae754985606eedc61a58897467ab..34f89cc4bd8e6bf6d673e33457865bb3f0411dd3 100644 (file)
@@ -1,3 +1,8 @@
+2015-06-16  Mark Wielaard  <mjw@redhat.com>
+
+       * run-strip-test.sh: Add strip-in-place (eu-strip without -o) test
+       for non-ET_REL files.
+
 2015-05-30  Mark Wielaard  <mjw@redhat.com>
 
        * backtrace-subr.sh (check_native_core): Notice core file couldn't be
index c558e90b5911b6d188364fc50c428aac31c6ea14..2ebb5a91ad2896756c2a801545eff24eeede0383 100755 (executable)
@@ -49,6 +49,19 @@ testrun ${abs_top_builddir}/src/unstrip -o testfile.unstrip testfile.temp testfi
 testrun ${abs_top_builddir}/src/elfcmp --hash-inexact $original testfile.unstrip
 }
 
+# Now strip in-place and make sure it is smaller.
+# Skip ET_REL files, they might have unexpected symbol table entries.
+is_ET_REL=0
+testrun ${abs_top_builddir}/src/readelf -h $original 2>&1 \
+  | fgrep 'REL (Relocatable file)' && is_ET_REL=1
+if test $is_ET_REL -eq 0; then
+  SIZE_original=$(stat -c%s $original)
+  testrun ${abs_top_builddir}/src/strip $original
+  SIZE_stripped=$(stat -c%s $original)
+  test $SIZE_stripped -lt $SIZE_original ||
+    { echo "*** failure in-place strip file not smaller $original"; status=1; }
+fi
+
 tempfiles testfile.sections
 testrun ${abs_top_builddir}/src/readelf -S testfile.temp > testfile.sections || status=$?
 fgrep ' .debug_' testfile.sections && status=1