Bug 1117458
| Summary: | ld from devtoolset copies SONAME to DT_NEEDED without checking if it’s empty | ||||||
|---|---|---|---|---|---|---|---|
| Product: | Red Hat Developer Toolset | Reporter: | Bryan Totty <btotty> | ||||
| Component: | binutils | Assignee: | Patsy Griffin <pfrankli> | ||||
| Status: | CLOSED ERRATA | QA Contact: | Martin Cermak <mcermak> | ||||
| Severity: | medium | Docs Contact: | |||||
| Priority: | medium | ||||||
| Version: | DTS 3.0 RHEL 6 | CC: | jonstanley, law, mcermak, mfranc, mnewsome, mpolacek, pfrankli | ||||
| Target Milestone: | beta2 | ||||||
| Target Release: | 3.0 | ||||||
| Hardware: | Unspecified | ||||||
| OS: | Linux | ||||||
| Whiteboard: | |||||||
| Fixed In Version: | Doc Type: | Bug Fix | |||||
| Doc Text: |
Cause: The linker will overwrite a valid SONAME with an empty string in a DT_NEEDED record.
Consequence: Certain programs will link, but not execute because symbols from some libraries will not be loaded.
Fix: The linker correctly handles empty strings in SONAMES.
Result: Programs execute as expected.
|
Story Points: | --- | ||||
| Clone Of: | |||||||
| : | 1128279 1128280 (view as bug list) | Environment: | |||||
| Last Closed: | 2014-10-30 09:26:39 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: | |||||||
| Bug Depends On: | |||||||
| Bug Blocks: | 1128279, 1128280 | ||||||
| Attachments: |
|
||||||
Since the problem described in this bug report should be resolved in a recent advisory, it has been closed with a resolution of ERRATA. For information on the advisory, and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. https://rhn.redhat.com/errata/RHEA-2014-1746.html |
Created attachment 916520 [details] Reproducer Package It looks like the ld from the devtoolset (or maybe all ld versions after GCC4.4 as a lot of things changed in the DT_NEEDED handling) just copies SONAME to DT_NEEDED without checking if it’s empty. Therefore at runtime it can’t find the library as there is an empty string instead of the library name (and ldd/objdump/readelf show this). GCC4.4 didn’t have problems with this. It correctly records the library name instead of getting empty nonsense from SONAME. Using DTS 2.1: server@test libtest$ gcc user.c -L. -lfoo -o user server@test libtest$ readelf -d user Dynamic section at offset 0x7e8 contains 25 entries: Tag Type Name/Value 0x0000000000000003 (PLTGOT) 0x4019d0 0x0000000000000002 (PLTRELSZ) 72 (bytes) 0x0000000000000017 (JMPREL) 0x400470 0x0000000000000014 (PLTREL) RELA 0x0000000000000007 (RELA) 0x400458 0x0000000000000008 (RELASZ) 24 (bytes) 0x0000000000000009 (RELAENT) 24 (bytes) 0x0000000000000015 (DEBUG) 0x0 0x0000000000000006 (SYMTAB) 0x400260 0x000000000000000b (SYMENT) 24 (bytes) 0x0000000000000005 (STRTAB) 0x400368 0x000000000000000a (STRSZ) 123 (bytes) 0x000000006ffffef5 (GNU_HASH) 0x4003e8 0x0000000000000001 (NEEDED) Shared library: [] 0x0000000000000001 (NEEDED) Shared library: [libc.so.6] 0x000000000000000c (INIT) 0x4004b8 0x000000000000000d (FINI) 0x4006ec 0x000000000000001a (FINI_ARRAY) 0x401a10 0x000000000000001c (FINI_ARRAYSZ) 8 (bytes) 0x0000000000000019 (INIT_ARRAY) 0x401a18 0x000000000000001b (INIT_ARRAYSZ) 8 (bytes) 0x000000006ffffff0 (VERSYM) 0x400420 0x000000006ffffffe (VERNEED) 0x400438 0x000000006fffffff (VERNEEDNUM) 1 0x0000000000000000 (NULL) 0x0 serverserver@test libtest$ ldd user linux-vdso.so.1 => (0x00007fff61fff000) libc.so.6 => /lib64/libc.so.6 (0x00000036d9600000) /lib64/ld-linux-x86-64.so.2 (0x00000036d8e00000) server@test libtest$ Even though it appears that all dependencies are met, and the linker doesn't complain when running, we get: server@test libtest$ ./user ./user: symbol lookup error: ./user: undefined symbol: foo Since foo is defined inside the customer's shared library. He verified that this does *not* happen using the system toolchain on RHEL6, as well as RHEL7. ----------Reproducer---------- Compile the attached libfoo.c as below: gcc -fPIC -g -c libfoo.c gcc -shared -Wl,-soname, -o libfoo.so -lc Then compile user.c as follows: gcc user.c -o user -L. -lfoo Do this with the system binutils, and then the DTS binutils and notice the different behavior.