This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Do we want to add -fsanitize=function?
- From: Martin Liška <mliska at suse dot cz>
- To: GCC Development <gcc at gcc dot gnu dot org>
- Cc: Jakub Jelinek <jakub at redhat dot com>, Marek Polacek <polacek at redhat dot com>
- Date: Tue, 14 Jan 2020 12:36:11 +0100
- Subject: Do we want to add -fsanitize=function?
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