This ruby 1.8.7 patch was derived from the ruby 1.9.3 fix for:
https://www.ruby-lang.org/en/news/2013/11/22/heap-overflow-in-floating-point-parsing-cve-2013-4164/
as seen here:
http://bugs.ruby-lang.org/projects/ruby-trunk/repository/diff/util.c?rev=43780&rev_to=41757
CVE-2013-4164
Heap-based buffer overflow in Ruby 1.8, 1.9 before 1.9.3-p484, 2.0
before 2.0.0-p353, 2.1 before 2.1.0 preview2, and trunk before revision
43780 allows context-dependent attackers to cause a denial of service
(segmentation fault) and possibly execute arbitrary code via a string
that is converted to a floating point value, as demonstrated using (1)
the to_f method or (2) JSON.parse.
--- ruby-1.8.7-p374-orig/util.c 2010-11-21 23:21:34.000000000 -0800
+++ ruby-1.8.7-p374/util.c 2013-12-02 16:58:32.995038000 -0800
@@ -892,6 +892,11 @@
#else
#define MALLOC malloc
#endif
+#ifdef FREE
+extern void FREE(void*);
+#else
+#define FREE free
+#endif
#ifndef Omit_Private_Memory
#ifndef PRIVATE_MEM
@@ -1176,7 +1181,7 @@
#endif
ACQUIRE_DTOA_LOCK(0);
- if ((rv = freelist[k]) != 0) {
+ if (k <= Kmax && (rv = freelist[k]) != 0) {
freelist[k] = rv->next;
}
else {
@@ -1186,7 +1191,7 @@
#else
len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
/sizeof(double);
- if (pmem_next - private_mem + len <= PRIVATE_mem) {
+ if (k <= Kmax && pmem_next - private_mem + len <= PRIVATE_mem) {
rv = (Bigint*)pmem_next;
pmem_next += len;
}
@@ -1205,6 +1210,10 @@
Bfree(Bigint *v)
{
if (v) {
+ if (v->k > Kmax) {
+ FREE(v);
+ return;
+ }
ACQUIRE_DTOA_LOCK(0);
v->next = freelist[v->k];
freelist[v->k] = v;
@@ -2200,6 +2209,7 @@
for (; c >= '0' && c <= '9'; c = *++s) {
have_dig:
nz++;
+ if (nf > DBL_DIG * 4) continue;
if (c -= '0') {
nf += nz;
for (i = 1; i < nz; i++)