[PATCH] x86: Include <bits/stdlib-bsearch.h> in dl-cacheinfo.h

Sam James sam@gentoo.org
Tue Sep 9 03:16:16 GMT 2025


"H.J. Lu" <hjl.tools@gmail.com> writes:

> 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.

. Fixes BZ #33374.

>
> Signed-off-by: H.J. Lu <hjl.tools@gmail.com>

Thanks for digging into it more. I think we may still want to do
something to future-proof but there's an awkward history there
(8b8f13b60d9587e91e8719239a9249b448bc1307 etc).

Reviewed-by: Sam James <sam@gentoo.org>

> ---
>  sysdeps/x86/dl-cacheinfo.h | 15 +++++++++++++--
>  1 file changed, 13 insertions(+), 2 deletions(-)
>
> diff --git a/sysdeps/x86/dl-cacheinfo.h b/sysdeps/x86/dl-cacheinfo.h
> index 6f9bb08a19..b6520bddaa 100644
> --- a/sysdeps/x86/dl-cacheinfo.h
> +++ b/sysdeps/x86/dl-cacheinfo.h
> @@ -16,6 +16,16 @@
>     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)


More information about the Libc-alpha mailing list