Strings that contain a lot of digits, like "1.341", might overflow and cause unexpected behavior.
There’s a similar issue in Ruby before 2.4 and 2.5, where user input can cause a buffer overflow. It occurs when converting arbitrary strings to floating-point values.
It is likely that you’ve encountered this issue if you’ve ever run a command like this:
$ ruby -e "1.234.564e16".to_f"
In case of this issue, the value passed to the function will be much larger than the buffer allocated for the function call. This can lead to a crash or even arbitrary code execution.
The problem here is that the integer 1.234.564e16 doesn’t fit into a single 32-bit integer.
When the code tries to convert it to a floating point number, it’s possible that a buffer overflows, resulting in a crash or arbitrary code execution.
This problem has been around since Ruby 1.9. It was fixed with the release of Ruby 2.0, but it’s still possible to encounter this problem with Ruby 2.4, 2.5, and 2.6.
There are two types of issues that can occur in this case.
If the code is checking for an integer value that does not fit into a 32-bit integer, it will
Ruby 2.6 - String Overflow
In Ruby 2.6, the problem is fixed by allocating a larger buffer.
If the code is checking for an integer value that does not fit into a 32-bit integer, it will allocate a larger buffer to handle the value. This will not cause an overflow and there should be no crashes or timeouts in this case.
Problem with integer overflow and underflow
First, this is a problem with integer overflow and underflow. This means that when
the code tries to convert an input value that is not representable as a 32-bit integer into a floating point number, the result will be either an exception or the resulting 32-bit integer value.
Second, even though you can encounter this issue in Ruby 1.9 and 2.0, it has been fixed in Ruby 2.0 and later.
How to avoid this issue?
There are two ways to avoid this issue:
The first is to add the right amount of padding to your input string. For example, if you need a floating point number with a 10-digit decimal value, you can do:
"1.234.564e16".to_f(10)
This will ensure that your input doesn't overflow when converting it to a floating point number. Secondly, you can use the truncate method on strings in Ruby 2.6 and higher. This method will truncate the string at a specified length and prevent any overflow from happening.
Crash when String Overflow is Detected
This is an issue with the specific code, where it will cause a crash when the value passed to it is too large for the size of the buffer allocated. You can avoid this issue by using a 32-bit integer for the buffer allocation and checking for integers that are too large to fit into a single 32-bit integer before converting them to floats.
If the code is performing some kind of binary operation on two strings, it will
Issue-1 - Integer overflow in Ruby
The first issue is when a buffer overflows in the code that checks for an integer that does not fit into a 32-bit integer.
This will cause the following error:
Invalid argument (Large object), noMethodError: undefined method `to_i' for nil:NilClass
This means that the value of 1.234.564e16 is too large to convert to a single integer, so it overflows and causes this error.
If you have been experiencing this error, then we recommend you upgrade Ruby to 2.0 or greater to fix these issues.
Timeline
Published on: 05/09/2022 18:15:00 UTC
Last modified on: 06/24/2022 16:15:00 UTC
References
- https://hackerone.com/reports/1248108
- https://security-tracker.debian.org/tracker/CVE-2022-28739
- https://www.ruby-lang.org/en/news/2022/04/12/buffer-overrun-in-string-to-float-cve-2022-28739/
- https://security.netapp.com/advisory/ntap-20220624-0002/
- https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2022-28739