Skip to content

Commit a7cc248

Browse files
mwilliams@fb.comOrvid
mwilliams@fb.com
authored andcommitted
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
1 parent f8f9559 commit a7cc248

File tree

3 files changed

+25
-8
lines changed

3 files changed

+25
-8
lines changed

hphp/runtime/ext/bcmath/ext_bcmath.cpp

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,15 @@ static IMPLEMENT_THREAD_LOCAL(bcmath_data, s_globals);
4040

4141
///////////////////////////////////////////////////////////////////////////////
4242

43+
static int64_t adjust_scale(int64_t scale) {
44+
if (scale < 0) {
45+
scale = BCG(bc_precision);
46+
if (scale < 0) scale = 0;
47+
}
48+
if ((uint64_t)scale > StringData::MaxSize) return StringData::MaxSize;
49+
return scale;
50+
}
51+
4352
static void php_str2num(bc_num *num, const char *str) {
4453
const char *p;
4554
if (!(p = strchr(str, '.'))) {
@@ -56,7 +65,7 @@ static bool HHVM_FUNCTION(bcscale, int64_t scale) {
5665

5766
static String HHVM_FUNCTION(bcadd, const String& left, const String& right,
5867
int64_t scale /* = -1 */) {
59-
if (scale < 0) scale = BCG(bc_precision);
68+
scale = adjust_scale(scale);
6069
bc_num first, second, result;
6170
bc_init_num(&first);
6271
bc_init_num(&second);
@@ -76,7 +85,7 @@ static String HHVM_FUNCTION(bcadd, const String& left, const String& right,
7685

7786
static String HHVM_FUNCTION(bcsub, const String& left, const String& right,
7887
int64_t scale /* = -1 */) {
79-
if (scale < 0) scale = BCG(bc_precision);
88+
scale = adjust_scale(scale);
8089
bc_num first, second, result;
8190
bc_init_num(&first);
8291
bc_init_num(&second);
@@ -96,7 +105,7 @@ static String HHVM_FUNCTION(bcsub, const String& left, const String& right,
96105

97106
static int64_t HHVM_FUNCTION(bccomp, const String& left, const String& right,
98107
int64_t scale /* = -1 */) {
99-
if (scale < 0) scale = BCG(bc_precision);
108+
scale = adjust_scale(scale);
100109
bc_num first, second;
101110
bc_init_num(&first);
102111
bc_init_num(&second);
@@ -110,7 +119,7 @@ static int64_t HHVM_FUNCTION(bccomp, const String& left, const String& right,
110119

111120
static String HHVM_FUNCTION(bcmul, const String& left, const String& right,
112121
int64_t scale /* = -1 */) {
113-
if (scale < 0) scale = BCG(bc_precision);
122+
scale = adjust_scale(scale);
114123
bc_num first, second, result;
115124
bc_init_num(&first);
116125
bc_init_num(&second);
@@ -130,7 +139,7 @@ static String HHVM_FUNCTION(bcmul, const String& left, const String& right,
130139

131140
static Variant HHVM_FUNCTION(bcdiv, const String& left, const String& right,
132141
int64_t scale /* = -1 */) {
133-
if (scale < 0) scale = BCG(bc_precision);
142+
scale = adjust_scale(scale);
134143
bc_num first, second, result;
135144
bc_init_num(&first);
136145
bc_init_num(&second);
@@ -172,7 +181,7 @@ static Variant HHVM_FUNCTION(bcmod, const String& left, const String& right) {
172181

173182
static String HHVM_FUNCTION(bcpow, const String& left, const String& right,
174183
int64_t scale /* = -1 */) {
175-
if (scale < 0) scale = BCG(bc_precision);
184+
scale = adjust_scale(scale);
176185
bc_num first, second, result;
177186
bc_init_num(&first);
178187
bc_init_num(&second);
@@ -194,7 +203,7 @@ static String HHVM_FUNCTION(bcpow, const String& left, const String& right,
194203

195204
static Variant HHVM_FUNCTION(bcpowmod, const String& left, const String& right,
196205
const String& modulus, int64_t scale /* = -1 */) {
197-
if (scale < 0) scale = BCG(bc_precision);
206+
scale = adjust_scale(scale);
198207
bc_num first, second, mod, result;
199208
bc_init_num(&first);
200209
bc_init_num(&second);
@@ -221,7 +230,7 @@ static Variant HHVM_FUNCTION(bcpowmod, const String& left, const String& right,
221230

222231
static Variant HHVM_FUNCTION(bcsqrt, const String& operand,
223232
int64_t scale /* = -1 */) {
224-
if (scale < 0) scale = BCG(bc_precision);
233+
scale = adjust_scale(scale);
225234
bc_num result;
226235
bc_init_num(&result);
227236
SCOPE_EXIT {
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
$intMaxPre = PHP_INT_MAX - 1;
4+
$stringNormal = 'abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ';
5+
6+
$number_bccomp_10 = bccomp("2015.5", $stringNormal, $intMaxPre);
7+
var_dump($number_bccomp_10);
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
int(1)

0 commit comments

Comments
 (0)