This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]