Pārlūkot izejas kodu

[CVE-2019-0644] Chakra - AV due to type confusion - Individual - Given a split scope (a function has both a param and body scope), then it is required that the body and param scope are marked as both requiring either a scope object or a scope slot. This was not being enforced in Scope::SetIsObject(). This led to an AV in the interpreter when accessing a property because StLocalSlot was used instead of StLocalObjSlot.

wyrichte 7 gadi atpakaļ
vecāks
revīzija
5f6dea1642

+ 6 - 0
lib/Runtime/ByteCode/ByteCodeGenerator.cpp

@@ -2944,6 +2944,12 @@ FuncInfo* PostVisitFunction(ParseNodeFnc* pnodeFnc, ByteCodeGenerator* byteCodeG
         Scope::MergeParamAndBodyScopes(pnodeFnc);
         Scope::RemoveParamScope(pnodeFnc);
     }
+    else
+    {
+        // A param and body scope exist for the same function, they
+        // should both either be using scope slots or scope objects.
+        Assert_FailFast(top->bodyScope->GetIsObject() == top->paramScope->GetIsObject());
+    }
 
     FuncInfo* const parentFunc = byteCodeGenerator->TopFuncInfo();
 

+ 10 - 3
lib/Runtime/ByteCode/Scope.cpp

@@ -69,11 +69,18 @@ void Scope::SetIsObject()
         });
     }
 
-    if (this->GetScopeType() == ScopeType_FunctionBody && funcInfo && !funcInfo->IsBodyAndParamScopeMerged()
-         && funcInfo->paramScope && !funcInfo->paramScope->GetIsObject())
+    // If the scope is split (there exists a body and param scope), then it is required that the
+    // body and param scope are marked as both requiring either a scope object or a scope slot.
+    if ((this->GetScopeType() == ScopeType_FunctionBody || this->GetScopeType() == ScopeType_Parameter)
+        && funcInfo && !funcInfo->IsBodyAndParamScopeMerged())
     {
-        // If this is split scope then mark the param scope also as an object
+        // The scope is split and one of the scopes (param or body) is being set 
+        // as an object, therefore set both the param and body scopes as objects.
+        Assert(funcInfo->paramScope);
         funcInfo->paramScope->SetIsObject();
+
+        Assert(funcInfo->bodyScope);
+        funcInfo->bodyScope->SetIsObject();
     }
 }