https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110442

            Bug ID: 110442
           Summary: IFUNC resolvers which use __builtin_cpu_supports crash
                    with -fsanitize=address
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: fw at gcc dot gnu.org
  Target Milestone: ---

With -O2 -fsanitize=address, this code:

“
#include <stdio.h>

void
f1 (void)
{
  puts ("f1");
}

void
f2 (void)
{
  puts ("f2");
}

void *
resolve (void)
{
  __builtin_cpu_init ();
  if (__builtin_cpu_supports ("f16c"))
    return f1;
  else
    return f2;
}

void f (void) __attribute__ ((ifunc ("resolve")));

int
main (void)
{
  f ();
}
”

In the store to the shadow mapping:

Dump of assembler code for function resolve:
   0x0000000000402320 <+0>:     sub    $0x8,%rsp
   0x0000000000402324 <+4>:     call   0x4010f0 <__cpu_indicator_init>
   0x0000000000402329 <+9>:     mov    $0x4050f0,%eax
   0x000000000040232e <+14>:    shr    $0x3,%rax
=> 0x0000000000402332 <+18>:    movzbl 0x7fff8000(%rax),%eax
   0x0000000000402339 <+25>:    test   %al,%al
   0x000000000040233b <+27>:    je     0x402341 <resolve+33>
   0x000000000040233d <+29>:    cmp    $0x3,%al
[…]

This happens because with IRELATIVE relocations (or BIND_NOW), IFUNC resolvers
run early, before libasan had a chance to set up the shadow mapping.

Setting the component to the C front-end because the ifunc function attribute
probably needs to be changed to imply no_sanitize_address. IFUNC resolvers are
not supposed to call functions (although it works in some cases on x86), so I
think this would really help building random code with -fsanitize=address.

(In theory, if libasan were an audit module, it would be possible to set up the
mapping before relocation, but that's a change that seems unlikely to happen.)

Reply via email to