VYPR
Critical severity9.8NVD Advisory· Published May 15, 2017· Updated May 13, 2026

CVE-2017-0252

CVE-2017-0252

Description

A remote code execution vulnerability exists in Microsoft Chakra Core in the way JavaScript engines render when handling objects in memory. aka "Scripting Engine Memory Corruption Vulnerability". This vulnerability is unique from CVE-2017-0223.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
Microsoft.ChakraCoreNuGet
< 1.4.41.4.4

Affected products

2
  • cpe:2.3:a:microsoft:edge:-:*:*:*:*:*:*:*
  • Microsoft Corporation/Chakra Corev5
    Range: n/a

Patches

1
f95aa762f89a

[CVE-2017-0252] CopyNativeIntArrayElementsToVar overflow

https://github.com/chakra-core/ChakraCoreSuwei ChenMay 9, 2017via ghsa
4 files changed · +39 33
  • lib/Runtime/Library/JavascriptArray.cpp+15 9 modified
    @@ -3066,7 +3066,7 @@ namespace Js
                 }
     
                 if (pDestArray && JavascriptArray::IsDirectAccessArray(aItem) && JavascriptArray::IsDirectAccessArray(pDestArray)
    -                && BigIndex(idxDest + JavascriptArray::FromVar(aItem)->length).IsSmallIndex()) // Fast path
    +                && BigIndex(idxDest + JavascriptArray::FromVar(aItem)->length).IsSmallIndex() && !JavascriptArray::FromVar(aItem)->IsFillFromPrototypes()) // Fast path
                 {
                     if (JavascriptNativeIntArray::Is(aItem))
                     {
    @@ -3200,10 +3200,11 @@ namespace Js
             for (uint idxArg = 0; idxArg < args.Info.Count; idxArg++)
             {
                 Var aItem = args[idxArg];
    +            BOOL isConcatSpreadable = false;
     
                 if (scriptContext->GetConfig()->IsES6IsConcatSpreadableEnabled())
                 {
    -                JS_REENTRANT(jsReentLock, BOOL isConcatSpreadable = JavascriptOperators::IsConcatSpreadable(aItem));
    +                JS_REENTRANT(jsReentLock, isConcatSpreadable = JavascriptOperators::IsConcatSpreadable(aItem));
                     if (!JavascriptNativeIntArray::Is(pDestArray))
                     {
                         ConcatArgs<uint>(pDestArray, remoteTypeIds, args, scriptContext, idxArg, idxDest);
    @@ -3222,7 +3223,7 @@ namespace Js
                     }
                 }
     
    -            if (JavascriptNativeIntArray::Is(aItem)) // Fast path
    +            if (JavascriptNativeIntArray::Is(aItem) && !JavascriptNativeIntArray::FromVar(aItem)->IsFillFromPrototypes()) // Fast path
                 {
                     JavascriptNativeIntArray* pItemArray = JavascriptNativeIntArray::FromVar(aItem);
                     
    @@ -3258,7 +3259,9 @@ namespace Js
                 else
                 {
                     JavascriptArray *pVarDestArray = JavascriptNativeIntArray::ConvertToVarArray(pDestArray);
    -                JS_REENTRANT(jsReentLock, ConcatArgs<uint>(pVarDestArray, remoteTypeIds, args, scriptContext, idxArg, idxDest));
    +                BigIndex length;
    +                JS_REENTRANT(jsReentLock, length = OP_GetLength(aItem, scriptContext),
    +                    ConcatArgs<uint>(pVarDestArray, remoteTypeIds, args, scriptContext, idxArg, idxDest, isConcatSpreadable, length));
                     return pVarDestArray;
                 }
             }
    @@ -3276,10 +3279,11 @@ namespace Js
             for (uint idxArg = 0; idxArg < args.Info.Count; idxArg++)
             {
                 Var aItem = args[idxArg];
    +            BOOL isConcatSpreadable = false;
     
                 if (scriptContext->GetConfig()->IsES6IsConcatSpreadableEnabled())
                 {
    -                JS_REENTRANT(jsReentLock, BOOL isConcatSpreadable = JavascriptOperators::IsConcatSpreadable(aItem));
    +                JS_REENTRANT(jsReentLock, isConcatSpreadable = JavascriptOperators::IsConcatSpreadable(aItem));
                     if (!JavascriptNativeFloatArray::Is(pDestArray))
                     {
                         ConcatArgs<uint>(pDestArray, remoteTypeIds, args, scriptContext, idxArg, idxDest);
    @@ -3299,18 +3303,18 @@ namespace Js
                     }
                 }
     
    -            bool converted;
    +            bool converted = false;
                 if (JavascriptArray::IsAnyArray(aItem) || remoteTypeIds[idxArg] == TypeIds_Array)
                 {
    -                if (JavascriptNativeIntArray::Is(aItem)) // Fast path
    +                if (JavascriptNativeIntArray::Is(aItem) && !JavascriptArray::FromVar(aItem)->IsFillFromPrototypes()) // Fast path
                     {
                         JavascriptNativeIntArray *pIntArray = JavascriptNativeIntArray::FromVar(aItem);
                         
                         JS_REENTRANT(jsReentLock, converted = CopyNativeIntArrayElementsToFloat(pDestArray, idxDest, pIntArray));
     
                         idxDest = idxDest + pIntArray->length;
                     }
    -                else if (JavascriptNativeFloatArray::Is(aItem))
    +                else if (JavascriptNativeFloatArray::Is(aItem) && !JavascriptArray::FromVar(aItem)->IsFillFromPrototypes())
                     {
                         JavascriptNativeFloatArray* pItemArray = JavascriptNativeFloatArray::FromVar(aItem);
     
    @@ -3322,7 +3326,9 @@ namespace Js
                     {
                         JavascriptArray *pVarDestArray = JavascriptNativeFloatArray::ConvertToVarArray(pDestArray);
     
    -                    JS_REENTRANT(jsReentLock, ConcatArgs<uint>(pVarDestArray, remoteTypeIds, args, scriptContext, idxArg, idxDest));
    +                    BigIndex length;
    +                    JS_REENTRANT(jsReentLock, length = OP_GetLength(aItem, scriptContext),
    +                        ConcatArgs<uint>(pVarDestArray, remoteTypeIds, args, scriptContext, idxArg, idxDest, isConcatSpreadable, length));
     
                         return pVarDestArray;
                     }
    
  • test/Array/concat2.baseline+20 20 modified
    @@ -1,26 +1,26 @@
     -------concat Small-------------
    
     - concat 101, 102, 103, 104, 105
    
    -length: 2147483647
    
    -  2147483641: 100
    
    -  2147483642: 101
    
    -  2147483643: 102
    
    -  2147483644: 103
    
    -  2147483645: 104
    
    -  2147483646: 105
    
    +length: 505
    
    +  499: 100
    
    +  500: 101
    
    +  501: 102
    
    +  502: 103
    
    +  503: 104
    
    +  504: 105
    
     - arr.concat(arr)
    
    -length: 4294967294
    
    -  2147483641: 100
    
    -  2147483642: 101
    
    -  2147483643: 102
    
    -  2147483644: 103
    
    -  2147483645: 104
    
    -  2147483646: 105
    
    -  4294967288: 100
    
    -  4294967289: 101
    
    -  4294967290: 102
    
    -  4294967291: 103
    
    -  4294967292: 104
    
    -  4294967293: 105
    
    +length: 1010
    
    +  499: 100
    
    +  500: 101
    
    +  501: 102
    
    +  502: 103
    
    +  503: 104
    
    +  504: 105
    
    +  1004: 100
    
    +  1005: 101
    
    +  1006: 102
    
    +  1007: 103
    
    +  1008: 104
    
    +  1009: 105
    
     -------test prototype lookup-------------
    
     a: 200,101,202,203,204,105,106,207
    
     r: 200,101,202,203,204,105,106,207,300,301,302,303,304
    
    
  • test/Array/concat2.js+1 1 modified
    @@ -38,7 +38,7 @@ function test_concat(size) {
     }
    
     
    
     echo("-------concat Small-------------");
    
    -test_concat(2147483642);
    
    +test_concat(500);
    
     
    
     // Fix for MSRC 33319 changes concat to skip a fast path if the index we're copying into is a BigIndex.
    
     // Disable the large portion of this test since this change makes such a test run for hours.
    
    
  • test/es6/es6toLength.js+3 3 modified
    @@ -12,12 +12,12 @@ var tests = [
            {
    
                 var c = [];
    
                 c[0] = 1;
    
    -            c[4294967293] = 2;
    
    +            c[100] = 2;
    
                 var oNeg = { length : -1, 0 : 3, 1: 4, [Symbol.isConcatSpreadable] : true};
    
                 c = c.concat(oNeg);
    
                 assert.areEqual(1, c[0], "confirm indices of array concated to did not change")
    
    -            assert.areEqual(2, c[4294967293], "confirm indices of array concated to did not change");
    
    -            assert.areEqual(undefined, c[4294967294], "Length of oNeg is coerced to 0 nothing is concated here");
    
    +            assert.areEqual(2, c[100], "confirm indices of array concated to did not change");
    
    +            assert.areEqual(undefined, c[101], "Length of oNeg is coerced to 0 nothing is concated here");
    
            }
    
        },
    
        {
    
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

4

News mentions

0

No linked articles in our index yet.