Bläddra i källkod

[CVE-2017-8756] JIT peephole optimization error

The peephole optimizer fails to invalidate both arguments to XCHG
instructions, which can lead subsequent passes (notably copy propagation)
to refer to the XCHG op's second arg, assuming it will get that register's
original value.  Fixed that by invalidating both arguments.

# Conflicts:
#	test/Bugs/rlexe.xml
Suwei Chen 8 år sedan
förälder
incheckning
1602eb32cb
4 ändrade filer med 66 tillägg och 0 borttagningar
  1. 14 0
      lib/Backend/amd64/PeepsMD.cpp
  2. 14 0
      lib/Backend/i386/PeepsMD.cpp
  3. 32 0
      test/Bugs/bug12628506.js
  4. 6 0
      test/Bugs/rlexe.xml

+ 14 - 0
lib/Backend/amd64/PeepsMD.cpp

@@ -41,6 +41,20 @@ PeepsMD::ProcessImplicitRegs(IR::Instr *instr)
             this->peeps->ClearReg(RegRDX);
         }
     }
+    else if (instr->m_opcode == Js::OpCode::XCHG)
+    {
+        // At time of writing, I believe that src1 is always identical to dst, but clear both for robustness.
+
+        // Either of XCHG's operands (but not both) can be a memory address, so only clear registers.
+        if (instr->GetSrc1()->IsRegOpnd())
+        {
+            this->peeps->ClearReg(instr->GetSrc1()->AsRegOpnd()->GetReg());
+        }
+        if (instr->GetSrc2()->IsRegOpnd())
+        {
+            this->peeps->ClearReg(instr->GetSrc2()->AsRegOpnd()->GetReg());
+        }
+    }
 }
 
 void

+ 14 - 0
lib/Backend/i386/PeepsMD.cpp

@@ -47,6 +47,20 @@ PeepsMD::ProcessImplicitRegs(IR::Instr *instr)
             this->peeps->ClearReg(RegEDX);
         }
     }
+    else if (instr->m_opcode == Js::OpCode::XCHG)
+    {
+        // At time of writing, I believe that src1 is always identical to dst, but clear both for robustness.
+
+        // Either of XCHG's operands (but not both) can be a memory address, so only clear registers.
+        if (instr->GetSrc1()->IsRegOpnd())
+        {
+            this->peeps->ClearReg(instr->GetSrc1()->AsRegOpnd()->GetReg());
+        }
+        if (instr->GetSrc2()->IsRegOpnd())
+        {
+            this->peeps->ClearReg(instr->GetSrc2()->AsRegOpnd()->GetReg());
+        }
+    }
 }
 
 void

+ 32 - 0
test/Bugs/bug12628506.js

@@ -0,0 +1,32 @@
+//-------------------------------------------------------------------------------------------------------
+// Copyright (C) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+//-------------------------------------------------------------------------------------------------------
+function test0() {
+    var loopInvariant = 9;
+    var obj1 = {};
+    var arrObj0 = {};
+    var func0 = function () {
+    };
+    var func2 = function () {
+        protoObj0;
+    };
+    arrObj0.method0 = obj1;
+    var i8 = new Int8Array(256);
+    var VarArr0 = Array(protoObj0, -188);
+    var protoObj0 = Object.create(func0);
+    protoObj0.prop0 = -1;
+    arrObj0.prop0 = -1863021692;
+    var __loopvar0 = 3, __loopSecondaryVar0_0 = 9 - 9, __loopSecondaryVar0_1 = 9;
+    while ((VarArr0[i8[255] + (arrObj0.prop0 <= protoObj0.prop0)]) && __loopvar0 < 10) {
+        __loopvar0++;
+        __loopSecondaryVar0_1 += 3;
+        if (3 > loopInvariant) {
+            break;
+        }
+        __loopSecondaryVar0_0 += 3;
+        arrObj0 = protoObj0;
+    }
+}
+test0();
+print("passed");

+ 6 - 0
test/Bugs/rlexe.xml

@@ -362,6 +362,12 @@
       <tags>exclude_dynapogo</tags>
     </default>
   </test>
+  <test>
+    <default>
+      <files>bug12628506.js</files>
+      <compile-flags>-loopinterpretcount:1</compile-flags>
+    </default>
+  </test>
   <test>
     <default>
       <files>bug13213828.js</files>