mirror of
https://github.com/php/php-src.git
synced 2024-11-23 18:04:36 +08:00
Fix use after free on compound division by zero
We can't destroy the result operand early, because the division might fail, in which case we need to preserve the original value. Place the division result in a temporary zval, and only copy it on success. Fixes oss-fuzz #35876.
This commit is contained in:
parent
52a00fe776
commit
62ecf54f35
16
Zend/tests/div_by_zero_compound_refcounted.phpt
Normal file
16
Zend/tests/div_by_zero_compound_refcounted.phpt
Normal file
@ -0,0 +1,16 @@
|
||||
--TEST--
|
||||
Division by zero in compound assignment with refcounted operand
|
||||
--FILE--
|
||||
<?php
|
||||
$h = "1";
|
||||
$h .= "2";
|
||||
try {
|
||||
$h /= 0;
|
||||
} catch (DivisionByZeroError $e) {
|
||||
echo $e->getMessage(), "\n";
|
||||
}
|
||||
var_dump($h);
|
||||
?>
|
||||
--EXPECT--
|
||||
Division by zero
|
||||
string(2) "12"
|
@ -1314,7 +1314,7 @@ ZEND_API zend_result ZEND_FASTCALL div_function(zval *result, zval *op1, zval *o
|
||||
|
||||
ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_DIV);
|
||||
|
||||
zval op1_copy, op2_copy;
|
||||
zval result_copy, op1_copy, op2_copy;
|
||||
if (UNEXPECTED(zendi_try_convert_scalar_to_number(op1, &op1_copy) == FAILURE)
|
||||
|| UNEXPECTED(zendi_try_convert_scalar_to_number(op2, &op2_copy) == FAILURE)) {
|
||||
zend_binop_error("/", op1, op2);
|
||||
@ -1324,12 +1324,12 @@ ZEND_API zend_result ZEND_FASTCALL div_function(zval *result, zval *op1, zval *o
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if (result == op1) {
|
||||
zval_ptr_dtor(result);
|
||||
}
|
||||
|
||||
retval = div_function_base(result, &op1_copy, &op2_copy);
|
||||
retval = div_function_base(&result_copy, &op1_copy, &op2_copy);
|
||||
if (retval == SUCCESS) {
|
||||
if (result == op1) {
|
||||
zval_ptr_dtor(result);
|
||||
}
|
||||
ZVAL_COPY_VALUE(result, &result_copy);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user