Skip to content

Commit

Permalink
Zend: fix overflow handling bug in non-x86 fast_add_function()
Browse files Browse the repository at this point in the history
The 'result' argument of fast_add_function() may alias with either
of its operands (or both). Take care not to write to 'result' before
reading op1 and op2.
  • Loading branch information
Ard Biesheuvel committed Dec 11, 2013
1 parent b1b23ab commit 8f1fee6
Showing 1 changed file with 7 additions and 2 deletions.
9 changes: 7 additions & 2 deletions Zend/zend_operators.h
Original file line number Diff line number Diff line change
Expand Up @@ -593,13 +593,18 @@ static zend_always_inline int fast_add_function(zval *result, zval *op1, zval *o
"r"(op2)
: "rax");
#else
Z_LVAL_P(result) = Z_LVAL_P(op1) + Z_LVAL_P(op2);
/*
* 'result' may alias with op1 or op2, so we need to
* ensure that 'result' is not updated until after we
* have read the values of op1 and op2.
*/

if (UNEXPECTED((Z_LVAL_P(op1) & LONG_SIGN_MASK) == (Z_LVAL_P(op2) & LONG_SIGN_MASK)
&& (Z_LVAL_P(op1) & LONG_SIGN_MASK) != (Z_LVAL_P(result) & LONG_SIGN_MASK))) {
&& (Z_LVAL_P(op1) & LONG_SIGN_MASK) != ((Z_LVAL_P(op1) + Z_LVAL_P(op2)) & LONG_SIGN_MASK))) {
Z_DVAL_P(result) = (double) Z_LVAL_P(op1) + (double) Z_LVAL_P(op2);
Z_TYPE_P(result) = IS_DOUBLE;
} else {
Z_LVAL_P(result) = Z_LVAL_P(op1) + Z_LVAL_P(op2);
Z_TYPE_P(result) = IS_LONG;
}
#endif
Expand Down

0 comments on commit 8f1fee6

Please sign in to comment.