Skip to content
Permalink
Browse files Browse the repository at this point in the history
Fix buffer overrun due to integer overflow in bcmath
Summary: scale gets passed around as an int inside the library.

Reviewed By: mxw

Differential Revision: D3624520

fbshipit-source-id: d39927413cec24fda2e475a296ad5d9019ccef0a
  • Loading branch information
mwilliams@fb.com authored and Hhvm Bot committed Aug 1, 2016
1 parent 2c9a8fc commit c00fc9d
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 8 deletions.
25 changes: 17 additions & 8 deletions hphp/runtime/ext/bcmath/ext_bcmath.cpp
Expand Up @@ -39,6 +39,15 @@ static IMPLEMENT_THREAD_LOCAL(bcmath_data, s_globals);

///////////////////////////////////////////////////////////////////////////////

static int64_t adjust_scale(int64_t scale) {
if (scale < 0) {
scale = BCG(bc_precision);
if (scale < 0) scale = 0;
}
if ((uint64_t)scale > StringData::MaxSize) return StringData::MaxSize;
return scale;
}

static void php_str2num(bc_num *num, const char *str) {
const char *p;
if (!(p = strchr(str, '.'))) {
Expand All @@ -55,7 +64,7 @@ static bool HHVM_FUNCTION(bcscale, int64_t scale) {

static String HHVM_FUNCTION(bcadd, const String& left, const String& right,
int64_t scale /* = -1 */) {
if (scale < 0) scale = BCG(bc_precision);
scale = adjust_scale(scale);
bc_num first, second, result;
bc_init_num(&first);
bc_init_num(&second);
Expand All @@ -75,7 +84,7 @@ static String HHVM_FUNCTION(bcadd, const String& left, const String& right,

static String HHVM_FUNCTION(bcsub, const String& left, const String& right,
int64_t scale /* = -1 */) {
if (scale < 0) scale = BCG(bc_precision);
scale = adjust_scale(scale);
bc_num first, second, result;
bc_init_num(&first);
bc_init_num(&second);
Expand All @@ -95,7 +104,7 @@ static String HHVM_FUNCTION(bcsub, const String& left, const String& right,

static int64_t HHVM_FUNCTION(bccomp, const String& left, const String& right,
int64_t scale /* = -1 */) {
if (scale < 0) scale = BCG(bc_precision);
scale = adjust_scale(scale);
bc_num first, second;
bc_init_num(&first);
bc_init_num(&second);
Expand All @@ -109,7 +118,7 @@ static int64_t HHVM_FUNCTION(bccomp, const String& left, const String& right,

static String HHVM_FUNCTION(bcmul, const String& left, const String& right,
int64_t scale /* = -1 */) {
if (scale < 0) scale = BCG(bc_precision);
scale = adjust_scale(scale);
bc_num first, second, result;
bc_init_num(&first);
bc_init_num(&second);
Expand All @@ -129,7 +138,7 @@ static String HHVM_FUNCTION(bcmul, const String& left, const String& right,

static Variant HHVM_FUNCTION(bcdiv, const String& left, const String& right,
int64_t scale /* = -1 */) {
if (scale < 0) scale = BCG(bc_precision);
scale = adjust_scale(scale);
bc_num first, second, result;
bc_init_num(&first);
bc_init_num(&second);
Expand Down Expand Up @@ -171,7 +180,7 @@ static Variant HHVM_FUNCTION(bcmod, const String& left, const String& right) {

static String HHVM_FUNCTION(bcpow, const String& left, const String& right,
int64_t scale /* = -1 */) {
if (scale < 0) scale = BCG(bc_precision);
scale = adjust_scale(scale);
bc_num first, second, result;
bc_init_num(&first);
bc_init_num(&second);
Expand All @@ -193,7 +202,7 @@ static String HHVM_FUNCTION(bcpow, const String& left, const String& right,

static Variant HHVM_FUNCTION(bcpowmod, const String& left, const String& right,
const String& modulus, int64_t scale /* = -1 */) {
if (scale < 0) scale = BCG(bc_precision);
scale = adjust_scale(scale);
bc_num first, second, mod, result;
bc_init_num(&first);
bc_init_num(&second);
Expand All @@ -220,7 +229,7 @@ static Variant HHVM_FUNCTION(bcpowmod, const String& left, const String& right,

static Variant HHVM_FUNCTION(bcsqrt, const String& operand,
int64_t scale /* = -1 */) {
if (scale < 0) scale = BCG(bc_precision);
scale = adjust_scale(scale);
bc_num result;
bc_init_num(&result);
SCOPE_EXIT {
Expand Down
7 changes: 7 additions & 0 deletions hphp/test/slow/ext_bcmath/bccomp_overflow.php
@@ -0,0 +1,7 @@
<?php

$intMaxPre = PHP_INT_MAX - 1;
$stringNormal = 'abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ';

$number_bccomp_10 = bccomp("2015.5", $stringNormal, $intMaxPre);
var_dump($number_bccomp_10);
1 change: 1 addition & 0 deletions hphp/test/slow/ext_bcmath/bccomp_overflow.php.expect
@@ -0,0 +1 @@
int(1)

0 comments on commit c00fc9d

Please sign in to comment.