Skip to content

Instantly share code, notes, and snippets.

@jnewland
Created July 23, 2008 18:43
Show Gist options
  • Save jnewland/1845 to your computer and use it in GitHub Desktop.
Save jnewland/1845 to your computer and use it in GitHub Desktop.
description, test case, and patches for the recent Ruby CVEs
Multiple integer overflows in the rb_str_buf_append function in
Ruby 1.8.4 and earlier, 1.8.5 before 1.8.5-p231, 1.8.6 before
1.8.6-p230, 1.8.7 before 1.8.7-p22, and 1.9.0 before 1.9.0-2
allow context-dependent attackers to execute arbitrary code or
cause a denial of service via unknown vectors that trigger memory
corruption. (CVE-2008-2662)
Multiple integer overflows in the rb_ary_store function in Ruby
1.8.4 and earlier, 1.8.5 before 1.8.5-p231, 1.8.6 before 1.8.6-p230,
and 1.8.7 before 1.8.7-p22 allow context-dependent attackers to
execute arbitrary code or cause a denial of service via unknown
vectors. (CVE-2008-2663)
The rb_str_format function in Ruby 1.8.4 and earlier, 1.8.5 before
1.8.5-p231, 1.8.6 before 1.8.6-p230, 1.8.7 before 1.8.7-p22, and 1.9.0
before 1.9.0-2 allows context-dependent attackers to trigger memory
corruption via unspecified vectors related to alloca. (CVE-2008-2664)
Integer overflow in the rb_ary_splice function in Ruby 1.8.4
and earlier, 1.8.5 before 1.8.5-p231, 1.8.6 before 1.8.6-p230,
and 1.8.7 before 1.8.7-p22 allows context-dependent attackers to
trigger memory corruption via unspecified vectors, aka the REALLOC_N
variant. (CVE-2008-2725)
Integer overflow in the rb_ary_splice function in Ruby 1.8.4 and
earlier, 1.8.5 before 1.8.5-p231, 1.8.6 before 1.8.6-p230, 1.8.7 before
1.8.7-p22, and 1.9.0 before 1.9.0-2 allows context-dependent attackers
to trigger memory corruption, aka the beg + rlen issue. (CVE-2008-2726)
Integer overflow in the rb_ary_fill function in array.c in Ruby before
revision 17756 allows context-dependent attackers to cause a denial
of service (crash) or possibly have unspecified other impact via a
call to the Array#fill method with a start (aka beg) argument greater
than ARY_MAX_SIZE. (CVE-2008-2376)
diff -Naur ruby-1.8.6-p114/array.c ruby-1.8.6-p114.1/array.c
--- ruby-1.8.6-p114/array.c 2007-09-07 03:46:40.000000000 -0400
+++ ruby-1.8.6-p114.1/array.c 2008-07-18 09:43:28.000000000 -0400
@@ -20,6 +20,7 @@
static ID id_cmp;
#define ARY_DEFAULT_SIZE 16
+#define ARY_MAX_SIZE (LONG_MAX / sizeof(VALUE))
void
rb_mem_clear(mem, size)
@@ -367,7 +368,7 @@
new_capa = ARY_DEFAULT_SIZE;
}
new_capa += idx;
- if (new_capa * (long)sizeof(VALUE) <= new_capa) {
+ if (new_capa < 0 || new_capa > LONG_MAX / sizeof(VALUE)) {
rb_raise(rb_eArgError, "index too big");
}
REALLOC_N(RARRAY(ary)->ptr, VALUE, new_capa);
@@ -976,6 +977,9 @@
if (beg >= RARRAY(ary)->len) {
len = beg + rlen;
+ if (len < 0 || len > LONG_MAX / sizeof(VALUE)) {
+ rb_raise(rb_eIndexError, "index %ld too big", beg);
+ }
if (len >= RARRAY(ary)->aux.capa) {
REALLOC_N(RARRAY(ary)->ptr, VALUE, len);
RARRAY(ary)->aux.capa = len;
@@ -2265,6 +2269,9 @@
break;
}
rb_ary_modify(ary);
+ if (beg >= ARY_MAX_SIZE || len > ARY_MAX_SIZE - beg) {
+ rb_raise(rb_eArgError, "argument too big");
+ }
end = beg + len;
if (end < 0) {
rb_raise(rb_eArgError, "argument too big");
diff -Naur ruby-1.8.6-p114/string.c ruby-1.8.6-p114.1/string.c
--- ruby-1.8.6-p114/string.c 2007-09-07 03:40:27.000000000 -0400
+++ ruby-1.8.6-p114.1/string.c 2008-07-18 09:43:28.000000000 -0400
@@ -458,10 +458,9 @@
VALUE *argv;
if (TYPE(arg) == T_ARRAY) {
- argv = ALLOCA_N(VALUE, RARRAY(arg)->len + 1);
- argv[0] = str;
- MEMCPY(argv+1, RARRAY(arg)->ptr, VALUE, RARRAY(arg)->len);
- return rb_f_sprintf(RARRAY(arg)->len+1, argv);
+ argv = rb_ary_dup(arg);
+ rb_ary_unshift(argv, str);
+ return rb_f_sprintf(RARRAY(arg)->len+1, RARRAY(argv)->ptr);
}
argv = ALLOCA_N(VALUE, 2);
@@ -780,6 +779,9 @@
capa = RSTRING(str)->aux.capa;
}
len = RSTRING(str)->len+RSTRING(str2)->len;
+ if (len < 0 || (capa+1) > LONG_MAX / 2) {
+ rb_raise(rb_eArgError, "string sizes too big");
+ }
if (capa <= len) {
while (len > capa) {
capa = (capa + 1) * 2;
require 'test/unit'
class TestJuneCves < Test::Unit::TestCase
def test_should_raise_index_error
assert_raise ArgumentError do
a = []
a[0x7fffffff] = "A"
end
end
def test_should_allow_ginormous_strings
string = "A" * (2**16); true
size = 0
while 1 && size < 2097152 do
string << string
puts size = string.size
end
assert true
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment