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