Bug #81368 [Opn->Fbk]: Possible divide by zero bug in zend_inference.c

From: Date: Tue, 17 Aug 2021 13:06:14 +0000
Subject: Bug #81368 [Opn->Fbk]: Possible divide by zero bug in zend_inference.c
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-235907@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=81368&edit=1

 ID:                 81368
 Updated by:         nikic@php.net
 Reported by:        yguoaz at gmail dot com
 Summary:            Possible divide by zero bug in zend_inference.c
-Status:             Open
+Status:             Feedback
 Type:               Bug
 Package:            *General Issues
 Operating System:   Linux
 PHP Version:        master-Git-2021-08-17 (Git)
 Block user comment: N
 Private report:     N

 New Comment:

op2_min <= op2_max is a general precondition. In additional, the check enforces !(op2_min <= 0
&& op2_max >= 0), or equivalently op2_min > 0 || op2_max < 0.

If op2_min > 0 then also op2_max >= op2_min > 0. If op2_max < 0 then also op2_min <=
op2_max < 0.

As such, neither op2_min or op2_max can be zero. Does that sound right?


Previous Comments:
------------------------------------------------------------------------
[2021-08-17 13:00:36] yguoaz at gmail dot com

I think the op2_min/op2_max check before is not sufficient.
For example, op2_min==0 && op2_max < 0 can bypass it.

Can this happen? This issue is found by inspection. Thus I do not have a test case here.

------------------------------------------------------------------------
[2021-08-17 12:39:34] nikic@php.net

Doesn't the op2_min/op2_max check before that exclude the possibility of a division by zero?

Can you share an example that would trigger a division by zero in this code?

------------------------------------------------------------------------
[2021-08-17 11:48:11] yguoaz at gmail dot com

Description:
------------
In the file Zend/Optimizer/zend_inference.c, the function zend_inference_calc_binary_op_range has
the following code:

case ZEND_DIV:
  if (OP1_HAS_RANGE() && OP2_HAS_RANGE()) {
    op1_min = OP1_MIN_RANGE();
    op2_min = OP2_MIN_RANGE();
    op1_max = OP1_MAX_RANGE();
    op2_max = OP2_MAX_RANGE();
    if (op2_min <= 0 && op2_max >= 0) {
      break;
    }
    
    float_div(op1_min, op2_min, &t1, &t1_);
    float_div(op1_min, op2_max, &t2, &t2_);
    float_div(op1_max, op2_min, &t3, &t3_);
    float_div(op1_max, op2_max, &t4, &t4_); 

The function float_div uses its second argument as a divisor. If only one of
the variables from op2_min and op2_max is zero, the checking can be bypassed
and will lead to a divide by zero problem.

Here is the link to the related code in github:
https://github.com/php/php-src/blob/be2df43b08cf13b9a5791ff5eb827a125115ef52/Zend/Optimizer/zend_inference.c#L674



------------------------------------------------------------------------



--
Edit this bug report at https://bugs.php.net/bug.php?id=81368&edit=1


Thread (1 message)

  • nikic@php.net
  • Unknown Message
    • nikic@php.net
« previous php.bugs (#235907) next »