123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- // { 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;
- }
|