|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #80959 infinite loop in building cfg during JIT compilation
Submitted: 2021-04-15 22:32 UTC Modified: 2021-04-16 09:50 UTC
From: zengyhkyle at asu dot edu Assigned: dmitry (profile)
Status: Closed Package: JIT
PHP Version: 8.0.4RC1 OS: Linux
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
Block user comment
Status: Assign to:
Bug Type:
From: zengyhkyle at asu dot edu
New email:
PHP Version: OS:


 [2021-04-15 22:32 UTC] zengyhkyle at asu dot edu
if JIT compilation is enabled, PHP will get stuck in infinitely during loop identification when building the cfg for some code.

the configuration we use is listed as follow:

This vulnerability is found by Yihui Zeng, Jayakrishna Menon, Steven Wirsz, and Gokul Krishna P from Arizona State University for class CSE598 Applied Vulnerability Research

a poc is attached.

Test script:
$v0 = -815;
$v1 = True;
$v2 = $v0;
   $v3 = [5, 5]; 
   $v2 = $v3;
   $v4 = False;
   $v5 = $v0;
      $v6 = $v4|$v0;
      $v5 = $v6;
      $v5 = $v5 + 1;
      $v7 = $v5 + 1;
      $v5 = $v7;
   $v2 = $v5;
$v8 = 0;
$v9 = 4;
$v10 = $v8;
   $v10 = $v10 + 1;
   $v11 = $v10 + 1;
   $v12 = $v10;
      $v10 = $v12;
   }catch(Exception $e){
      $v2 = $v12;
   $v13 = False;
   $v14 = $v13;
      $v15 = $v12/$v14;
      $v14 = $v15;
      $v16 = 0;
      $v17 = 9;
      $v18 = $v16;
         $v18 = $v18 + 1;
         $v19 = $v18 + 1;
         $v19 = $v19 - 1;
         $v20 = $v19 - 1;
      $v21 = "kBBqSjjO63";
      $v21[0] = $v12;
      $v14 = $v21;
$v22 = [3.055141489223973, 5.118032201755781, 1.6115282496633003, 2.796353888054253, 1.607762036181039, 5.52005061408927, 2.4609577104054896];
$v23 = [4, 1, 4, 4]; 

echo "Done";


Add a Patch

Pull Requests

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2021-04-15 22:34 UTC] zengyhkyle at asu dot edu
-PHP Version: 8.0.3 +PHP Version: 8.0.4RC1
 [2021-04-15 22:34 UTC] zengyhkyle at asu dot edu
in our experiment, the execution is stuck at function `zend_cfg_identify_loops`
 [2021-04-16 03:39 UTC]
-Status: Open +Status: Verified
 [2021-04-16 08:23 UTC]
Nice find! Here's a somewhat reduced version:

function test($a, $b) {
    echo "Start\n";
    do {
        try {
        } catch (Exception $e) {
        do { 
        } while ($j < $b);
    } while ($i < $a);
    echo "Done\n";
 [2021-04-16 09:12 UTC]
CFG for reference:

The core problem here is that BB5 and BB6 are not reachable from entry through normal edges (they have domtree level 0 and will be processed last). They are reachable in the reverse graph though, which is traversed when loop headers are assigned. We end up with BB3 having BB6 as loop header, and BB6 having BB3 as loop header, causing an infinite loop.

There's probably two separate problems here: We should be treating unreachable code more gracefully, and we should not be treating this code as unreachable in the first place, though I'm not sure what the right way to handle unwind edges would be right now.
 [2021-04-16 09:25 UTC]
Though it would be great if we could not run loop identification in the first place if a function has try/catch. In that case we don't perform SSA construction or register allocation, which need this for correctness. It seems like the only places that use the information in that case is timeout checks and hot loop counters. Maybe we just want to pessimize those in the presence of try/catch?
 [2021-04-16 09:29 UTC]
-Assigned To: +Assigned To: dmitry
 [2021-04-16 09:50 UTC]
Possible patch to avoid infinite loop:

It uses missing idom to identify blocks that are unreachable or only abnormally reachable and skips the loop header assignment for them.

Of course, that doesn't fix the problem that computed results for try/catch may be incorrect, as we're working on an inaccurate CFG.
 [2021-07-21 11:34 UTC]
Automatic comment on behalf of dstogov
Log: Fixed Bug #80959 (infinite loop in building cfg during JIT compilation)
 [2021-07-21 11:34 UTC]
-Status: Verified +Status: Closed
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Wed Feb 21 09:01:28 2024 UTC