Bug 22634 - Missing IFUNC support is not detected for gcc --enable-default-pie, breaks at least ia64 target
Summary: Missing IFUNC support is not detected for gcc --enable-default-pie, breaks at...
Status: RESOLVED DUPLICATE of bug 25506
Alias: None
Product: glibc
Classification: Unclassified
Component: dynamic-link (show other bugs)
Version: 2.27
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-12-20 08:37 UTC by Sergei Trofimovich
Modified: 2024-01-08 20:36 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:
fweimer: security-


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Sergei Trofimovich 2017-12-20 08:37:53 UTC
Original bug report:
    https://bugs.gentoo.org/641216

On ia64 glibc's ./configure (false) detects IFUNC support on gcc built as --enable-default-pie. This manifests as crashes when calling IFUNC-resolved functions from librt:

    $ cat a.c
    #include <time.h>
    #include <stdio.h>

    int main() {
        struct timespec t;
        int r = clock_getres(CLOCK_REALTIME, &t);
        printf ("r=%i; tv_sec=%llu, tv_nsec=%llu\n", r, (unsigned long long)t.tv_sec, (unsigned long long)t.tv_nsec);
    }

    $ gcc -Wall a.c -o a
    $ ./a
    r=0; tv_sec=0, tv_nsec=4000000
    # ok

    $ gcc -Wall a.c -o a -lrt
    $ ./a
    SIGSEGV (core dumped)
    # crash

    $ LD_BIND_NOW=1 ./a
    r=339656; tv_sec=0, tv_nsec=0
    # garbage data


Relevant log snippet from config.log:

  configure:3948: checking for assembler and linker STT_GNU_IFUNC support

  Relocation section '.rela.dyn' at offset 0x1b0 contains 1 entries:
    Offset          Info           Type           Sym. Value    Sym. Name + Addend
0000000102e8  00000000006f R_IA64_REL64LSB                      1d0
  configure:3979: result: yes

It should be an _IRELATIVE relocation to declare ifunc support. This is unrelated relocation.

Instead glibc checks for any relocations and gets tricked by unrelated relocation:
    https://sourceware.org/git/?p=glibc.git;a=blob;f=configure.ac;h=ca1282a6b3f8c5369c133a47f5c8239c3f2d32b5;hb=HEAD#l597

Building glibc with libc_cv_ld_gnu_indirect_function=no restores librt.so calls.

Basically this test is too weak to detect ifunc support:

 619   LC_ALL=C $READELF -r conftest | grep 'no relocations' >/dev/null || {
 620     libc_cv_ld_gnu_indirect_function=yes
 621   }

One of the solutions would be to build final binary with -no-pie / -nopie (depends on gcc version).
Another would be to grep specifically for R_.+_IRELATIVE (repends on reloaction names).

List of likely unaffected targets (given new enough binutils):
  #define R_386_IRELATIVE    42
  #define R_SPARC_IRELATIVE       249
  #define R_PPC_IRELATIVE         248
  #define R_PPC64_IRELATIVE       248
  #define R_AARCH64_P32_IRELATIVE
  #define R_AARCH64_IRELATIVE     1032
  #define R_ARM_IRELATIVE         160
  #define R_390_IRELATIVE         61
  #define R_X86_64_IRELATIVE      37

List of likely affected targets (don't know how many of those are linux/pie capable):
    #define R_68K_
    #define R_MIPS_
    #define R_PARISC_
    #define R_ALPHA_
    #define R_IA64_
    #define R_SH_
    #define R_CRIS_
    #define R_MN10300_
    #define R_M32R_
    #define R_MICROBLAZE_
    #define R_MICROBLAZE_64_
    #define R_NIOS2_
    #define R_TILEPRO_
    #define R_TILEGX_
    #define R_BPF_
    #define R_METAG_
Comment 1 Sergei Trofimovich 2017-12-20 09:16:27 UTC
As I understand we need a few moving parts to make IFUNC to work:

1. binutils gas frontend to parse '.type foo,%gnu_indirect_function'
   statement

   Status: works everywhere? (assume new binutils)

2. binutils gas backend to generate relevant relocations with
   symbol type IFUNC

    Status: works everywhere? (assume new binutils)

3. binutils ld to convert IFUNC into dynamic relocation, like
   R_X86_64_IRELATIV

   Status: architecture dependent. Not all target have relocation assigned but ld does not fail on IFUNC symbols and converts them into something that does not work. Why?

4. glibc runtime loader to handle R_.+_IRELATIV relocations

   Status: architeture dependent?


Worth filing a separate bug report for [3.] against ld?
Comment 2 Sourceware Commits 2024-01-08 20:09:49 UTC
The master branch has been updated by Adhemerval Zanella <azanella@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=460860f457e2a889785c506e8c77d4a7dff24d3e

commit 460860f457e2a889785c506e8c77d4a7dff24d3e
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Mon Jan 8 10:21:17 2024 -0300

    Remove ia64-linux-gnu
    
    Linux 6.7 removed ia64 from the official tree [1], following the general
    principle that a glibc port needs upstream support for the architecture
    in all the components it depends on (binutils, GCC, and the Linux
    kernel).
    
    Apart from the removal of sysdeps/ia64 and sysdeps/unix/sysv/linux/ia64,
    there are updates to various comments referencing ia64 for which removal
    of those references seemed appropriate. The configuration is removed
    from README and build-many-glibcs.py.
    
    The CONTRIBUTED-BY, elf/elf.h, manual/contrib.texi (the porting
    mention), *.po files, config.guess, and longlong.h are not changed.
    
    For Linux it allows cleanup some clone2 support on multiple files.
    
    The following bug can be closed as WONTFIX: BZ 22634 [2], BZ 14250 [3],
    BZ 21634 [4], BZ 10163 [5], BZ 16401 [6], and BZ 11585 [7].
    
    [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=43ff221426d33db909f7159fdf620c3b052e2d1c
    [2] https://sourceware.org/bugzilla/show_bug.cgi?id=22634
    [3] https://sourceware.org/bugzilla/show_bug.cgi?id=14250
    [4] https://sourceware.org/bugzilla/show_bug.cgi?id=21634
    [5] https://sourceware.org/bugzilla/show_bug.cgi?id=10163
    [6] https://sourceware.org/bugzilla/show_bug.cgi?id=16401
    [7] https://sourceware.org/bugzilla/show_bug.cgi?id=11585
    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Comment 3 Sergei Trofimovich 2024-01-08 20:36:04 UTC
Looking at the current `configure.ac` it's already fixed with:

commit 87a698a21646b7ee620923ef5ffa9735471a8ddd
Author: Fangrui Song <maskray@google.com>
Date:   Tue Feb 4 21:55:44 2020 -0800

    Improve IFUNC check [BZ #25506]

*** This bug has been marked as a duplicate of bug 25506 ***