*Environment $ cat /etc/issue Fedora release 17 (Beefy Miracle) Kernel \r on an \m (\l) $ cat /proc/version Linux version 3.6.6-1.fc17.i686.PAE (mockbuild@) (gcc version 4.7.2 20120921 (Red Hat 4.7.2-2) (GCC) ) #1 SMP Mon Nov 5 22:05:54 UTC 2012 RPM version is 4.9.1.3, and it still exists in 5.4.9. *Problem Segment fault while invoke debugedit to process 'xB.linkhuge' file Step 1: touch debugsources.list Step 2: $ ls xB.linkhuge -al -rwxr-xr-x 1 hongxujia hongxujia 1221403 Oct 16 16:14 test/xB.linkhuge Step 3: /usr/lib/rpm/debugedit -b '/var/src/debug/log' -d '/usr/src/debug' -i -l 'debugsources.list' 'xB.linkhuge' 364d09c997aa5c65b27d030a689363e9b88c6816 Segmentation fault (core dumped) Step 4: $ ls -al xB.linkhuge -rwxr-xr-x 1 hongxujia hongxujia 2097152 Oct 16 16:14 xB.linkhuge It only happens at first invoking and the file's bss Offset have a large number. $ readelf -a xB.linkhuge ...... [Nr] Name Type Address Offset Size EntSize Flags Link Info Align skip.. [25] .data PROGBITS 00000000005128a0 001128a0 0000000000010168 0000000000000000 WA 0 0 32 [26] .bss NOBITS 0000000001000000 00200000 0000000000010050 0000000000000000 WA 0 0 32 [27] .comment PROGBITS 0000000000000000 00122a08 0000000000000011 0000000000000001 MS 0 0 1 ...... *Analysis In debugedit, it invoked elf_begin with ELF_C_RDWR_MMAP as start, and invoked elf_update to modify the file and memory, and then invoked elf_end in the end. 1) While ELF_C_RDWR_MMAP was used, elf_begin invoked mmap() to map file into memory with the size of '1221403'. Log from strace: ...... open("debugsources.list", O_WRONLY|O_CREAT|O_APPEND|O_LARGEFILE, 0644) = 3 stat64("xB.linkhuge", {st_mode=S_IFREG|0755, st_size=1221403, ...}) = 0 chmod("xB.linkhuge", 0100755) = 0 open("xB.linkhuge", O_RDWR|O_LARGEFILE) = 4 fcntl64(4, F_GETFL) = 0x8002 (flags O_RDWR|O_LARGEFILE) fstat64(4, {st_mode=S_IFREG|0755, st_size=1221403, ...}) = 0 mmap2(NULL, 1221403, PROT_READ|PROT_WRITE, MAP_SHARED, 4, 0) = 0xb761d000 ...... 2) While file's bss Offset has a large number '00200000', elf_update caculated file size by __elf64_updatenull_wrlock and the size was enlarged. 3) In this situation, elf_update invoked ftruncate to enlarge the file, and memory size (elf->maximum_size) also was incorrectly updated. Log from strace: ...... ftruncate64(4, 2097152) = 0 msync(0xb761d000, 1216568, MS_SYNC) = 0 ...... 4) There was segment fault in elf_end which invoked munmap with the length is incorrectly enlarged file size '2097152', not the length of mmap in elf_begin '1216568'. Log from strace: ...... munmap(0xb761d000, 2097152) = 0 ...... *Solution 1) I tried to use ELF_C_RDWR instaed of ELF_C_RDWR_MMAP while invoke elf_begin, but it failed to modify the file's build_id. 2) I also tried to modify elf library, don't update memory size (elf->maximum_size) in this situation. It fixed this issue and everything looks ok, but I am not sure the modification is necessary. ...... 11 diff --git a/libelf/elf_update.c b/libelf/elf_update.c 12 --- a/libelf/elf_update.c 13 +++ b/libelf/elf_update.c 14 @@ -120,7 +120,9 @@ write_file (Elf *elf, off_t size, int change_bo, size_t shnum) 15 size = -1; 16 } 17 18 - if (size != -1 && elf->parent == NULL) 19 + /* If the file is enlarged by truncate, we should not update maximum_size to 20 + avoid segment fault while invoking munmap in elf_end */ 21 + if (size != -1 && elf->parent == NULL && (size_t) size <= elf->maximum_size) 22 elf->maximum_size = size; ......
Created attachment 812845 [details] The file whose bss offset have a large number
Looks to me like something to fix in elfutils rather than debugedit, reassigning.
This looks similar to https://bugzilla.redhat.com/show_bug.cgi?id=1020842
*** This bug has been marked as a duplicate of bug 1020842 ***