You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Here we show the bug in the mruby with the build config from mruby-engine. So MRB_INT64 and MRB_WORD_BOXING is included in conf.cc.defines. The MRB_INT_MAX of this build is 4611686018427387903 (2^62 - 1). The bug is also presented in other build configurations, but may triggered with different input.
Note that the other operators (add, sub, ...) does check the overflow properly.
The root cause of this bug is very subtle. Here is how mruby implements num_pow:
Unfortunately, C macro expansion is just a typeless simple substitution. Since the variable d is a mrb_float, the constantsMRB_INT_MAX and MRB_INT_MIN are silently promoted from mrb_int to mrb_float as well. But the significand precision of double-precision floating-point is only 53 bits, so this check is passed. We can verify this behavior in python:
$ python>>>float(2**62) <=float(2**62-1)
True
Another subtly failed overflow checking is (d > 0 && (mrb_int)d > 0). Because d is only 2^62, we can convert it to mrb_int without any problem. But when build with MRB_WORD_BOXING, the correspond slot in the mrb_value struct is a 63 bits bit-field:
So the value survives these two checks, but still cause an integer overflow.
When reviewing this bug, I found that in mruby, some functions pass int64_t to FIXABLE like int64_value, which has no problem. But there are many other places pass floating point to FIXABLE like flo_ceil, flo_floor, etc. All of them have the same problem as num_pow.
If there is any business logic or boundary check rely on this, it would fail.
A possible fix is split the macro into two macros/functions, like FIXABLE_INT and FIXABLE_FLOAT. I can provide a patch if needed, but I think we may need someone (Matz?) who is familiar with the codebase of mruby to check the impact of this bug.
The text was updated successfully, but these errors were encountered:
https://hackerone.com/shikchen reported the following:
Here we show the bug in the mruby with the build config from mruby-engine. So
MRB_INT64
andMRB_WORD_BOXING
is included inconf.cc.defines
. TheMRB_INT_MAX
of this build is4611686018427387903 (2^62 - 1)
. The bug is also presented in other build configurations, but may triggered with different input.Note that the other operators (add, sub, ...) does check the overflow properly.
The root cause of this bug is very subtle. Here is how mruby implements
num_pow
:The key part for overflow checking is
FIXABLE
, a C macro:Unfortunately, C macro expansion is just a typeless simple substitution. Since the variable
d
is amrb_float
, the constantsMRB_INT_MAX
andMRB_INT_MIN
are silently promoted frommrb_int
tomrb_float
as well. But the significand precision of double-precision floating-point is only 53 bits, so this check is passed. We can verify this behavior in python:Another subtly failed overflow checking is
(d > 0 && (mrb_int)d > 0)
. Becaused
is only2^62
, we can convert it tomrb_int
without any problem. But when build withMRB_WORD_BOXING
, the correspond slot in themrb_value
struct is a 63 bits bit-field:So the value survives these two checks, but still cause an integer overflow.
When reviewing this bug, I found that in mruby, some functions pass
int64_t
toFIXABLE
likeint64_value
, which has no problem. But there are many other places pass floating point toFIXABLE
likeflo_ceil
,flo_floor
, etc. All of them have the same problem asnum_pow
.If there is any business logic or boundary check rely on this, it would fail.
A possible fix is split the macro into two macros/functions, like
FIXABLE_INT
andFIXABLE_FLOAT
. I can provide a patch if needed, but I think we may need someone (Matz?) who is familiar with the codebase of mruby to check the impact of this bug.The text was updated successfully, but these errors were encountered: