| Summary: | debugedit: segment fault while file's bss offset have a large number | ||||||
|---|---|---|---|---|---|---|---|
| Product: | [Build System, Metadata & Runtime] OE-Core | Reporter: | Hongxu Jia <hongxu.jia> | ||||
| Component: | core | Assignee: | Hongxu Jia <hongxu.jia> | ||||
| Status: | RESOLVED FIXED | QA Contact: | |||||
| Severity: | normal | ||||||
| Priority: | Medium | CC: | hongxu.jia, jessica.zhang, liezhi.yang, mark.hatle, meta.mr.watcher, meta.watcher, Qi.Chen, sgw, yi.zhao | ||||
| Version: | 1.5 | ||||||
| Target Milestone: | 1.6 | ||||||
| Hardware: | x86 | ||||||
| OS: | Multiple | ||||||
| Whiteboard: | |||||||
| OS type for building Yocto: | --- | Type of Regression: | --- | ||||
| Verified: | Documentation change: | Don't know | |||||
| Attachments: |
|
||||||
This defect exists on the Distro's rpm, so I have reported this to upstream. https://bugzilla.redhat.com/show_bug.cgi?id=1019707 The real reason was about elflib also, I have filed another bug to upstream: https://bugzilla.redhat.com/show_bug.cgi?id=1020842 |
Created attachment 1566 [details] The file whose bss offset have a large number *Environment $ cat /etc/issue Ubuntu 13.04 \n \l $ uname -a Linux pek-hjia-d1 3.8.0-31-generic #46-Ubuntu SMP Tue Sep 10 20:03:44 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux *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 xB.linkhuge Step 3: tmp/sysroots/x86_64-linux/usr/lib/rpm/bin/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; ......