aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/libvtv/testsuite/libvtv.cc/thunk_vtable_map_attack.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.9/libvtv/testsuite/libvtv.cc/thunk_vtable_map_attack.cc')
-rw-r--r--gcc-4.9/libvtv/testsuite/libvtv.cc/thunk_vtable_map_attack.cc113
1 files changed, 113 insertions, 0 deletions
diff --git a/gcc-4.9/libvtv/testsuite/libvtv.cc/thunk_vtable_map_attack.cc b/gcc-4.9/libvtv/testsuite/libvtv.cc/thunk_vtable_map_attack.cc
new file mode 100644
index 000000000..51f974ee4
--- /dev/null
+++ b/gcc-4.9/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;
+}