[PATCH] libelf: Get alignement correct when calling conversion functions.
When writing out data that needs to be converted we have to make sure the conversion function is called on correctly aligned buffers. When using mmap this might mean we have to convert into a temporarily buffer if the user wants to write out the section at a location that is not correctly aligned for the section type. Older gas would generate misaligned ELF notes for the .version directive. When copying over such notes using mmap from files with a different endianness using mmap we would get the alignment of the conversion destination wrong. The new testcase would fail with configure --enable-sanitize-undefined on little endian systems. The GCC undefinited sanitizer caught a similar issue with testfile1 on big endian systems. gelf_xlate.h:47:1: runtime error: member access within misaligned address 0x7f8145d770d5 for type 'struct Elf32_Nhdr', which requires 4 byte alignment Signed-off-by: Mark Wielaard --- libelf/ChangeLog | 5 libelf/elf32_updatefile.c | 36 tests/ChangeLog| 7 ++ tests/Makefile.am | 6 +++-- tests/run-strip-version.sh | 58 + tests/testfile-version.bz2 | Bin 0 -> 378 bytes 6 files changed, 105 insertions(+), 7 deletions(-) create mode 100755 tests/run-strip-version.sh create mode 100755 tests/testfile-version.bz2 diff --git a/libelf/ChangeLog b/libelf/ChangeLog index 68c4fbd..5923c85 100644 --- a/libelf/ChangeLog +++ b/libelf/ChangeLog @@ -1,3 +1,8 @@ +2018-11-17 Mark Wielaard + + * elf32_updatefile.c (updatemmap): Make sure to call convert + function on a properly aligned destination. + 2018-11-16 Mark Wielaard * libebl.h (__elf32_msize): Mark with const attribute. diff --git a/libelf/elf32_updatefile.c b/libelf/elf32_updatefile.c index f2e9a28..284bacc 100644 --- a/libelf/elf32_updatefile.c +++ b/libelf/elf32_updatefile.c @@ -1,5 +1,5 @@ /* Write changed data structures. - Copyright (C) 2000-2010, 2014, 2015, 2016 Red Hat, Inc. + Copyright (C) 2000-2010, 2014, 2015, 2016, 2018 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper , 2000. @@ -354,7 +354,9 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum) user's section data with the latest one, rather than crashing. */ - if (unlikely (change_bo)) + if (unlikely (change_bo + && dl->data.d.d_size != 0 + && dl->data.d.d_type != ELF_T_BYTE)) { #if EV_NUM != 2 xfct_t fctp; @@ -364,9 +366,33 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum) # define fctp __elf_xfctstom[0][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][dl->data.d.d_type] #endif - /* Do the real work. */ - (*fctp) (last_position, dl->data.d.d_buf, -dl->data.d.d_size, 1); + size_t align; + align = __libelf_type_align (ELFW(ELFCLASS,LIBELFBITS), +dl->data.d.d_type); + if uintptr_t) last_position) +& (uintptr_t) (align - 1)) == 0) + { + /* No need to copy, we can convert directly. */ + (*fctp) (last_position, dl->data.d.d_buf, +dl->data.d.d_size, 1); + } + else + { + /* We have to do the conversion on properly + aligned memory first. */ + size_t size = dl->data.d.d_size; + char *converted = aligned_alloc (align, size); + if (converted == NULL) + { + __libelf_seterrno (ELF_E_NOMEM); + return 1; + } +(*fctp) (converted, dl->data.d.d_buf, size, 1); + + /* And then write it to the mmapped file. */ + memcpy (last_position, converted, size); + free (converted); + } last_position += dl->data.d.d_size; } diff --git a/tests/ChangeLog b/tests/ChangeLog index 514229b..08358d2 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,10 @@ +2018-11-17 Mark Wielaard + + * run-strip-version.sh: New test. + * testfile-version.bz2: New test file. + * Makefile.am (TESTS): Add run-strip-version.sh. + (EXTRA_DIST): Add run-strip-version.sh and testfile-version.bz2. + 2018-11-09 Mark Wielaard * ru
Re: elfutils 0.175 released
On Fri, Nov 16, 2018 at 02:00:46PM +0100, Mark Wielaard wrote: > ELFUTILS 0.175 - http://elfutils.org/ > > A new release of elfutils is available at: > ftp://sourceware.org/pub/elfutils/0.175/ > or https://sourceware.org/elfutils/ftp/0.175/ Trying to build this on Debian, I get 8 failures, but they all seem to be white space differences. I've attached the test-suite.log file. Kurt == elfutils 0.175: tests/test-suite.log == # TOTAL: 204 # PASS: 195 # SKIP: 1 # XFAIL: 0 # FAIL: 8 # XPASS: 0 # ERROR: 0 .. contents:: :depth: 2 FAIL: run-readelf-const-values.sh = --- readelf.out 2018-11-18 23:43:41.610890094 +0100 +++ - 2018-11-18 23:43:41.616503487 +0100 @@ -21,7 +21,7 @@ low_pc (addr) 0x004004d0 high_pc (data8) 3 (0x004004d3) frame_base (exprloc) - [ 0] call_frame_cfa + [ 0] call_frame_cfa call_all_calls (flag_present) yes sibling (ref4) [5e] [4d] variable abbrev: 1 @@ -59,7 +59,7 @@ low_pc (addr) 0x004003e0 high_pc (data8) 7 (0x004003e7) frame_base (exprloc) - [ 0] call_frame_cfa + [ 0] call_frame_cfa GNU_all_call_sites (flag_present) yes sibling (ref4) [ 119] [b0] variable abbrev: 3 FAIL run-readelf-const-values.sh (exit status: 1) FAIL: run-readelf-twofiles.sh = --- readelf.out 2018-11-18 23:43:44.286830882 +0100 +++ - 2018-11-18 23:43:44.295663903 +0100 @@ -8,15 +8,15 @@ [ 0] range 34, 35 0x0040049c .. 0x0040049c - [ 0] breg7 -8 + [ 0] breg7 -8 range 35, 46 0x0040049d .. 0x004004ad - [ 0] breg7 0 + [ 0] breg7 0 range 46, 47 0x004004ae .. 0x004004ae - [ 0] breg7 -8 + [ 0] breg7 -8 testfile14: @@ -27,12 +27,12 @@ [ 0] range 34, 35 0x0040049c .. 0x0040049c - [ 0] breg7 -8 + [ 0] breg7 -8 range 35, 46 0x0040049d .. 0x004004ad - [ 0] breg7 0 + [ 0] breg7 0 range 46, 47 0x004004ae .. 0x004004ae - [ 0] breg7 -8 + [ 0] breg7 -8 FAIL run-readelf-twofiles.sh (exit status: 1) FAIL: run-readelf-loc.sh --- readelf.out 2018-11-18 23:43:44.446827342 +0100 +++ - 2018-11-18 23:43:44.458498779 +0100 @@ -5,17 +5,17 @@ [ 0] range 0, d 0x00400480 .. 0x0040048c - [ 0] reg5 + [ 0] reg5 [23] range 5, d 0x00400485 .. 0x0040048c - [ 0] reg5 + [ 0] reg5 CU [e0] base: 0x004004a0 [46] range 12, 1a 0x004004b2 .. 0x004004b9 - [ 0] breg5 0 + [ 0] breg5 0 DWARF section [34] '.debug_ranges' at offset 0xd94: FAIL run-readelf-loc.sh (exit status: 1) FAIL: run-readelf-variant.sh --- testfile2.temp 2018-11-18 23:43:51.70686 +0100 +++ - 2018-11-18 23:43:51.714817340 +0100 @@ -1,7 +1,7 @@ byte_size(exprloc) - [ 0] push_object_address - [ 1] deref_size 1 + [ 0] push_object_address + [ 1] deref_size 1 [ 3] call4 [95] - [ 8] plus_uconst 7 - [ 10] const1s -4 - [ 12] and + [ 8] plus_uconst 7 + [10] const1s -4 + [12] and FAIL run-readelf-variant.sh (exit status: 1) FAIL: run-readelf-types.sh == --- readelf.out 2018-11-18 23:43:56.682556562 +0100 +++ - 2018-11-18 23:43:56.694717935 +0100 @@ -19,7 +19,7 @@ low_pc (addr) 0x004005b0 high_pc (data8) 11 (0x004005bb) frame_base (exprloc) - [ 0] call_frame_cfa + [ 0] call_frame_cfa GNU_all_call_sites (flag_present) yes [46]base_typeabbrev: 10 byte_size(data1) 4 FAIL run-readelf-types.sh (exit status: 1) FAIL: run-readelf-dwz-multi.sh == --- readelf.out 2018-11-18 23:43:56.790554172 +0100 +++ - 2018-11-18 23:43:56.801299743 +0100 @@ -26,7 +26,7 @@ low_pc (addr) 0x004006ac high_pc
Re: elfutils 0.175 released
On Sun, Nov 18, 2018 at 11:46:29PM +0100, Kurt Roeckx wrote: > On Fri, Nov 16, 2018 at 02:00:46PM +0100, Mark Wielaard wrote: > > ELFUTILS 0.175 - http://elfutils.org/ > > > > A new release of elfutils is available at: > > ftp://sourceware.org/pub/elfutils/0.175/ > > or https://sourceware.org/elfutils/ftp/0.175/ > > Trying to build this on Debian, I get 8 failures, but they all > seem to be white space differences. I've attached the > test-suite.log file. That looks like you somehow are missing: commit 704f5fc477efaf120980449e677deb563da8491f Author: Mark Wielaard Date: Wed Nov 29 15:43:26 2017 +0100 readelf: Adjust print_ops formatting. Use only 2 spaces for index (there are never 1, the most seen in the wild is 64). Adjust re-indenting after GNU_entry_value. Signed-off-by: Mark Wielaard But that is a commit from elfutils-0.171. Maybe you have a local patch that conflicts with it? Cheers, Mark