diff options
Diffstat (limited to 'libvtv/testsuite/libvtv.cc/thunk_vtable_map_attack.cc')
-rw-r--r-- | libvtv/testsuite/libvtv.cc/thunk_vtable_map_attack.cc | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/libvtv/testsuite/libvtv.cc/thunk_vtable_map_attack.cc b/libvtv/testsuite/libvtv.cc/thunk_vtable_map_attack.cc new file mode 100644 index 00000000000..51f974ee4e7 --- /dev/null +++ b/libvtv/testsuite/libvtv.cc/thunk_vtable_map_attack.cc @@ -0,0 +1,113 @@ +// { dg-do run } + +#include <assert.h> +#include <signal.h> +#include <setjmp.h> +#include <stdio.h> + +#include <iostream> +#include <fstream> + +using std::ofstream; +using std::ifstream; +using std::ios; + +struct A { + A():value(123) {} + int value; + virtual int access() { return this->value; } +}; +struct B { + B():value(456) {} + int value; + virtual int access() { return this->value; } +}; +struct C : public A, public B { + C():better_value(789) {} + int better_value; + virtual int access() { return this->better_value; } +}; +struct D: public C { + D():other_value(987) {} + int other_value; + virtual int access() { return this->other_value; } +}; + +volatile static int signal_count = 0; + +sigjmp_buf before_segv; + +static void +handler(int sig, siginfo_t *si, void *unused) +{ + /* + printf("Got SIGSEGV at address: 0x%lx\n", + (long) si->si_addr); + */ + + signal_count++; + /* You are not supposed to longjmp out of a signal handler but it seems + to work for this test case and it simplifies it */ + siglongjmp(before_segv, 1); + /* exit(1); */ +} + +/* Access one of the vtable_map variables generated by this .o */ +extern void * _ZN4_VTVI1BE12__vtable_mapE; + +/* Access one of the vtable_map variables generated by libstdc++ */ +extern void * _ZN4_VTVISt8ios_baseE12__vtable_mapE; + +int use(B *b) +{ + int ret; + + ret = sigsetjmp(before_segv, 1); + if (ret == 0) + { + /* This should generate a segmentation violation. ie: at this point it should + be protected */ + _ZN4_VTVI1BE12__vtable_mapE = 0; + } + assert(ret == 1 && signal_count == 1); + + ret = sigsetjmp(before_segv, 1); + if (ret == 0) + { + /* Try to modify one of the vtable_map variables in the stdc++ library. + This should generate a segmentation violation. ie: at this point it + should be protected */ + _ZN4_VTVISt8ios_baseE12__vtable_mapE = 0; + } + assert(ret == 1 && signal_count == 2); + + return b->access(); +} + +void myread(std::istream * in) +{ + char input_str[50] = "\0"; + if (in->good()) + (*in) >> input_str; + std::cout << input_str << std::endl; + delete in; +} + +int main() +{ + ifstream * infile = new ifstream("./thunk_vtable_map_attack.cpp"); + myread(infile); + + /* Set up handler for SIGSEGV. */ + struct sigaction sa; + sa.sa_flags = SA_SIGINFO; + sigemptyset(&sa.sa_mask); + sa.sa_sigaction = handler; + if (sigaction(SIGSEGV, &sa, NULL) == -1) + assert(0); + + C c; + assert(use(&c) == 789); + + return 0; +} |