5

Let vptr be the pointer to the vtable which is carried along objects whose classes are subject to virtual functions.

Alteration of the 'vptr' is likely not intended behavior. However, such alterations cannot be detected as illegal memory accesses, since the pointer lies in boundaries of allocated memory. 'Efence' and 'valgrind/memcheck' won't help--to my knowledge.

Nevertheless, unintended vptr change may lead to serious trouble. If the vptr is altered to point to arbitrary memory, then a delete operator is likely to cause an immediate segmentation fault.

Is there anything that may set 'guards' on vtables, or on pointers to vtables, so that any alteration is monitored?

Clang++ does not seem to do the whole job. Given

#include <string.h>
#include <stdio.h>
struct X { virtual ~X() {} };
int main(int argc, char** argv)
{
    X x;
    memset((void*)&x, 0, sizeof(X));
    printf("<before exit>\n");
    return 0;
}

Compiled and executed ...

> clang++ -fsanitize=undefined -fsanitize=vptr tmp.cpp -o test
> ./test

Detects the violation upon call to 'virtual ~X()'.

<before exit>
<unknown>: runtime error: member call on address 0xbfe30ab8 which does not point to an object of type 'X'
0xbfe30ab8: note: object has invalid vptr
 74 0b e3 bf  00 00 00 00 4d 46 48 b7  74 0b e3 bf 01 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00
              ^~~~~~~~~~~
              invalid vptr

The same does not work for

 ...
    X* x_p = new X();
    memset((void*)x_p, 0, sizeof(X));
    delete x_p;
    printf("<before exit>\n");
 ...

A detector of vptr corruption should set some type of 'watch points' on the vptr-s of all objects.

Frank-Rene Schäfer
  • 3,182
  • 27
  • 51
  • 2
    Not sure why this got closed. As for the question, aren't vtables in .rodata? – yugr Feb 15 '17 at 10:13
  • 1) Agreed, no understanding why this question is put on hold. 2) AFAIK, an object carries some pointer to the vtable of its particular class along with it. If this pointer gets corrupted the object is non-functional. The vtable itself does not necessarily be carried along. Problem remains. – Frank-Rene Schäfer Feb 15 '17 at 10:21
  • But note that you ask about vtable itself, not vptr. E.g. this "virtual destructor's entry in the vtable is maliciously overwritten" clearly talks about vtable. – yugr Feb 15 '17 at 15:34
  • If you actually ask about accidental vptr overwrite, it's no different from accidental overwrite of any other object field (i.e. both can result in crash or in abnormal behavior so there's no point to treat vptr in any special way). – yugr Feb 15 '17 at 15:57
  • 1
    No, the vptr is special, because it's alteration is usually never checked by any type of asserts or consistency checks. Further, I am not aware of any situation where a modification of the vptr can be considered desirable. Thus, it makes sense to detect its alteration. – Frank-Rene Schäfer Feb 15 '17 at 22:13
  • The moderation decision is totally inept. – curiousguy Feb 18 '17 at 20:39
  • @Frank-ReneSchäfer Perhaps you are looking for ` -fsanitize=cfi` ([added in recent Clang](https://clang.llvm.org/docs/ControlFlowIntegrity.html))? It seems to check for broken vptrs. – yugr Feb 20 '17 at 12:03
  • @curiousguy You should be able to vote for reopen (as you have enough rep). – yugr Feb 20 '17 at 12:04
  • @yugr "_You should be able to vote for reopen_" Done. – curiousguy Feb 20 '17 at 13:44
  • vptr isn't any more special than any of library- or compiler-maintained pieces of data. In addition, no assertion or consistency check (or anything really) can reliably detect invalid pointers. There are tools that try to detect unwanted memory accesses and other undefined behaviour in a generic manner (valgrind, ub-sanitizer) but they may slow down your executable considerably. – n. m. could be an AI Feb 21 '17 at 16:03
  • 1
    The question's description provides enough argument to support the standpoint that 'vptr' is special. Again, it is supposed to be constant, it is implicitly present, and it is critical to functioning. Changes to it are not explicitly detectable in program code and errors with respect to it may be hard to find. – Frank-Rene Schäfer Feb 22 '17 at 09:50

0 Answers0