Hi. The missing sanitizer reports about violations of function signatures for indirect calls, like:
$ cat sanitize-function.cpp #include <inttypes.h> void f() {} void (*fnpointer) (int); void save () { fnpointer = reinterpret_cast<void (*)(int)>(reinterpret_cast<uintptr_t>(f)); } int main(void) { save (); fnpointer (32); } $ clang++ sanitize-function.cpp -fsanitize=function -g && ./a.out sanitize-function.cpp:12:3: runtime error: call to function f() through pointer to incorrect function type 'void (*)(int)' /home/marxin/Programming/testcases/sanitize-function.cpp:3: note: f() defined here #0 0x431c57 in main /home/marxin/Programming/testcases/sanitize-function.cpp:12:3 #1 0x7f6284994e0a in __libc_start_main /usr/src/debug/glibc-2.30-2.1.x86_64/csu/../csu/libc-start.c:308:16 #2 0x403349 in _start /home/abuild/rpmbuild/BUILD/glibc-2.30/csu/../sysdeps/x86_64/start.S:120 The sanitizer leverages the following UBSAN API: void __ubsan_handle_function_type_mismatch_v1(FunctionTypeMismatchData *Data, ValueHandle Function, ValueHandle calleeRTTI, ValueHandle fnRTTI) { } Which is quite obvious API, except the last argument. The last argument is a pointer to RTTI of a function pointer that will be used for indirect calls. Having a pointer to a fn, clang emits the following sequence at the very beginning of a function: void save () { 431bb0: eb 06 jmp 431bb8 <_Z4savev+0x8> 431bb2: 76 32 jbe 431be6 <main+0x16> 431bb4: e8 90 00 00 55 callq 55431c49 <_end+0x546d8979> 431bb9: 48 89 e5 mov %rsp,%rbp so it jump +8 and the content of the next 8 bytes is actually a pointer to RTTI of this function. That's how can one get RTTI of a fn pointer. The checking code then verifies that a dereferenced function really contains the 431bb8 jump at the very beginning of a function. The suggested approach is very target-dependent and quite hackish. So my question is if we want the sanitizer? And second, do we have something similar that does so explicit .text emission w/o GAS assistance? Thanks, Martin