diff --git a/_posts/2021-04-20-Chromium-Issue-1196683-1195777.md b/_posts/2021-04-20-Chromium-Issue-1196683-1195777.md
index a263a2ea2..a7cf5a76c 100644
--- a/_posts/2021-04-20-Chromium-Issue-1196683-1195777.md
+++ b/_posts/2021-04-20-Chromium-Issue-1196683-1195777.md
@@ -9,7 +9,7 @@ author:
On April 12, a code commit[1] in Chromium get people's attention. This is a bugfix for some vulnerability in Chromium Javascript engine v8. At the same time, the regression test case regress-1196683.js for this bugfix was also submitted. Based on this regression test case, some security researcher published an exploit sample[2]. Due to Chrome release pipeline, the vulnerability wasn't been fixed in Chrome stable update until April 13[3].
-Coincidentally, on April 15, another code commit[4] of some bugfix in v8 has also included one regression test case regress-1195777.js. Based on this test case, the exploit sample was exposed again[5]. Since the latest Chrome stable version does not pull this bugfix commit, the sample can still exploit in render process of latest Chrome. When the vulnerable Chormium browser accesses a malicious link without enalbing the sandbox (--no-sandbox), the vulnerability will be triggered and caused remote code execution.
+Coincidentally, on April 15, another code commit[4] of some bugfix in v8 has also included one regression test case regress-1195777.js. Based on this test case, the exploit sample was exposed again[5]. Since the latest Chrome stable version does not pull this bugfix commit, the sample can still exploit in render process of latest Chrome. When the vulnerable Chormium browser accesses a malicious link without enabling the sandbox (--no-sandbox), the vulnerability will be triggered and caused remote code execution.
## RCA of Issue 1196683
The bugfix for this issue is shown as follows:
@@ -32,7 +32,7 @@ First, let's analyze the root cause of this vulnerability via regress-1196683.js
});
```
-The foo function that triggers JIT has only one code line. Let's focus on the optimization process of (arr[0] ^ 0) + 1 in the key stage of TurboFan:
+The foo function that triggers JIT has only one code line. Let's focus on the optimization process of (arr[0] ^ 0) + 1 in the key phases of TurboFan:
**1) TyperPhase**

@@ -46,7 +46,7 @@ The original node 32: SpeculativeNumberBitwiseXor is optimized to Word32Xor, and
**3) EarlyOptimizationPhase**

-We can see that the original node 32 (Word32Xor) has been deleted and replaced with node 80 as the input of the node 110 ChangeInt32ToInt64. Now the input node (LoadTypedElement) type of ChangeInt32ToInt64 is Unsigned32.
+We can see that the original node 32 (Word32Xor) has been deleted and replaced with node 80 as the input of the node 110 ChangeInt32ToInt64. Now the input node (LoadTypedElement) type of ChangeInt32ToInt64 is **Unsigned32**.
The v8 code corresponding to the logic is as follows:
```cpp
@@ -97,10 +97,10 @@ function foo() {
```
## RCA of Issue 1195777
-The bugfix for this issue is as follows:
+The bugfix for this issue is shown as follows:

-This commit fixes a integer conversion node generation error which used to convert a 64-bit integer to a 32-bit integer in SimplifiedLowering phase.
+This commit fixes a integer conversion node generation error which used to convert a 64-bit integer to a 32-bit integer (truncation) in SimplifiedLowering phase.
Before the commit, if the output type of current node is Signed32 or Unsigned32, the TruncateInt64ToInt32 node is generated. After the commit, if the output type of current node is Unsigned32, the type of use_info is needed to be checked next. Only when use_info.type_check() == TypeCheckKind::kNone, the TruncateInt64ToInt32 node wiill be generated.
First, let's analyze the root cause of this vulnerability via regress-1195777.js:
@@ -109,7 +109,7 @@ First, let's analyze the root cause of this vulnerability via regress-1195777.js
(function() {
function foo(b) {
let x = -1;
- if (b) x = 0xFFFF_FFFF;
+ if (b) x = 0xFFFFFFFF;
return -1 < Math.max(0, x, -1);
}
assertTrue(foo(true));
@@ -120,7 +120,7 @@ First, let's analyze the root cause of this vulnerability via regress-1195777.js
})();
```
-The key code in foo function which triggers JIT is 'return -1 < Math.max(0, x, -1)'. Let's focus on the optimization process of Math.max(0, x, -1) in the key stages of TurboFan:
+The key code in foo function which triggers JIT is 'return -1 < Math.max(0, x, -1)'. Let's focus on the optimization process of Math.max(0, x, -1) in the key phases of TurboFan:
**1) TyperPhase**

@@ -134,7 +134,9 @@ The two constant parameters 0, -1 (node 54 and node 55) in Math.max(0, x, -1) ar
**3) SimplifiedLoweringPhase**

-The original NumberMax node 56 and node 58 are replaced by Int64LessThan + Select nodes. The original node 41: SpeculativeNumberLessThan is replaced with Int32LessThan. When processing the input node of SpeculativeNumberLessThan, because the output type of the input node (Select) is Unsigned32, the vulnerability is triggered and the node 76: TruncateInt64ToInt32 is generated incorrectly. The result of Math.max(0, x, -1) is truncated to Signed32. Therefore, when the x in Math.max(0, x, -1) is Unsigned32, it will be truncated to Signed32 by TruncateInt64ToInt32.
+The original NumberMax node 56 and node 58 are replaced by Int64LessThan + Select nodes. The original node 41: SpeculativeNumberLessThan is replaced with Int32LessThan. When processing the input node of SpeculativeNumberLessThan, because the output type of the input node (Select) is Unsigned32, the vulnerability is triggered and the node 76: TruncateInt64ToInt32 is generated incorrectly.
+
+The result of Math.max(0, x, -1) is truncated to Signed32. Therefore, when the x in Math.max(0, x, -1) is Unsigned32, it will be truncated to Signed32 by TruncateInt64ToInt32.
Finally, using this vulnerability, a variable x with an unexpected value 1 in JIT can be obtained via the following code (the expected value should be 0):
@@ -150,10 +152,11 @@ function foo(flag){
```
## Exploit analysis
-According to the above root cause analysis, we can see that the two vulnerabilities are triggered when TurboFan performs integer data type conversion (expansion, truncation). Using the two vulnerabilities, a variable x with an unexpected value 1 in JIT can be obtained. Next, according to the samples exploited in the wild, the exploit are following the steps below:
-**1) Create an Array with length 1 with the help of variable x which has one error value of 1;**
+According to the above root cause analysis, we can see that the two vulnerabilities are triggered when TurboFan performs integer data type conversion (expansion, truncation). Using the two vulnerabilities, a variable x with an unexpected value 1 in JIT can be obtained.
+According to the samples exploited in the wild, the exploit is following the steps below:
+**1) Create an Array which length is 1 with the help of variable x which has the error value 1;**
**2) Obtain an out-of-bounds array with length 0xFFFFFFFF through Array.prototype.shift();**
-The key code is as follows:
+The key code is as shown follows:
```javascript
var arr = new Array(x); // wrong: x = 1
@@ -165,7 +168,7 @@ return [arr, cor];
The JIT code of var arr = new Array(x) is:

-Rdi is the length of arr, which value is 1. It left shift one bit (rdi+rdi) by pointer compression and stored in JSArray.length property (+0xC).
+Rdi is the length of arr, which value is 1. It shift left one bit (rdi+rdi) by pointer compression and stored in JSArray.length property (+0xC).
The JIT code of arr.shift() is:

@@ -178,7 +181,7 @@ The array length assignment operation is mainly composed of node 152 and node 15
(2)LoadEliminationPhase

-Since the value of x which collected during the execution of Ignition is 0, constant folding (0-1=-1) happens here to get the constant 0xFFFFFFFF. After left shift one bit, it is 0xFFFFFFFE, which is stored in Array.length (+0xC). Thus, an out-of-bounds array with a length of 0xFFFFFFFF is obtained.
+Since the value of x which collected by Ignition is 0, constant folding (0-1=-1) happens here to get the constant 0xFFFFFFFF. After shift left one bit, it is 0xFFFFFFFE, which is stored in Array.length (+0xC). Thus, an out-of-bounds array with a length of 0xFFFFFFFF is obtained.
After the out-of-bounds array is obtained, the next steps are common:
**3) Realize addrof/fakeobj with the help of this out-of-bounds array;**