Bug 1020842
Summary: | libelf: segment fault on x86-64 while file's bss offset have a large number | ||||||
---|---|---|---|---|---|---|---|
Product: | [Fedora] Fedora | Reporter: | hongxu jia <hongxu.jia> | ||||
Component: | elfutils | Assignee: | Roland McGrath <roland> | ||||
Status: | CLOSED ERRATA | QA Contact: | Fedora Extras Quality Assurance <extras-qa> | ||||
Severity: | urgent | Docs Contact: | |||||
Priority: | unspecified | ||||||
Version: | 22 | CC: | aoliva, fche, jakub, jan.kratochvil, mjw, mjw, mnewsome, roland | ||||
Target Milestone: | --- | Keywords: | FutureFeature | ||||
Target Release: | --- | ||||||
Hardware: | Unspecified | ||||||
OS: | Linux | ||||||
Whiteboard: | |||||||
Fixed In Version: | elfutils-0.163-1.fc21 | Doc Type: | Enhancement | ||||
Doc Text: | Story Points: | --- | |||||
Clone Of: | Environment: | ||||||
Last Closed: | 2015-06-30 20:11:25 UTC | Type: | Bug | ||||
Regression: | --- | Mount Type: | --- | ||||
Documentation: | --- | CRM: | |||||
Verified Versions: | Category: | --- | |||||
oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |||||
Cloudforms Team: | --- | Target Upstream Version: | |||||
Embargoed: | |||||||
Attachments: |
|
Description
hongxu jia
2013-10-18 11:20:08 UTC
*Analysis 1) While ELF_C_RDWR_MMAP was used, elf_begin invoked mmap() to map file into memory with the size of '1221403'. ...strace log... mmap(NULL, 1221403, PROT_READ|PROT_WRITE, MAP_SHARED, 3, 0) = 0x7ff720fe2000 ................ 2) While 'xB.linkhuge' bss Offset has a large number '00200000', elf_update caculated file size by __elf64_updatenull_wrlock and the size was enlarged from '1221403' to '2097152' 3) In this situation, elf_update invoked ftruncate to enlarge the file, and memory size (elf->maximum_size) also was incorrectly updated. ...strace log... ftruncate(3, 2097152) ................ 4) There was segment fault in elf_end which invoked munmap with the length is the enlarged file size '2097152', not the length of mmap '1216568'. ...strace log... munmap(0x7ff720fe2000, 2097152) = 0 ................ *Solution 1) I tried to modify elf_update.c, 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; ...... 2) I also tried to add check before munmap in elf_end by msync with the length of elf->maximum_size, if msync return error, munmap should not be invoked, this could avoid segment fault. --- a/libelf/elf_end.c +++ b/libelf/elf_end.c @@ -217,7 +217,10 @@ elf_end (elf) if ((elf->flags & ELF_F_MALLOCED) != 0) free (elf->map_address); else if ((elf->flags & ELF_F_MMAPPED) != 0) - munmap (elf->map_address, elf->maximum_size); + { + if (msync (elf->map_address, elf->maximum_size, MS_SYNC) == 0) + munmap (elf->map_address, elf->maximum_size); + } } 3) Any suggestion is welcomed. *** Bug 1019707 has been marked as a duplicate of this bug. *** This bug appears to have been reported against 'rawhide' during the Fedora 22 development cycle. Changing version to '22'. More information and reason for this action is here: https://fedoraproject.org/wiki/Fedora_Program_Management/HouseKeeping/Fedora22 Still an issue with current upstream git elfutils. So the problem is indeed the large sh_offset of the .bss section. Since it is NOBITS the size of the section is taken into account. gabi says that a NOBITS section occupies no space in the file, and its sh_offset member locates the conceptual placement in the file. So that is why updatenull_wrlock takes the sh_offset and assumes it is inside the file (enlarging the file size) when ELF_F_LAYOUT is set. We can probably just ignore the sh_offset of any NOBITS section in updatenull (). diff --git a/libelf/elf32_updatenull.c b/libelf/elf32_updatenull.c index 5e809b7..7629502 100644 --- a/libelf/elf32_updatenull.c +++ b/libelf/elf32_updatenull.c @@ -318,9 +318,8 @@ __elfw2(LIBELFBITS,updatenull_wrlock) (Elf *elf, int *change_bop, size_t shnum) if (elf->flags & ELF_F_LAYOUT) { size = MAX ((GElf_Word) size, - shdr->sh_offset - + (shdr->sh_type != SHT_NOBITS - ? shdr->sh_size : 0)); + (shdr->sh_type != SHT_NOBITS + ? shdr->sh_offset + shdr->sh_size : 0)); /* The alignment must be a power of two. This is a requirement from the ELF specification. Additionally It seems to fix the issue. Question. What program created the xB.linkhuge ELF file in the first place? It seems it is bug to generate a .bss NOBITS section with a sh_off that is not inside the file in the first place (even if we can work around it). So maybe that generator should also be fixed? (In reply to Mark Wielaard from comment #6) > So the problem is indeed the large sh_offset of the .bss section. > Since it is NOBITS the size of the section is taken into account. Sorry, that should have read: "Since it is NOBITS the size of the section is ignored, but the offset is taken into account." Such files are probably created by buggy binutils ld: https://sourceware.org/bugzilla/show_bug.cgi?id=12921 Patch posted upstream: https://lists.fedorahosted.org/pipermail/elfutils-devel/2015-March/004646.html The patch is now in elfutils git master and the bug will be fixed when elfutils 0.162 is released later this week. elfutils-0.162-1.fc22 has been submitted as an update for Fedora 22. https://admin.fedoraproject.org/updates/elfutils-0.162-1.fc22 Package elfutils-0.162-1.fc22: * should fix your issue, * was pushed to the Fedora 22 testing repository, * should be available at your local mirror within two days. Update it with: # su -c 'yum update --enablerepo=updates-testing elfutils-0.162-1.fc22' as soon as you are able to. Please go to the following url: https://admin.fedoraproject.org/updates/FEDORA-2015-9857/elfutils-0.162-1.fc22 then log in and leave karma (feedback). elfutils-0.163-1.fc22 has been submitted as an update for Fedora 22. https://admin.fedoraproject.org/updates/elfutils-0.163-1.fc22 elfutils-0.163-1.fc22 has been pushed to the Fedora 22 stable repository. If problems still persist, please make note of it in this bug report. elfutils-0.163-1.fc21 has been submitted as an update for Fedora 21. https://admin.fedoraproject.org/updates/elfutils-0.163-1.fc21 elfutils-0.163-1.fc21 has been pushed to the Fedora 21 stable repository. If problems still persist, please make note of it in this bug report. |