1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
| | Fix CVE-2013-4164:
https://www.ruby-lang.org/en/news/2013/11/22/heap-overflow-in-floating-point-parsing-cve-2013-4164/
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-4164
https://security-tracker.debian.org/tracker/CVE-2013-4164
Patch copied from snapshot.debian.org:
https://snapshot.debian.org/archive/debian-security/20180423T104456Z/pool/updates/main/r/ruby1.8/ruby1.8_1.8.7.358-7.1%2Bdeb7u6.debian.tar.gz
Description: Fix Heap Overflow in Floating Point Parsing
This vulnerability is tracked with CVE-2013-4164.
.
https://www.ruby-lang.org/en/news/2013/11/22/ruby-1-9-3-p484-is-released/
Origin: backport, https://bugs.ruby-lang.org/projects/ruby-193/repository/revisions/43776/diff
https://bugs.ruby-lang.org/projects/ruby-193/repository/revisions/43782/diff
Bug-Debian: http://bugs.debian.org/730189
Forwarded: not-needed
Applied-Upstream: 1.9.3-p484, 2.0.0-p353
Last-Update: 2013-11-29
--- a/util.c
+++ b/util.c
@@ -892,6 +892,11 @@ extern void *MALLOC(size_t);
#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 @@ Balloc(int k)
#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 @@ Balloc(int k)
#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 @@ static void
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 @@ break2:
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++)
--- a/test/ruby/test_float.rb
+++ b/test/ruby/test_float.rb
@@ -171,4 +171,9 @@ class TestFloat < Test::Unit::TestCase
assert_raise(ArgumentError) { 1.0 < nil }
assert_raise(ArgumentError) { 1.0 <= nil }
end
+
+ def test_long_string
+ assert(10.0 - ("1."+"1"*300000).to_f*9 < 0.000001)
+ end
+
end
|