Game Development Community

T3D 1.1 Final - StringStack memory corruption with fix (all engines affected) - RESOLVED (THREED-2465)

by Fyodor -bank- Osokin · in Torque 3D Professional · 08/11/2011 (7:29 am) · 3 replies

IMPORTANT: This applies to all engines!
Including T3D, TGEA, iTorque2D (all versions), TGB, TGE.

The old good TGE/T2D/TGB have this too, but doesn't crash due to the different logic in void StringStack::getArgcArgv, but the memory corruption is still there -- good that it doesn't lead to anything bad.

Build: Any

Platform: Any

Target: StringStack routine

Issues:
Torque crashes when calling a console function with more than 20 args.

Steps to Repeat:
Call the function with 21 args, like:
%obj.schedule(0, doStuff, %type, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13, %a14, %a15, %a16, %a17, %a18);
Crash!

Suggested Fix:

Inside void StringStack::getArgcArgv()
we have:
U32 argCount   = getMin(mStartStackSize - startStack, (U32)MaxArgs);
and later in for loop:

mArgV[i+1] = mBuffer + mStartOffsets[startStack + i];

if we pass more than 20 args, the argCount will be 20 (getMin!!!), but in loop we assigning i+1, which means memory corruption!

The fix:

U32 argCount   = getMin(mStartStackSize - startStack, (U32)MaxArgs - 1);

Btw, in CodeBlock::exec()
the U32 callArgc; is not initialized to anything by default, so making it
U32 callArgc = 0; is could be good idea. Had some headaches because of that while trying to debug this memory corruption issue.

#1
08/11/2011 (9:50 am)
I've went ahead and logged a ticket for this issue under THREED-2465. Thanks for the find Fyodor Osokin.
#2
08/11/2011 (10:30 am)
Oh, forgot to tell where it crashes.
After setting "ahead" for mArgV[i+1], the data in mFrameOffsets[] gets corrupted, as it declared right after mArgV[]:
struct StringStack
{
..//skipped
   const char *mArgV[MaxArgs];
   U32 mFrameOffsets[MaxStackDepth];
   U32 mStartOffsets[MaxStackDepth];
..//skipped
so, when we get into:
// This one
   void popFrame()
   {
      mStartStackSize = mFrameOffsets[--mNumFrames];
      mStart = mStartOffsets[mStartStackSize];
      mLen = 0;
   }
the mStartStackSize have some crazy values (way off the 0<x<1023 limit), so then it tries to set mStart we are getting out of bounds.
#3
10/11/2011 (3:31 pm)
Fixed in 1.2.