Open
Description
-fsanitize=cfi-icall
does not emit CFI statements and eliminates the icall during code elimination, leading to broken binaries.
We have created a minimal example highlighting the issue. The following code gets compiled using clang 19.1.0 x86_64 and -O3 -fsanitize=cfi-icall -flto
void (*pFunc)();
int main(int argc, char** argv) {
pFunc = argv[1];
pFunc();
}
to
main:
mov rax,QWORD PTR [rsi+0x8]
mov QWORD PTR [rip+0x2edd],rax # 4018 <pFunc>
ud1 eax,DWORD PTR [eax+0x2]
When setting the -O0
, it does emit the icall as expected. We created a compiler explorer example: https://godbolt.org/z/P71hx6xqs
However, we have also found that initializing the pFunc
seems to stop the code elimination:
void test() {
test();
}
//void (*pFunc)(); // Bad
void (*pFunc)() = &test; // Good
int main(int argc, char** argv) {
pFunc = (void (*)())**argv;
pFunc();
}
In that case the icall exists. Compiler explorer: https://godbolt.org/z/36hYWb7YW
We have also tested the previous clang version but cannot find a version where this compiles as expected.