Procházet zdrojové kódy

[CVE-2018-8315] Add guards for speculation on non-jit operations

Derek Morris před 7 roky
rodič
revize
e03b3e3016

+ 1 - 0
lib/Runtime/Language/JavascriptOperators.cpp

@@ -3809,6 +3809,7 @@ CommonNumber:
 
     Var JavascriptOperators::OP_GetElementI(Var instance, Var index, ScriptContext* scriptContext)
     {
+        instance = BreakSpeculation(instance);
         if (TaggedInt::Is(index))
         {
             return GetElementIIntIndex(instance, index, scriptContext);

+ 17 - 0
lib/Runtime/Library/JavascriptFunction.cpp

@@ -1155,6 +1155,18 @@ using namespace Js;
     template Var JavascriptFunction::CallFunction<false>(RecyclableObject* function, JavascriptMethod entryPoint, Arguments args, bool useLargeArgCount);
 
 #if _M_IX86
+    extern "C" Var BreakSpeculation(Var passthrough)
+    {
+        Var result = nullptr;
+        __asm
+        {
+            mov ecx, passthrough;
+            cmp ecx, ecx;
+            cmove eax, ecx;
+            mov result, eax;
+        }
+        return result;
+    }
 #ifdef ASMJS_PLAT
     template <> int JavascriptFunction::CallAsmJsFunction<int>(RecyclableObject * function, JavascriptMethod entryPoint, Var * argv, uint argsSize, byte* reg)
     {
@@ -1350,6 +1362,11 @@ dbl_align:
         extern Var arm_CallFunction(JavascriptFunction* function, CallInfo info, uint argCount, Var* values, JavascriptMethod entryPoint);
     }
 
+    extern "C" Var BreakSpeculation(Var passthrough)
+    {
+        return passthrough;
+    }
+
     template <bool doStackProbe>
     Var JavascriptFunction::CallFunction(RecyclableObject* function, JavascriptMethod entryPoint, Arguments args, bool useLargeArgCount)
     {

+ 2 - 0
lib/Runtime/Library/JavascriptFunction.h

@@ -34,6 +34,8 @@ namespace Js
    extern "C" Var amd64_CallFunction(RecyclableObject *function, JavascriptMethod entryPoint, CallInfo callInfo, uint argc, Var *argv);
 #endif
 
+    extern "C" Var BreakSpeculation(Var passthroughObject);
+
     class JavascriptFunction : public DynamicObject
     {
     private:

+ 9 - 1
lib/Runtime/Library/JavascriptString.cpp

@@ -747,6 +747,7 @@ case_2:
         Var value;
         if (pThis->GetItemAt(idxPosition, &value))
         {
+            value = BreakSpeculation(value);
             return value;
         }
         else
@@ -795,7 +796,7 @@ case_2:
             return scriptContext->GetLibrary()->GetNaN();
         }
 
-        return TaggedInt::ToVarUnchecked(pThis->GetItem(idxPosition));
+        return BreakSpeculation(TaggedInt::ToVarUnchecked(pThis->GetItem(idxPosition)));
     }
 
     Var JavascriptString::EntryCodePointAt(RecyclableObject* function, CallInfo callInfo, ...)
@@ -1849,6 +1850,9 @@ case_2:
         {
             idxEnd = idxStart;
         }
+
+        pThis = (JavascriptString*)BreakSpeculation(pThis);
+
         return SubstringCore(pThis, idxStart, idxEnd - idxStart, scriptContext);
     }
 
@@ -1968,6 +1972,8 @@ case_2:
             return pThis;
         }
 
+        pThis = (JavascriptString*)BreakSpeculation(pThis);
+
         return SubstringCore(pThis, idxStart, idxEnd - idxStart, scriptContext);
     }
 
@@ -2024,6 +2030,8 @@ case_2:
             return pThis;
         }
 
+        pThis = (JavascriptString*)BreakSpeculation(pThis);
+
         Assert(0 <= idxStart && idxStart <= idxEnd && idxEnd <= len);
         return SubstringCore(pThis, idxStart, idxEnd - idxStart, scriptContext);
     }

+ 7 - 0
lib/Runtime/Library/amd64/JavascriptFunctionA.S

@@ -235,3 +235,10 @@ NESTED_ENTRY _ZN2Js18JavascriptFunction24DeferredDeserializeThunkEPNS_16Recyclab
         jmp rax
 
 NESTED_END _ZN2Js18JavascriptFunction24DeferredDeserializeThunkEPNS_16RecyclableObjectENS_8CallInfoEz, _TEXT
+
+.balign 16
+NESTED_ENTRY BreakSpeculation, _TEXT, NoHandler
+        cmp rdi, rdi
+        cmove rax, rdi
+        ret
+NESTED_END BreakSpeculation, _TEXT

+ 7 - 0
lib/Runtime/Library/amd64/JavascriptFunctionA.asm

@@ -411,5 +411,12 @@ endif
         rex_jmp_reg rax
 ?DeferredDeserializeThunk@JavascriptFunction@Js@@SAPEAXPEAVRecyclableObject@2@UCallInfo@2@ZZ ENDP
 
+align 16
+BreakSpeculation PROC
+        cmp rcx, rcx
+        cmove rax, rcx
+        ret
+BreakSpeculation ENDP
+
         _TEXT ENDS
         end

+ 6 - 0
lib/Runtime/Library/arm64/arm64_CallFunction.asm

@@ -96,4 +96,10 @@ CopyLoop
 
     NESTED_END
 
+    NESTED_ENTRY BreakSpeculation
+    cmp x0, x0
+    cseleq x0, x0, x0
+    ret
+    NESTED_END
+
     END