Skip to content

Commit e03b3e3

Browse files
PenguinwizzardMikeHolman
authored andcommitted
[CVE-2018-8315] Add guards for speculation on non-jit operations
1 parent 3f35448 commit e03b3e3

File tree

7 files changed

+49
-1
lines changed

7 files changed

+49
-1
lines changed

lib/Runtime/Language/JavascriptOperators.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3809,6 +3809,7 @@ using namespace Js;
38093809

38103810
Var JavascriptOperators::OP_GetElementI(Var instance, Var index, ScriptContext* scriptContext)
38113811
{
3812+
instance = BreakSpeculation(instance);
38123813
if (TaggedInt::Is(index))
38133814
{
38143815
return GetElementIIntIndex(instance, index, scriptContext);

lib/Runtime/Library/JavascriptFunction.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1155,6 +1155,18 @@ using namespace Js;
11551155
template Var JavascriptFunction::CallFunction<false>(RecyclableObject* function, JavascriptMethod entryPoint, Arguments args, bool useLargeArgCount);
11561156

11571157
#if _M_IX86
1158+
extern "C" Var BreakSpeculation(Var passthrough)
1159+
{
1160+
Var result = nullptr;
1161+
__asm
1162+
{
1163+
mov ecx, passthrough;
1164+
cmp ecx, ecx;
1165+
cmove eax, ecx;
1166+
mov result, eax;
1167+
}
1168+
return result;
1169+
}
11581170
#ifdef ASMJS_PLAT
11591171
template <> int JavascriptFunction::CallAsmJsFunction<int>(RecyclableObject * function, JavascriptMethod entryPoint, Var * argv, uint argsSize, byte* reg)
11601172
{
@@ -1350,6 +1362,11 @@ void __cdecl _alloca_probe_16()
13501362
extern Var arm_CallFunction(JavascriptFunction* function, CallInfo info, uint argCount, Var* values, JavascriptMethod entryPoint);
13511363
}
13521364

1365+
extern "C" Var BreakSpeculation(Var passthrough)
1366+
{
1367+
return passthrough;
1368+
}
1369+
13531370
template <bool doStackProbe>
13541371
Var JavascriptFunction::CallFunction(RecyclableObject* function, JavascriptMethod entryPoint, Arguments args, bool useLargeArgCount)
13551372
{

lib/Runtime/Library/JavascriptFunction.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ namespace Js
3434
extern "C" Var amd64_CallFunction(RecyclableObject *function, JavascriptMethod entryPoint, CallInfo callInfo, uint argc, Var *argv);
3535
#endif
3636

37+
extern "C" Var BreakSpeculation(Var passthroughObject);
38+
3739
class JavascriptFunction : public DynamicObject
3840
{
3941
private:

lib/Runtime/Library/JavascriptString.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -747,6 +747,7 @@ namespace Js
747747
Var value;
748748
if (pThis->GetItemAt(idxPosition, &value))
749749
{
750+
value = BreakSpeculation(value);
750751
return value;
751752
}
752753
else
@@ -795,7 +796,7 @@ namespace Js
795796
return scriptContext->GetLibrary()->GetNaN();
796797
}
797798

798-
return TaggedInt::ToVarUnchecked(pThis->GetItem(idxPosition));
799+
return BreakSpeculation(TaggedInt::ToVarUnchecked(pThis->GetItem(idxPosition)));
799800
}
800801

801802
Var JavascriptString::EntryCodePointAt(RecyclableObject* function, CallInfo callInfo, ...)
@@ -1849,6 +1850,9 @@ namespace Js
18491850
{
18501851
idxEnd = idxStart;
18511852
}
1853+
1854+
pThis = (JavascriptString*)BreakSpeculation(pThis);
1855+
18521856
return SubstringCore(pThis, idxStart, idxEnd - idxStart, scriptContext);
18531857
}
18541858

@@ -1968,6 +1972,8 @@ namespace Js
19681972
return pThis;
19691973
}
19701974

1975+
pThis = (JavascriptString*)BreakSpeculation(pThis);
1976+
19711977
return SubstringCore(pThis, idxStart, idxEnd - idxStart, scriptContext);
19721978
}
19731979

@@ -2024,6 +2030,8 @@ namespace Js
20242030
return pThis;
20252031
}
20262032

2033+
pThis = (JavascriptString*)BreakSpeculation(pThis);
2034+
20272035
Assert(0 <= idxStart && idxStart <= idxEnd && idxEnd <= len);
20282036
return SubstringCore(pThis, idxStart, idxEnd - idxStart, scriptContext);
20292037
}

lib/Runtime/Library/amd64/JavascriptFunctionA.S

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,3 +235,10 @@ NESTED_ENTRY _ZN2Js18JavascriptFunction24DeferredDeserializeThunkEPNS_16Recyclab
235235
jmp rax
236236

237237
NESTED_END _ZN2Js18JavascriptFunction24DeferredDeserializeThunkEPNS_16RecyclableObjectENS_8CallInfoEz, _TEXT
238+
239+
.balign 16
240+
NESTED_ENTRY BreakSpeculation, _TEXT, NoHandler
241+
cmp rdi, rdi
242+
cmove rax, rdi
243+
ret
244+
NESTED_END BreakSpeculation, _TEXT

lib/Runtime/Library/amd64/JavascriptFunctionA.asm

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,5 +411,12 @@ endif
411411
rex_jmp_reg rax
412412
?DeferredDeserializeThunk@JavascriptFunction@Js@@SAPEAXPEAVRecyclableObject@2@UCallInfo@2@ZZ ENDP
413413

414+
align 16
415+
BreakSpeculation PROC
416+
cmp rcx, rcx
417+
cmove rax, rcx
418+
ret
419+
BreakSpeculation ENDP
420+
414421
_TEXT ENDS
415422
end

lib/Runtime/Library/arm64/arm64_CallFunction.asm

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,4 +96,10 @@ CopyLoop
9696

9797
NESTED_END
9898

99+
NESTED_ENTRY BreakSpeculation
100+
cmp x0, x0
101+
cseleq x0, x0, x0
102+
ret
103+
NESTED_END
104+
99105
END

0 commit comments

Comments
 (0)