Răsfoiți Sursa

[MERGE #2196 @suwc] Change to address CVE-2016-7202

Merge pull request #2196 from suwc:build/suwc/bugfix

Heap overflow in Array.prototype.reverse
In Array.prototype.reverse, array length is cached and used in ReverseHelper().
ReverseHelper() could invoke FillFromPrototypes(), which can cause a side-effect on the array,
including changing its length. Therefore, the use of cached array length to calculate segment left index could result in overflow. Fix by clamping array length at zero.
Suwei Chen 9 ani în urmă
părinte
comite
fc7ea25190

+ 1 - 1
lib/Runtime/Library/JavascriptArray.cpp

@@ -5202,7 +5202,7 @@ Case0:
                         ((SparseArraySegment<Var>*)seg)->ReverseSegment(recycler);
                     }
 
-                    seg->left = ((uint32)length) - (seg->left + seg->length);
+                    seg->left = ((uint32)length) > (seg->left + seg->length) ? ((uint32)length) - (seg->left + seg->length) : 0;
 
                     seg->next = prevSeg;
                     // Make sure size doesn't overlap with next segment.

+ 19 - 0
test/Array/Array_TypeConfusion_bugs.js

@@ -574,5 +574,24 @@ var tests = [
             assert.areEqual([0x41424344], Array.prototype.slice.call(y));
         }
     },
+    {
+        name: "[MSRC34994,35226] heap overflow in Array.prototype.reverse",
+        body: function ()
+        {
+            var count = 0;
+            arr = new Array(100);
+            var desc = Object.getOwnPropertyDescriptor(Array.prototype, 1);
+            Object.defineProperty(Array.prototype, 1, { get: function () {
+                    count++;
+                    if (count == 1) {
+                        arr.push(null);
+                    }
+                }});
+
+            arr.reverse();
+            restorePropertyFromDescriptor(Array.prototype, 1, desc);
+            assert.areEqual(101, arr.length);
+        }
+    },
 ];
 testRunner.runTests(tests, { verbose: WScript.Arguments[0] != "summary" });