Fix JIT crash with large number of match/switch arms (#8961)

Switch statements may generate a large number of exit points. Once the max
number of exit points is reached, get_exit_addr() returns NULL. This was not
checked, and this resulted in a jump table with some 0 addresses.
This commit is contained in:
Arnaud Le Blanc 2022-07-18 12:34:20 +02:00 committed by GitHub
parent b734d45626
commit f2381ae4ba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 1103 additions and 1 deletions

View File

@ -9,7 +9,7 @@ end_of_line = lf
charset = utf-8
tab_width = 4
[{*.{awk,bat,c,cpp,d,h,l,re,skl,w32,y},Makefile*}]
[{*.{awk,bat,c,cpp,d,dasc,h,l,re,skl,w32,y},Makefile*}]
indent_size = 4
indent_style = tab

View File

@ -13992,6 +13992,9 @@ static int zend_jit_hash_jmp(dasm_State **Dst, const zend_op *opline, const zend
} else {
exit_point = zend_jit_trace_get_exit_point(target, 0);
exit_addr = zend_jit_trace_get_exit_addr(exit_point);
if (!exit_addr) {
return 0;
}
| .addr &exit_addr
}
}
@ -14154,6 +14157,9 @@ static int zend_jit_switch(dasm_State **Dst, const zend_op *opline, const zend_o
} else {
exit_point = zend_jit_trace_get_exit_point(target, 0);
exit_addr = zend_jit_trace_get_exit_addr(exit_point);
if (!exit_addr) {
return 0;
}
| .addr &exit_addr
}
}

View File

@ -14877,6 +14877,9 @@ static int zend_jit_hash_jmp(dasm_State **Dst, const zend_op *opline, const zend
} else {
exit_point = zend_jit_trace_get_exit_point(target, 0);
exit_addr = zend_jit_trace_get_exit_addr(exit_point);
if (!exit_addr) {
return 0;
}
| .aword &exit_addr
}
}
@ -15043,6 +15046,9 @@ static int zend_jit_switch(dasm_State **Dst, const zend_op *opline, const zend_o
} else {
exit_point = zend_jit_trace_get_exit_point(target, 0);
exit_addr = zend_jit_trace_get_exit_addr(exit_point);
if (!exit_addr) {
return 0;
}
| .aword &exit_addr
}
}

View File

@ -0,0 +1,543 @@
--TEST--
GH-8030: Segfault with JIT and large match/switch statements 001
--EXTENSIONS--
opcache
--INI--
opcache.enable=1
opcache.enable_cli=1
opcache.jit_buffer_size=1M
opcache.jit=1255
opcache.file_update_protection=0
opcache.revalidate_freq=0
opcache.protect_memory=1
--FILE--
<?php
function lookup($s){
return match($s){
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
6 => 6,
7 => 7,
8 => 8,
9 => 9,
10 => 10,
11 => 11,
12 => 12,
13 => 13,
14 => 14,
15 => 15,
16 => 16,
17 => 17,
18 => 18,
19 => 19,
20 => 20,
21 => 21,
22 => 22,
23 => 23,
24 => 24,
25 => 25,
26 => 26,
27 => 27,
28 => 28,
29 => 29,
30 => 30,
31 => 31,
32 => 32,
33 => 33,
34 => 34,
35 => 35,
36 => 36,
37 => 37,
38 => 38,
39 => 39,
40 => 40,
41 => 41,
42 => 42,
43 => 43,
44 => 44,
45 => 45,
46 => 46,
47 => 47,
48 => 48,
49 => 49,
50 => 50,
51 => 51,
52 => 52,
53 => 53,
54 => 54,
55 => 55,
56 => 56,
57 => 57,
58 => 58,
59 => 59,
60 => 60,
61 => 61,
62 => 62,
63 => 63,
64 => 64,
65 => 65,
66 => 66,
67 => 67,
68 => 68,
69 => 69,
70 => 70,
71 => 71,
72 => 72,
73 => 73,
74 => 74,
75 => 75,
76 => 76,
77 => 77,
78 => 78,
79 => 79,
80 => 80,
81 => 81,
82 => 82,
83 => 83,
84 => 84,
85 => 85,
86 => 86,
87 => 87,
88 => 88,
89 => 89,
90 => 90,
91 => 91,
92 => 92,
93 => 93,
94 => 94,
95 => 95,
96 => 96,
97 => 97,
98 => 98,
99 => 99,
100 => 100,
101 => 101,
102 => 102,
103 => 103,
104 => 104,
105 => 105,
106 => 106,
107 => 107,
108 => 108,
109 => 109,
110 => 110,
111 => 111,
112 => 112,
113 => 113,
114 => 114,
115 => 115,
116 => 116,
117 => 117,
118 => 118,
119 => 119,
120 => 120,
121 => 121,
122 => 122,
123 => 123,
124 => 124,
125 => 125,
126 => 126,
127 => 127,
128 => 128,
129 => 129,
130 => 130,
131 => 131,
132 => 132,
133 => 133,
134 => 134,
135 => 135,
136 => 136,
137 => 137,
138 => 138,
139 => 139,
140 => 140,
141 => 141,
142 => 142,
143 => 143,
144 => 144,
145 => 145,
146 => 146,
147 => 147,
148 => 148,
149 => 149,
150 => 150,
151 => 151,
152 => 152,
153 => 153,
154 => 154,
155 => 155,
156 => 156,
157 => 157,
158 => 158,
159 => 159,
160 => 160,
161 => 161,
162 => 162,
163 => 163,
164 => 164,
165 => 165,
166 => 166,
167 => 167,
168 => 168,
169 => 169,
170 => 170,
171 => 171,
172 => 172,
173 => 173,
174 => 174,
175 => 175,
176 => 176,
177 => 177,
178 => 178,
179 => 179,
180 => 180,
181 => 181,
182 => 182,
183 => 183,
184 => 184,
185 => 185,
186 => 186,
187 => 187,
188 => 188,
189 => 189,
190 => 190,
191 => 191,
192 => 192,
193 => 193,
194 => 194,
195 => 195,
196 => 196,
197 => 197,
198 => 198,
199 => 199,
200 => 200,
201 => 201,
202 => 202,
203 => 203,
204 => 204,
205 => 205,
206 => 206,
207 => 207,
208 => 208,
209 => 209,
210 => 210,
211 => 211,
212 => 212,
213 => 213,
214 => 214,
215 => 215,
216 => 216,
217 => 217,
218 => 218,
219 => 219,
220 => 220,
221 => 221,
222 => 222,
223 => 223,
224 => 224,
225 => 225,
226 => 226,
227 => 227,
228 => 228,
229 => 229,
230 => 230,
231 => 231,
232 => 232,
233 => 233,
234 => 234,
235 => 235,
236 => 236,
237 => 237,
238 => 238,
239 => 239,
240 => 240,
241 => 241,
242 => 242,
243 => 243,
244 => 244,
245 => 245,
246 => 246,
247 => 247,
248 => 248,
249 => 249,
250 => 250,
251 => 251,
252 => 252,
253 => 253,
254 => 254,
255 => 255,
256 => 256,
257 => 257,
258 => 258,
259 => 259,
260 => 260,
261 => 261,
262 => 262,
263 => 263,
264 => 264,
265 => 265,
266 => 266,
267 => 267,
268 => 268,
269 => 269,
270 => 270,
271 => 271,
272 => 272,
273 => 273,
274 => 274,
275 => 275,
276 => 276,
277 => 277,
278 => 278,
279 => 279,
280 => 280,
281 => 281,
282 => 282,
283 => 283,
284 => 284,
285 => 285,
286 => 286,
287 => 287,
288 => 288,
289 => 289,
290 => 290,
291 => 291,
292 => 292,
293 => 293,
294 => 294,
295 => 295,
296 => 296,
297 => 297,
298 => 298,
299 => 299,
300 => 300,
301 => 301,
302 => 302,
303 => 303,
304 => 304,
305 => 305,
306 => 306,
307 => 307,
308 => 308,
309 => 309,
310 => 310,
311 => 311,
312 => 312,
313 => 313,
314 => 314,
315 => 315,
316 => 316,
317 => 317,
318 => 318,
319 => 319,
320 => 320,
321 => 321,
322 => 322,
323 => 323,
324 => 324,
325 => 325,
326 => 326,
327 => 327,
328 => 328,
329 => 329,
330 => 330,
331 => 331,
332 => 332,
333 => 333,
334 => 334,
335 => 335,
336 => 336,
337 => 337,
338 => 338,
339 => 339,
340 => 340,
341 => 341,
342 => 342,
343 => 343,
344 => 344,
345 => 345,
346 => 346,
347 => 347,
348 => 348,
349 => 349,
350 => 350,
351 => 351,
352 => 352,
353 => 353,
354 => 354,
355 => 355,
356 => 356,
357 => 357,
358 => 358,
359 => 359,
360 => 360,
361 => 361,
362 => 362,
363 => 363,
364 => 364,
365 => 365,
366 => 366,
367 => 367,
368 => 368,
369 => 369,
370 => 370,
371 => 371,
372 => 372,
373 => 373,
374 => 374,
375 => 375,
376 => 376,
377 => 377,
378 => 378,
379 => 379,
380 => 380,
381 => 381,
382 => 382,
383 => 383,
384 => 384,
385 => 385,
386 => 386,
387 => 387,
388 => 388,
389 => 389,
390 => 390,
391 => 391,
392 => 392,
393 => 393,
394 => 394,
395 => 395,
396 => 396,
397 => 397,
398 => 398,
399 => 399,
400 => 400,
401 => 401,
402 => 402,
403 => 403,
404 => 404,
405 => 405,
406 => 406,
407 => 407,
408 => 408,
409 => 409,
410 => 410,
411 => 411,
412 => 412,
413 => 413,
414 => 414,
415 => 415,
416 => 416,
417 => 417,
418 => 418,
419 => 419,
420 => 420,
421 => 421,
422 => 422,
423 => 423,
424 => 424,
425 => 425,
426 => 426,
427 => 427,
428 => 428,
429 => 429,
430 => 430,
431 => 431,
432 => 432,
433 => 433,
434 => 434,
435 => 435,
436 => 436,
437 => 437,
438 => 438,
439 => 439,
440 => 440,
441 => 441,
442 => 442,
443 => 443,
444 => 444,
445 => 445,
446 => 446,
447 => 447,
448 => 448,
449 => 449,
450 => 450,
451 => 451,
452 => 452,
453 => 453,
454 => 454,
455 => 455,
456 => 456,
457 => 457,
458 => 458,
459 => 459,
460 => 460,
461 => 461,
462 => 462,
463 => 463,
464 => 464,
465 => 465,
466 => 466,
467 => 467,
468 => 468,
469 => 469,
470 => 470,
471 => 471,
472 => 472,
473 => 473,
474 => 474,
475 => 475,
476 => 476,
477 => 477,
478 => 478,
479 => 479,
480 => 480,
481 => 481,
482 => 482,
483 => 483,
484 => 484,
485 => 485,
486 => 486,
487 => 487,
488 => 488,
489 => 489,
490 => 490,
491 => 491,
492 => 492,
493 => 493,
494 => 494,
495 => 495,
496 => 496,
497 => 497,
498 => 498,
499 => 499,
500 => 500,
501 => 501,
502 => 502,
503 => 503,
504 => 504,
505 => 505,
506 => 506,
507 => 507,
508 => 508,
509 => 509,
510 => 510,
511 => 511,
512 => 512,
513 => 513,
};
}
for ($i=0; $i<2; $i++){
var_dump(lookup(510));
var_dump(lookup(513));
}
?>
==DONE==
--EXPECT--
int(510)
int(513)
int(510)
int(513)
==DONE==

View File

@ -0,0 +1,547 @@
--TEST--
GH-8030: Segfault with JIT and large match/switch statements 002
--EXTENSIONS--
opcache
--INI--
opcache.enable=1
opcache.enable_cli=1
opcache.jit_buffer_size=1M
opcache.jit=1255
opcache.file_update_protection=0
opcache.revalidate_freq=0
opcache.protect_memory=1
--FILE--
<?php
function lookup($s){
switch($s){
case 1: return 1;
case 2: return 2;
case 3: return 3;
case 4: return 4;
case 5: return 5;
case 6: return 6;
case 7: return 7;
case 8: return 8;
case 9: return 9;
case 10: return 10;
case 11: return 11;
case 12: return 12;
case 13: return 13;
case 14: return 14;
case 15: return 15;
case 16: return 16;
case 17: return 17;
case 18: return 18;
case 19: return 19;
case 20: return 20;
case 21: return 21;
case 22: return 22;
case 23: return 23;
case 24: return 24;
case 25: return 25;
case 26: return 26;
case 27: return 27;
case 28: return 28;
case 29: return 29;
case 30: return 30;
case 31: return 31;
case 32: return 32;
case 33: return 33;
case 34: return 34;
case 35: return 35;
case 36: return 36;
case 37: return 37;
case 38: return 38;
case 39: return 39;
case 40: return 40;
case 41: return 41;
case 42: return 42;
case 43: return 43;
case 44: return 44;
case 45: return 45;
case 46: return 46;
case 47: return 47;
case 48: return 48;
case 49: return 49;
case 50: return 50;
case 51: return 51;
case 52: return 52;
case 53: return 53;
case 54: return 54;
case 55: return 55;
case 56: return 56;
case 57: return 57;
case 58: return 58;
case 59: return 59;
case 60: return 60;
case 61: return 61;
case 62: return 62;
case 63: return 63;
case 64: return 64;
case 65: return 65;
case 66: return 66;
case 67: return 67;
case 68: return 68;
case 69: return 69;
case 70: return 70;
case 71: return 71;
case 72: return 72;
case 73: return 73;
case 74: return 74;
case 75: return 75;
case 76: return 76;
case 77: return 77;
case 78: return 78;
case 79: return 79;
case 80: return 80;
case 81: return 81;
case 82: return 82;
case 83: return 83;
case 84: return 84;
case 85: return 85;
case 86: return 86;
case 87: return 87;
case 88: return 88;
case 89: return 89;
case 90: return 90;
case 91: return 91;
case 92: return 92;
case 93: return 93;
case 94: return 94;
case 95: return 95;
case 96: return 96;
case 97: return 97;
case 98: return 98;
case 99: return 99;
case 100: return 100;
case 101: return 101;
case 102: return 102;
case 103: return 103;
case 104: return 104;
case 105: return 105;
case 106: return 106;
case 107: return 107;
case 108: return 108;
case 109: return 109;
case 110: return 110;
case 111: return 111;
case 112: return 112;
case 113: return 113;
case 114: return 114;
case 115: return 115;
case 116: return 116;
case 117: return 117;
case 118: return 118;
case 119: return 119;
case 120: return 120;
case 121: return 121;
case 122: return 122;
case 123: return 123;
case 124: return 124;
case 125: return 125;
case 126: return 126;
case 127: return 127;
case 128: return 128;
case 129: return 129;
case 130: return 130;
case 131: return 131;
case 132: return 132;
case 133: return 133;
case 134: return 134;
case 135: return 135;
case 136: return 136;
case 137: return 137;
case 138: return 138;
case 139: return 139;
case 140: return 140;
case 141: return 141;
case 142: return 142;
case 143: return 143;
case 144: return 144;
case 145: return 145;
case 146: return 146;
case 147: return 147;
case 148: return 148;
case 149: return 149;
case 150: return 150;
case 151: return 151;
case 152: return 152;
case 153: return 153;
case 154: return 154;
case 155: return 155;
case 156: return 156;
case 157: return 157;
case 158: return 158;
case 159: return 159;
case 160: return 160;
case 161: return 161;
case 162: return 162;
case 163: return 163;
case 164: return 164;
case 165: return 165;
case 166: return 166;
case 167: return 167;
case 168: return 168;
case 169: return 169;
case 170: return 170;
case 171: return 171;
case 172: return 172;
case 173: return 173;
case 174: return 174;
case 175: return 175;
case 176: return 176;
case 177: return 177;
case 178: return 178;
case 179: return 179;
case 180: return 180;
case 181: return 181;
case 182: return 182;
case 183: return 183;
case 184: return 184;
case 185: return 185;
case 186: return 186;
case 187: return 187;
case 188: return 188;
case 189: return 189;
case 190: return 190;
case 191: return 191;
case 192: return 192;
case 193: return 193;
case 194: return 194;
case 195: return 195;
case 196: return 196;
case 197: return 197;
case 198: return 198;
case 199: return 199;
case 200: return 200;
case 201: return 201;
case 202: return 202;
case 203: return 203;
case 204: return 204;
case 205: return 205;
case 206: return 206;
case 207: return 207;
case 208: return 208;
case 209: return 209;
case 210: return 210;
case 211: return 211;
case 212: return 212;
case 213: return 213;
case 214: return 214;
case 215: return 215;
case 216: return 216;
case 217: return 217;
case 218: return 218;
case 219: return 219;
case 220: return 220;
case 221: return 221;
case 222: return 222;
case 223: return 223;
case 224: return 224;
case 225: return 225;
case 226: return 226;
case 227: return 227;
case 228: return 228;
case 229: return 229;
case 230: return 230;
case 231: return 231;
case 232: return 232;
case 233: return 233;
case 234: return 234;
case 235: return 235;
case 236: return 236;
case 237: return 237;
case 238: return 238;
case 239: return 239;
case 240: return 240;
case 241: return 241;
case 242: return 242;
case 243: return 243;
case 244: return 244;
case 245: return 245;
case 246: return 246;
case 247: return 247;
case 248: return 248;
case 249: return 249;
case 250: return 250;
case 251: return 251;
case 252: return 252;
case 253: return 253;
case 254: return 254;
case 255: return 255;
case 256: return 256;
case 257: return 257;
case 258: return 258;
case 259: return 259;
case 260: return 260;
case 261: return 261;
case 262: return 262;
case 263: return 263;
case 264: return 264;
case 265: return 265;
case 266: return 266;
case 267: return 267;
case 268: return 268;
case 269: return 269;
case 270: return 270;
case 271: return 271;
case 272: return 272;
case 273: return 273;
case 274: return 274;
case 275: return 275;
case 276: return 276;
case 277: return 277;
case 278: return 278;
case 279: return 279;
case 280: return 280;
case 281: return 281;
case 282: return 282;
case 283: return 283;
case 284: return 284;
case 285: return 285;
case 286: return 286;
case 287: return 287;
case 288: return 288;
case 289: return 289;
case 290: return 290;
case 291: return 291;
case 292: return 292;
case 293: return 293;
case 294: return 294;
case 295: return 295;
case 296: return 296;
case 297: return 297;
case 298: return 298;
case 299: return 299;
case 300: return 300;
case 301: return 301;
case 302: return 302;
case 303: return 303;
case 304: return 304;
case 305: return 305;
case 306: return 306;
case 307: return 307;
case 308: return 308;
case 309: return 309;
case 310: return 310;
case 311: return 311;
case 312: return 312;
case 313: return 313;
case 314: return 314;
case 315: return 315;
case 316: return 316;
case 317: return 317;
case 318: return 318;
case 319: return 319;
case 320: return 320;
case 321: return 321;
case 322: return 322;
case 323: return 323;
case 324: return 324;
case 325: return 325;
case 326: return 326;
case 327: return 327;
case 328: return 328;
case 329: return 329;
case 330: return 330;
case 331: return 331;
case 332: return 332;
case 333: return 333;
case 334: return 334;
case 335: return 335;
case 336: return 336;
case 337: return 337;
case 338: return 338;
case 339: return 339;
case 340: return 340;
case 341: return 341;
case 342: return 342;
case 343: return 343;
case 344: return 344;
case 345: return 345;
case 346: return 346;
case 347: return 347;
case 348: return 348;
case 349: return 349;
case 350: return 350;
case 351: return 351;
case 352: return 352;
case 353: return 353;
case 354: return 354;
case 355: return 355;
case 356: return 356;
case 357: return 357;
case 358: return 358;
case 359: return 359;
case 360: return 360;
case 361: return 361;
case 362: return 362;
case 363: return 363;
case 364: return 364;
case 365: return 365;
case 366: return 366;
case 367: return 367;
case 368: return 368;
case 369: return 369;
case 370: return 370;
case 371: return 371;
case 372: return 372;
case 373: return 373;
case 374: return 374;
case 375: return 375;
case 376: return 376;
case 377: return 377;
case 378: return 378;
case 379: return 379;
case 380: return 380;
case 381: return 381;
case 382: return 382;
case 383: return 383;
case 384: return 384;
case 385: return 385;
case 386: return 386;
case 387: return 387;
case 388: return 388;
case 389: return 389;
case 390: return 390;
case 391: return 391;
case 392: return 392;
case 393: return 393;
case 394: return 394;
case 395: return 395;
case 396: return 396;
case 397: return 397;
case 398: return 398;
case 399: return 399;
case 400: return 400;
case 401: return 401;
case 402: return 402;
case 403: return 403;
case 404: return 404;
case 405: return 405;
case 406: return 406;
case 407: return 407;
case 408: return 408;
case 409: return 409;
case 410: return 410;
case 411: return 411;
case 412: return 412;
case 413: return 413;
case 414: return 414;
case 415: return 415;
case 416: return 416;
case 417: return 417;
case 418: return 418;
case 419: return 419;
case 420: return 420;
case 421: return 421;
case 422: return 422;
case 423: return 423;
case 424: return 424;
case 425: return 425;
case 426: return 426;
case 427: return 427;
case 428: return 428;
case 429: return 429;
case 430: return 430;
case 431: return 431;
case 432: return 432;
case 433: return 433;
case 434: return 434;
case 435: return 435;
case 436: return 436;
case 437: return 437;
case 438: return 438;
case 439: return 439;
case 440: return 440;
case 441: return 441;
case 442: return 442;
case 443: return 443;
case 444: return 444;
case 445: return 445;
case 446: return 446;
case 447: return 447;
case 448: return 448;
case 449: return 449;
case 450: return 450;
case 451: return 451;
case 452: return 452;
case 453: return 453;
case 454: return 454;
case 455: return 455;
case 456: return 456;
case 457: return 457;
case 458: return 458;
case 459: return 459;
case 460: return 460;
case 461: return 461;
case 462: return 462;
case 463: return 463;
case 464: return 464;
case 465: return 465;
case 466: return 466;
case 467: return 467;
case 468: return 468;
case 469: return 469;
case 470: return 470;
case 471: return 471;
case 472: return 472;
case 473: return 473;
case 474: return 474;
case 475: return 475;
case 476: return 476;
case 477: return 477;
case 478: return 478;
case 479: return 479;
case 480: return 480;
case 481: return 481;
case 482: return 482;
case 483: return 483;
case 484: return 484;
case 485: return 485;
case 486: return 486;
case 487: return 487;
case 488: return 488;
case 489: return 489;
case 490: return 490;
case 491: return 491;
case 492: return 492;
case 493: return 493;
case 494: return 494;
case 495: return 495;
case 496: return 496;
case 497: return 497;
case 498: return 498;
case 499: return 499;
case 500: return 500;
case 501: return 501;
case 502: return 502;
case 503: return 503;
case 504: return 504;
case 505: return 505;
case 506: return 506;
case 507: return 507;
case 508: return 508;
case 509: return 509;
case 510: return 510;
case 511: return 511;
case 512: return 512;
case 513: return 513;
default: return -1;
};
}
for ($i=0; $i<2; $i++){
var_dump(lookup(510));
var_dump(lookup(513));
var_dump(lookup(-1));
}
?>
==DONE==
--EXPECT--
int(510)
int(513)
int(-1)
int(510)
int(513)
int(-1)
==DONE==