ソースを参照

[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 年 前
コミット
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" });