Skip to content

Commit 15bd399

Browse files
Meghana Guptaaneeshdk
authored andcommitted
[CVE-2018-8380] Edge - Incorrect callinfo on inlineeFrame on an exception - Google, Inc
1 parent 2c4085b commit 15bd399

File tree

7 files changed

+45
-45
lines changed

7 files changed

+45
-45
lines changed

lib/Runtime/Base/ThreadContext.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ ThreadContext::ThreadContext(AllocationPolicyManager * allocationPolicyManager,
124124
entryExitRecord(nullptr),
125125
leafInterpreterFrame(nullptr),
126126
threadServiceWrapper(nullptr),
127-
tryCatchFrameAddr(nullptr),
127+
tryHandlerAddrOfReturnAddr(nullptr),
128128
temporaryArenaAllocatorCount(0),
129129
temporaryGuestArenaAllocatorCount(0),
130130
crefSContextForDiag(0),

lib/Runtime/Base/ThreadContext.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -667,7 +667,7 @@ class ThreadContext sealed :
667667
ThreadServiceWrapper* threadServiceWrapper;
668668
uint functionCount;
669669
uint sourceInfoCount;
670-
void * tryCatchFrameAddr;
670+
void * tryHandlerAddrOfReturnAddr;
671671
enum RedeferralState
672672
{
673673
InitialRedeferralState,
@@ -1268,8 +1268,8 @@ class ThreadContext sealed :
12681268
uint EnterScriptStart(Js::ScriptEntryExitRecord *, bool doCleanup);
12691269
void EnterScriptEnd(Js::ScriptEntryExitRecord *, bool doCleanup);
12701270

1271-
void * GetTryCatchFrameAddr() { return this->tryCatchFrameAddr; }
1272-
void SetTryCatchFrameAddr(void * frameAddr) { this->tryCatchFrameAddr = frameAddr; }
1271+
void * GetTryHandlerAddrOfReturnAddr() { return this->tryHandlerAddrOfReturnAddr; }
1272+
void SetTryHandlerAddrOfReturnAddr(void * addrOfReturnAddr) { this->tryHandlerAddrOfReturnAddr = addrOfReturnAddr; }
12731273

12741274
template <bool leaveForHost>
12751275
void LeaveScriptStart(void *);

lib/Runtime/Language/InterpreterStackFrame.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6492,6 +6492,8 @@ namespace Js
64926492
this->OrFlags(InterpreterStackFrameFlags_WithinTryBlock);
64936493

64946494
Js::JavascriptExceptionOperators::AutoCatchHandlerExists autoCatchHandlerExists(scriptContext);
6495+
void * addrOfReturnAddr = _AddressOfReturnAddress();
6496+
Js::JavascriptExceptionOperators::TryHandlerAddrOfReturnAddrStack tryHandlerAddrOfReturnAddrStack(scriptContext, addrOfReturnAddr);
64956497

64966498
#ifdef ENABLE_SCRIPT_DEBUGGING
64976499
if (this->IsInDebugMode())

lib/Runtime/Language/JavascriptExceptionOperators.cpp

Lines changed: 29 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -69,16 +69,16 @@ namespace Js
6969
m_threadContext->SetIsUserCode(m_previousCatchHandlerToUserCodeStatus);
7070
}
7171

72-
JavascriptExceptionOperators::TryCatchFrameAddrStack::TryCatchFrameAddrStack(ScriptContext* scriptContext, void *frameAddr)
72+
JavascriptExceptionOperators::TryHandlerAddrOfReturnAddrStack::TryHandlerAddrOfReturnAddrStack(ScriptContext* scriptContext, void *addrOfReturnAddr)
7373
{
7474
m_threadContext = scriptContext->GetThreadContext();
75-
m_prevTryCatchFrameAddr = m_threadContext->GetTryCatchFrameAddr();
76-
scriptContext->GetThreadContext()->SetTryCatchFrameAddr(frameAddr);
75+
m_prevTryHandlerAddrOfReturnAddr = m_threadContext->GetTryHandlerAddrOfReturnAddr();
76+
scriptContext->GetThreadContext()->SetTryHandlerAddrOfReturnAddr(addrOfReturnAddr);
7777
}
7878

79-
JavascriptExceptionOperators::TryCatchFrameAddrStack::~TryCatchFrameAddrStack()
79+
JavascriptExceptionOperators::TryHandlerAddrOfReturnAddrStack::~TryHandlerAddrOfReturnAddrStack()
8080
{
81-
m_threadContext->SetTryCatchFrameAddr(m_prevTryCatchFrameAddr);
81+
m_threadContext->SetTryHandlerAddrOfReturnAddr(m_prevTryHandlerAddrOfReturnAddr);
8282
}
8383

8484
JavascriptExceptionOperators::HasBailedOutPtrStack::HasBailedOutPtrStack(ScriptContext* scriptContext, bool *hasBailedOutPtr)
@@ -125,13 +125,14 @@ namespace Js
125125
{
126126
void *continuation = nullptr;
127127
JavascriptExceptionObject *exception = nullptr;
128-
void *tryCatchFrameAddr = nullptr;
128+
void *tryHandlerAddrOfReturnAddr = nullptr;
129129

130130
Js::JavascriptExceptionOperators::HasBailedOutPtrStack hasBailedOutPtrStack(scriptContext, (bool*)((char*)frame + hasBailedOutOffset));
131131

132132
PROBE_STACK(scriptContext, Constants::MinStackJitEHBailout + spillSize + argsSize);
133133
{
134-
Js::JavascriptExceptionOperators::TryCatchFrameAddrStack tryCatchFrameAddrStack(scriptContext, frame);
134+
void * addrOfReturnAddr = (void*)((char*)frame + sizeof(char*));
135+
Js::JavascriptExceptionOperators::TryHandlerAddrOfReturnAddrStack tryHandlerAddrOfReturnAddrStack(scriptContext, addrOfReturnAddr);
135136
try
136137
{
137138
Js::JavascriptExceptionOperators::AutoCatchHandlerExists autoCatchHandlerExists(scriptContext);
@@ -140,8 +141,7 @@ namespace Js
140141
catch (const Js::JavascriptException& err)
141142
{
142143
exception = err.GetAndClear();
143-
tryCatchFrameAddr = scriptContext->GetThreadContext()->GetTryCatchFrameAddr();
144-
Assert(frame == tryCatchFrameAddr);
144+
tryHandlerAddrOfReturnAddr = scriptContext->GetThreadContext()->GetTryHandlerAddrOfReturnAddr();
145145
}
146146
}
147147
if (exception)
@@ -157,7 +157,7 @@ namespace Js
157157
#if ENABLE_NATIVE_CODEGEN
158158
if (exception->GetExceptionContext() && exception->GetExceptionContext()->ThrowingFunction())
159159
{
160-
WalkStackForCleaningUpInlineeInfo(scriptContext, nullptr /* start stackwalk from the current frame */, tryCatchFrameAddr);
160+
WalkStackForCleaningUpInlineeInfo(scriptContext, nullptr /* start stackwalk from the current frame */, tryHandlerAddrOfReturnAddr);
161161
}
162162
#endif
163163

@@ -212,11 +212,11 @@ namespace Js
212212
if (exception)
213213
{
214214
#if ENABLE_NATIVE_CODEGEN
215-
if (scriptContext->GetThreadContext()->GetTryCatchFrameAddr() != nullptr)
215+
if (scriptContext->GetThreadContext()->GetTryHandlerAddrOfReturnAddr() != nullptr)
216216
{
217217
if (exception->GetExceptionContext() && exception->GetExceptionContext()->ThrowingFunction())
218218
{
219-
WalkStackForCleaningUpInlineeInfo(scriptContext, nullptr /* start stackwalk from the current frame */, scriptContext->GetThreadContext()->GetTryCatchFrameAddr());
219+
WalkStackForCleaningUpInlineeInfo(scriptContext, nullptr /* start stackwalk from the current frame */, scriptContext->GetThreadContext()->GetTryHandlerAddrOfReturnAddr());
220220
}
221221
}
222222
else
@@ -295,13 +295,13 @@ namespace Js
295295
{
296296
void *continuation = nullptr;
297297
JavascriptExceptionObject *exception = nullptr;
298-
void * tryCatchFrameAddr = nullptr;
298+
void * tryHandlerAddrOfReturnAddr = nullptr;
299299
Js::JavascriptExceptionOperators::HasBailedOutPtrStack hasBailedOutPtrStack(scriptContext, (bool*)((char*)localsPtr + hasBailedOutOffset));
300300

301301
PROBE_STACK(scriptContext, Constants::MinStackJitEHBailout + argsSize);
302302
{
303-
Js::JavascriptExceptionOperators::TryCatchFrameAddrStack tryCatchFrameAddrStack(scriptContext, framePtr);
304-
303+
void * addrOfReturnAddr = (void*)((char*)framePtr + sizeof(char*));
304+
Js::JavascriptExceptionOperators::TryHandlerAddrOfReturnAddrStack tryHandlerAddrOfReturnAddrStack(scriptContext, addrOfReturnAddr);
305305
try
306306
{
307307
Js::JavascriptExceptionOperators::AutoCatchHandlerExists autoCatchHandlerExists(scriptContext);
@@ -314,8 +314,7 @@ namespace Js
314314
catch (const Js::JavascriptException& err)
315315
{
316316
exception = err.GetAndClear();
317-
tryCatchFrameAddr = scriptContext->GetThreadContext()->GetTryCatchFrameAddr();
318-
Assert(framePtr == tryCatchFrameAddr);
317+
tryHandlerAddrOfReturnAddr = scriptContext->GetThreadContext()->GetTryHandlerAddrOfReturnAddr();
319318
}
320319
}
321320

@@ -332,7 +331,7 @@ namespace Js
332331
#if ENABLE_NATIVE_CODEGEN
333332
if (exception->GetExceptionContext() && exception->GetExceptionContext()->ThrowingFunction())
334333
{
335-
WalkStackForCleaningUpInlineeInfo(scriptContext, nullptr /* start stackwalk from the current frame */, tryCatchFrameAddr);
334+
WalkStackForCleaningUpInlineeInfo(scriptContext, nullptr /* start stackwalk from the current frame */, tryHandlerAddrOfReturnAddr);
336335
}
337336
#endif
338337
exception = exception->CloneIfStaticExceptionObject(scriptContext);
@@ -387,11 +386,11 @@ namespace Js
387386
if (exception)
388387
{
389388
#if ENABLE_NATIVE_CODEGEN
390-
if (scriptContext->GetThreadContext()->GetTryCatchFrameAddr() != nullptr)
389+
if (scriptContext->GetThreadContext()->GetTryHandlerAddrOfReturnAddr() != nullptr)
391390
{
392391
if (exception->GetExceptionContext() && exception->GetExceptionContext()->ThrowingFunction())
393392
{
394-
WalkStackForCleaningUpInlineeInfo(scriptContext, nullptr /* start stackwalk from the current frame */, scriptContext->GetThreadContext()->GetTryCatchFrameAddr());
393+
WalkStackForCleaningUpInlineeInfo(scriptContext, nullptr /* start stackwalk from the current frame */, scriptContext->GetThreadContext()->GetTryHandlerAddrOfReturnAddr());
395394
}
396395
}
397396
else
@@ -486,14 +485,14 @@ namespace Js
486485
{
487486
void* continuationAddr = NULL;
488487
Js::JavascriptExceptionObject* pExceptionObject = NULL;
489-
void *tryCatchFrameAddr = nullptr;
488+
void *tryHandlerAddrOfReturnAddr = nullptr;
490489

491490
Js::JavascriptExceptionOperators::HasBailedOutPtrStack hasBailedOutPtrStack(scriptContext, (bool*)((char*)framePtr + hasBailedOutOffset));
492491

493492
PROBE_STACK(scriptContext, Constants::MinStackJitEHBailout);
494493
{
495-
Js::JavascriptExceptionOperators::TryCatchFrameAddrStack tryCatchFrameAddrStack(scriptContext, framePtr);
496-
494+
void * addrOfReturnAddr = (void*)((char*)framePtr + sizeof(char*));
495+
Js::JavascriptExceptionOperators::TryHandlerAddrOfReturnAddrStack tryHandlerAddrOfReturnAddrStack(scriptContext, addrOfReturnAddr);
497496
try
498497
{
499498
Js::JavascriptExceptionOperators::AutoCatchHandlerExists autoCatchHandlerExists(scriptContext);
@@ -557,8 +556,7 @@ namespace Js
557556
catch (const Js::JavascriptException& err)
558557
{
559558
pExceptionObject = err.GetAndClear();
560-
tryCatchFrameAddr = scriptContext->GetThreadContext()->GetTryCatchFrameAddr();
561-
Assert(framePtr == tryCatchFrameAddr);
559+
tryHandlerAddrOfReturnAddr = scriptContext->GetThreadContext()->GetTryHandlerAddrOfReturnAddr();
562560
}
563561
}
564562

@@ -576,7 +574,7 @@ namespace Js
576574
#if ENABLE_NATIVE_CODEGEN
577575
if (pExceptionObject->GetExceptionContext() && pExceptionObject->GetExceptionContext()->ThrowingFunction())
578576
{
579-
WalkStackForCleaningUpInlineeInfo(scriptContext, nullptr /* start stackwalk from the current frame */, tryCatchFrameAddr);
577+
WalkStackForCleaningUpInlineeInfo(scriptContext, nullptr /* start stackwalk from the current frame */, tryHandlerAddrOfReturnAddr);
580578
}
581579
#endif
582580
pExceptionObject = pExceptionObject->CloneIfStaticExceptionObject(scriptContext);
@@ -722,11 +720,11 @@ namespace Js
722720
if (pExceptionObject)
723721
{
724722
#if ENABLE_NATIVE_CODEGEN
725-
if (scriptContext->GetThreadContext()->GetTryCatchFrameAddr() != nullptr)
723+
if (scriptContext->GetThreadContext()->GetTryHandlerAddrOfReturnAddr() != nullptr)
726724
{
727725
if (pExceptionObject->GetExceptionContext() && pExceptionObject->GetExceptionContext()->ThrowingFunction())
728726
{
729-
WalkStackForCleaningUpInlineeInfo(scriptContext, nullptr /* start stackwalk from the current frame */, scriptContext->GetThreadContext()->GetTryCatchFrameAddr());
727+
WalkStackForCleaningUpInlineeInfo(scriptContext, nullptr /* start stackwalk from the current frame */, scriptContext->GetThreadContext()->GetTryHandlerAddrOfReturnAddr());
730728
}
731729
}
732730
else
@@ -1053,14 +1051,14 @@ namespace Js
10531051
}
10541052
#if ENABLE_NATIVE_CODEGEN
10551053
// TODO: Add code address of throwing function on exception context, and use that for returnAddress instead of passing nullptr which starts stackwalk from the top
1056-
void JavascriptExceptionOperators::WalkStackForCleaningUpInlineeInfo(ScriptContext *scriptContext, PVOID returnAddress, PVOID tryCatchFrameAddr)
1054+
void JavascriptExceptionOperators::WalkStackForCleaningUpInlineeInfo(ScriptContext *scriptContext, PVOID returnAddress, PVOID tryHandlerAddrOfReturnAddr)
10571055
{
1058-
Assert(tryCatchFrameAddr != nullptr);
1056+
Assert(tryHandlerAddrOfReturnAddr != nullptr);
10591057
JavascriptStackWalker walker(scriptContext, /*useEERContext*/ true, returnAddress);
10601058

10611059
// We have to walk the inlinee frames and clear callinfo count on them on an exception
10621060
// At this point inlinedFrameWalker is closed, so we should build it again by calling InlinedFrameWalker::FromPhysicalFrame
1063-
walker.WalkAndClearInlineeFrameCallInfoOnException(tryCatchFrameAddr);
1061+
walker.WalkAndClearInlineeFrameCallInfoOnException(tryHandlerAddrOfReturnAddr);
10641062
}
10651063
#endif
10661064
void

lib/Runtime/Language/JavascriptExceptionOperators.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,15 @@ namespace Js
4343
~AutoCatchHandlerExists();
4444
};
4545

46-
class TryCatchFrameAddrStack
46+
class TryHandlerAddrOfReturnAddrStack
4747
{
4848
private:
49-
void * m_prevTryCatchFrameAddr;
49+
void * m_prevTryHandlerAddrOfReturnAddr;
5050
ThreadContext* m_threadContext;
5151

5252
public:
53-
TryCatchFrameAddrStack(ScriptContext* scriptContext, void *frameAddr);
54-
~TryCatchFrameAddrStack();
53+
TryHandlerAddrOfReturnAddrStack(ScriptContext* scriptContext, void *addrOfReturnAddr);
54+
~TryHandlerAddrOfReturnAddrStack();
5555
};
5656

5757
class HasBailedOutPtrStack

lib/Runtime/Language/JavascriptStackWalker.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,7 @@ namespace Js
632632
return nullptr;
633633
}
634634
#if ENABLE_NATIVE_CODEGEN
635-
void JavascriptStackWalker::WalkAndClearInlineeFrameCallInfoOnException(void *tryCatchFrameAddr)
635+
void JavascriptStackWalker::WalkAndClearInlineeFrameCallInfoOnException(void *tryHandlerAddrOfReturnAddr)
636636
{
637637
// Walk the stack and when we find the first native frame, we clear the inlinee's callinfo for this frame
638638
// It is sufficient we stop at the first native frame which had the enclosing try-catch
@@ -649,10 +649,10 @@ namespace Js
649649
inlinedFrame->callInfo.Clear();
650650
}
651651
}
652-
if (this->currentFrame.GetFrame() == tryCatchFrameAddr)
653-
{
654-
break;
655-
}
652+
}
653+
if (this->currentFrame.GetAddressOfReturnAddress() == tryHandlerAddrOfReturnAddr)
654+
{
655+
break;
656656
}
657657
}
658658
}

lib/Runtime/Language/JavascriptStackWalker.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ namespace Js
237237
void ClearCachedInternalFrameInfo();
238238
void SetCachedInternalFrameInfo(InternalFrameType frameType, JavascriptFunction* function, bool hasInlinedFramesOnStack, bool prevIntFrameIsFromBailout);
239239
InternalFrameInfo GetCachedInternalFrameInfo() const { return this->lastInternalFrameInfo; }
240-
void WalkAndClearInlineeFrameCallInfoOnException(void *tryCatchFrameAddr);
240+
void WalkAndClearInlineeFrameCallInfoOnException(void *tryHandlerAddrOfReturnAddr);
241241
#endif
242242
bool IsCurrentPhysicalFrameForLoopBody() const;
243243

0 commit comments

Comments
 (0)