Bug 26391 - Question regarding duplicate symbols
Summary: Question regarding duplicate symbols
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.36
: P2 normal
Target Milestone: 2.36
Assignee: Not yet assigned to anyone
URL: https://sourceware.org/pipermail/binu...
Keywords:
Depends on:
Blocks:
 
Reported: 2020-08-14 18:22 UTC by Kristen Carlson Accardi
Modified: 2023-04-28 15:40 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed: 2020-08-14 00:00:00


Attachments
sparc64-linux binaries (8.35 KB, application/octet-stream)
2021-12-24 14:45 UTC, H.J. Lu
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Kristen Carlson Accardi 2020-08-14 18:22:27 UTC
I am implementing "function granular kernel address space layout randomization" for Linux, and am trying to solve a problem that I am really hoping there is a compiler or linker option for. My implementation uses gcc's -ffunction-sections to break apart the kernel .text section by function. At kernel boot time, just after decompression, I shuffle all the function sections randomly and re-layout the kernel. Surprisingly, this works pretty well, but I am having a problem with a niche condition that is important to resolve for the live-patching use case. In order to live-patch the kernel, the live-patching code will request the address of symbols by name from the kernel. This works great after randomization because it always receives the current address at runtime rather than relying on any kind of buildtime address. The issue with with the live-patching code's algorithm for resolving duplicate symbol names. If they request a symbol by name from the kernel and there are 3 symbols with the same name, they use the symbol's position in the built binary image to select the correct symbol. This is obviously invalid when the layout has been shuffled randomly. I was hoping there was some kind of compiler or linker option that would add some kind of uniqueness to the symbols to make sure their were never any duplicates, but I am not finding such a thing. Is there something like this already available? Thanks very much!
Comment 1 H.J. Lu 2020-08-14 19:32:20 UTC
Please try

https://gitlab.com/x86-binutils/binutils-gdb/-/tree/users/hjl/pr26391/master

You can pass -z unique to ld to make local symbols unique.
Comment 2 Kristen Carlson Accardi 2020-08-21 22:49:02 UTC
This works for me! Thanks!
Comment 3 H.J. Lu 2020-08-22 15:40:52 UTC
I updated my branch to rename the option name to "-z unique-symbol".
Comment 4 Kristen Carlson Accardi 2020-09-09 15:24:01 UTC
This feature was well received by the livepatch maintainers. It not only solves my individual problem, but also would allow them to more precisely locate duplicate symbols in general for patching. I'd like to request that this feature be implemented in a future release.
Comment 6 H.J. Lu 2020-09-09 16:21:04 UTC
A patch is posted at

https://sourceware.org/pipermail/binutils/2020-September/113271.html
Comment 7 Sourceware Commits 2020-09-12 12:40:12 UTC
The master branch has been updated by H.J. Lu <hjl@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=496afd17055aeb7d8f45e01715c475664f2b73bd

commit 496afd17055aeb7d8f45e01715c475664f2b73bd
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Sat Sep 12 05:37:30 2020 -0700

    elf: Add -z unique-symbol to avoid duplicated local symbol names
    
    The symbol string table in the .symtab section is optional and cosmetic.
    The contents of the .symtab section have no impact on run-time execution.
    The symbol names in the symbol string table help distinguish addresses at
    different locations.  Add a linker option, -z unique-symbol, to avoid
    duplicated local symbol names in the symbol string table.
    
    This feature was well received by the livepatch maintainers.  It not only
    solves the duplicated local symbol name problem, but also would allow
    livepatch to more precisely locate duplicate symbols in general for
    patching.
    
    bfd/
    
            PR ld/26391
            * elflink.c (elf_final_link_info): Add local_hash_table.
            (local_hash_entry): New.
            (local_hash_newfunc): Likewise.
            (elf_link_output_symstrtab): Append ".COUNT" to duplicated local
            symbols.
            (bfd_elf_final_link): Initialize and free local_hash_table for
            "-z unique-symbol".
    
    include/
    
            PR ld/26391
            * bfdlink.h (bfd_link_info): Add unique_symbol.
    
    ld/
    
            PR ld/26391
            * NEWS: Mention "-z unique-symbol".
            * emultempl/elf.em (gld${EMULATION_NAME}_handle_option): Handle
            "-z unique-symbol" and "-z nounique-symbol".
            * ld.texi: Document "-z unique-symbol" and "-z nounique-symbol".
            * lexsup.c (elf_static_list_options): Add "-z unique-symbol" and
            "-z nounique-symbol".
            * testsuite/ld-elf/elf.exp: Add PR ld/26391 tests.
            * testsuite/ld-elf/pr26391.nd: New file.
            * testsuite/ld-elf/pr26391.out: Likewise.
            * testsuite/ld-elf/pr26391a.c: Likewise.
            * testsuite/ld-elf/pr26391b.c: Likewise.
            * testsuite/ld-elf/pr26391c.c: Likewise.
            * testsuite/ld-elf/pr26391d.c: Likewise.
Comment 8 H.J. Lu 2020-09-12 12:40:54 UTC
Fixed for 2.36.
Comment 9 Sourceware Commits 2020-09-13 09:17:14 UTC
The master branch has been updated by Alan Modra <amodra@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=1f656a652ea8d489b5aa5b7f55c535fc9e6b0b29

commit 1f656a652ea8d489b5aa5b7f55c535fc9e6b0b29
Author: Alan Modra <amodra@gmail.com>
Date:   Sun Sep 13 17:56:52 2020 +0930

    Re: elf: Add -z unique-symbol
    
            PR 26391
            * testsuite/ld-elf/pr26391.nd: Adjust to match powerpc64 function
            descriptors.
Comment 10 John Paul Adrian Glaubitz 2021-12-15 10:04:25 UTC
It seems that this test is failing on sparc64:

FAIL: Run pr26391-5
FAIL: Run pr26391-6

See: https://buildd.debian.org/status/fetch.php?pkg=binutils&arch=sparc64&ver=2.37-10&stamp=1637614637&raw=0
Comment 11 John Paul Adrian Glaubitz 2021-12-15 20:01:56 UTC
(In reply to John Paul Adrian Glaubitz from comment #10)
> It seems that this test is failing on sparc64:
> 
> FAIL: Run pr26391-5
> FAIL: Run pr26391-6
> 
> See:
> https://buildd.debian.org/status/fetch.php?pkg=binutils&arch=sparc64&ver=2.
> 37-10&stamp=1637614637&raw=0

I have verified that this commit introduced the regression on sparc64:

496afd17055aeb7d8f45e01715c475664f2b73bd is the first bad commit
commit 496afd17055aeb7d8f45e01715c475664f2b73bd
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Sat Sep 12 05:37:30 2020 -0700

    elf: Add -z unique-symbol to avoid duplicated local symbol names

    The symbol string table in the .symtab section is optional and cosmetic.
    The contents of the .symtab section have no impact on run-time execution.
    The symbol names in the symbol string table help distinguish addresses at
    different locations.  Add a linker option, -z unique-symbol, to avoid
    duplicated local symbol names in the symbol string table.

    This feature was well received by the livepatch maintainers.  It not only
    solves the duplicated local symbol name problem, but also would allow
    livepatch to more precisely locate duplicate symbols in general for
    patching.
Comment 12 H.J. Lu 2021-12-16 05:04:57 UTC
I don't know why "ld -r -z unique-symbol" generates incorrect output
on sparc64.
Comment 13 H.J. Lu 2021-12-24 14:45:04 UTC
Created attachment 13877 [details]
sparc64-linux binaries

I built sparc64-linux pr26391-5 and pr26391-6 binaries with a cross
compiler on Linux/x8-64.  They run fine on sparc64-linux:

hjl@gcc102:~$ cd /tmp/
hjl@gcc102:/tmp$ ./pr26391-5
bar 1
bar 2
bar 3
hjl@gcc102:/tmp$ ./pr26391-6
bar 1
bar 2
bar 3
hjl@gcc102:/tmp$ 

If they fail in binutils tests on sparc64-linux, it is caused by
sparc64-linux hardware, kernel, glibc, binutils, ... bugs.
Comment 14 Sourceware Commits 2023-01-16 22:22:11 UTC
The try-PR26391 branch has been updated by Mark Wielaard <mark@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=99175c84026b1bfa534f3946150535c39027911d

commit 99175c84026b1bfa534f3946150535c39027911d
Author: Sam James <sam@gentoo.org>
Date:   Mon Jan 16 14:03:02 2023 -0800

    ld: Use run_cc_link_tests for PR ld/26391 tests
    
    Use run_cc_link_tests for PR ld/26391 tests to compile PR ld/26391 tests
    in C.
    
            PR ld/30002
            * testsuite/ld-elf/elf.exp: Use run_cc_link_tests for PR ld/26391
            tests.
Comment 15 Sourceware Commits 2023-04-28 15:40:41 UTC
The master branch has been updated by H.J. Lu <hjl@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=64b59b6bb2261fe2fa8310f94b4ed420c162e357

commit 64b59b6bb2261fe2fa8310f94b4ed420c162e357
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Mon Jan 16 14:03:02 2023 -0800

    ld: Use run_cc_link_tests for PR ld/26391 tests
    
    Use run_cc_link_tests for PR ld/26391 tests to compile PR ld/26391 tests
    in C.
    
            PR ld/30002
            * testsuite/ld-elf/elf.exp: Use run_cc_link_tests for PR ld/26391
            tests.