Race condition reading C++ vtable. Is possible?

120 views Asked by At

I have an app crashing some times because the MS _purecall is being called but the data I see on the crash dump is not what I expected.

I have CSocket derived from CConnection, the latter has a pure virtual function named DoRead and the app crashes when an instance of CSocket calls this function in a worker thread.

Following the register values and how Microsoft implements C++ virtual tables and calls, I see RCX has the correct this value, the first quad-word points to the v-table and the v-table is correct so the call to _purecall should not happen.

But after seeing how the constructor is implemented, I see CConnection constructor sets up the pointer to the v-table which includes the call to _purecall and then, CSocket's constructor overwrites this value with the correct/derived v-table.

This is what I suspect is happening:

  1. A thread calls to new CSocket.
  2. Before CSocket constructor is called and the v-table modified, the worker thread reads some memory near the pointer (probably because it is processing an operation of other CSocket instance) and that memory page is "cached" by the processor.
  3. The thread creating CSocket continues its execution finishing CSocket construction.
  4. When the worker thread accesses the v-table, reads the value from the "cached" page instead of the real memory containing the correct v-table.

At first glance there is no memory barrier inserted by the compiler to avoid this.

Am I correct in my assumption? Is it possible to happen or the compiler/processor has a mechanism to avoid this?

0

There are 0 answers