]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
x86: Include <bits/stdlib-bsearch.h> in dl-cacheinfo.h
authorH.J. Lu <hjl.tools@gmail.com>
Tue, 9 Sep 2025 02:49:24 +0000 (19:49 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Tue, 9 Sep 2025 03:31:36 +0000 (20:31 -0700)
On x86-64, when glibc is configured with --enable-stack-protector=all
and compiled with -Os, ld.so crashes very early:

(gdb) r --direct
Starting program: /export/build/gnu/tools-build/glibc-gitlab/build-x86_64-linux/string/test-memswap --direct

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7f41b0a in bsearch (__key=__key@entry=0x7fffffffda28,
    __base=__base@entry=0x7ffff7fca140 <intel_02_known>,
    __nmemb=__nmemb@entry=68, __size=__size@entry=8,
    __compar=__compar@entry=0x7ffff7f3b691 <intel_02_known_compare>)
    at ../bits/stdlib-bsearch.h:22
22 {
(gdb) disass
Dump of assembler code for function bsearch:
   0x00007ffff7f41af0 <+0>: push   %r15
   0x00007ffff7f41af2 <+2>: mov    %rcx,%r15
   0x00007ffff7f41af5 <+5>: push   %r14
   0x00007ffff7f41af7 <+7>: push   %r13
   0x00007ffff7f41af9 <+9>: mov    %rsi,%r13
   0x00007ffff7f41afc <+12>: push   %r12
   0x00007ffff7f41afe <+14>: mov    %rdi,%r12
   0x00007ffff7f41b01 <+17>: push   %rbp
   0x00007ffff7f41b02 <+18>: mov    %rdx,%rbp
   0x00007ffff7f41b05 <+21>: push   %rbx
   0x00007ffff7f41b06 <+22>: sub    $0x18,%rsp
=> 0x00007ffff7f41b0a <+26>: mov    %fs:0x28,%r14
^^^^^^^^^^^^^^^^^^^^^^^^^^^^ We can't use stack protector at this point.
   0x00007ffff7f41b13 <+35>: mov    %r14,0x8(%rsp)
   0x00007ffff7f41b18 <+40>: mov    %r8,%r14
   0x00007ffff7f41b1b <+43>: test   %rbp,%rbp
   0x00007ffff7f41b1e <+46>: je     0x7ffff7f41b48 <bsearch+88>
   0x00007ffff7f41b20 <+48>: mov    %rbp,%rbx
   0x00007ffff7f41b23 <+51>: mov    %r12,%rdi
   0x00007ffff7f41b26 <+54>: shr    $1,%rbx
   0x00007ffff7f41b29 <+57>: imul   %r15,%rbx
   0x00007ffff7f41b2d <+61>: add    %r13,%rbx
   0x00007ffff7f41b30 <+64>: mov    %rbx,%rsi
(gdb) bt
 #0  0x00007ffff7f41b0a in bsearch (__key=__key@entry=0x7fffffffda28,
    __base=__base@entry=0x7ffff7fca140 <intel_02_known>,
    __nmemb=__nmemb@entry=68, __size=__size@entry=8,
    __compar=__compar@entry=0x7ffff7f3b691 <intel_02_known_compare>)
    at ../bits/stdlib-bsearch.h:22
 #1  0x00007ffff7f3c1be in intel_check_word (name=188, value=1979933440,
    has_level_2=has_level_2@entry=0x7fffffffda7f,
    no_level_2_or_3=no_level_2_or_3@entry=0x7fffffffda7e,
    cpu_features=<optimized out>) at ../sysdeps/x86/dl-cacheinfo.h:217
 #2  0x00007ffff7f3c29f in handle_intel (name=name@entry=188,
    cpu_features=<optimized out>) at ../sysdeps/x86/dl-cacheinfo.h:279
 #3  0x00007ffff7f3ccf9 in dl_init_cacheinfo (cpu_features=<optimized out>)
    at ../sysdeps/x86/dl-cacheinfo.h:852
 #4  init_cpu_features (cpu_features=<optimized out>)
    at ../sysdeps/x86/cpu-features.c:1153
 #5  0x00007ffff7f3d6f9 in __libc_start_main_impl (main=0x7ffff7f396dc <main>,
    argc=2, argv=0x7fffffffdbe8, init=<optimized out>, fini=<optimized out>,
    rtld_fini=0x0, stack_end=0x7fffffffdbd8) at ../csu/libc-start.c:269
 #6  0x00007ffff7f39901 in _start () at ../sysdeps/x86_64/start.S:115
(gdb)

The problem is that since __USE_EXTERN_INLINES isn't defined with -Os,
the inline bsearch in <bits/stdlib-bsearch.h> isn't available and the
external bsearch is compiled with stack protector.  Include
<bits/stdlib-bsearch.h> in dl-cacheinfo.h fixed BZ #33374.

Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
Reviewed-by: Sam James <sam@gentoo.org>
sysdeps/x86/dl-cacheinfo.h

index 6f9bb08a19c5c9e443c2d3923e3057b679f34310..b6520bddaaf8467d205daed9b2261d2dd4d8240c 100644 (file)
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
+/* NB: When glibc is compiled with -Os, <bits/stdlib-bsearch.h> isn't
+   included by <stdlib.h> since __USE_EXTERN_INLINES isn't defined.
+   Include <bits/stdlib-bsearch.h> here since <bits/stdlib-bsearch.h>
+   may be included more than once, rename bsearch to __bsearch and
+   use __bsearch, instead of bsearch, in intel_check_word which may
+   be called very early during startup.  */
+#define bsearch __bsearch
+#include <bits/stdlib-bsearch.h>
+#undef bsearch
+
 static const struct intel_02_cache_info
 {
   unsigned char idx;
@@ -214,8 +224,9 @@ intel_check_word (int name, unsigned int value, bool *has_level_2,
          struct intel_02_cache_info search;
 
          search.idx = byte;
-         found = bsearch (&search, intel_02_known, nintel_02_known,
-                          sizeof (intel_02_known[0]), intel_02_known_compare);
+         found = __bsearch (&search, intel_02_known, nintel_02_known,
+                            sizeof (intel_02_known[0]),
+                            intel_02_known_compare);
          if (found != NULL)
            {
              if (found->rel_name == folded_rel_name)