ruby-changes:5956
From: shyouhei <ko1@a...>
Date: Fri, 20 Jun 2008 08:13:34 +0900 (JST)
Subject: [ruby-changes:5956] Ruby:r17460 (ruby_1_8_6, trunk, ruby_1_8_5, ruby_1_8, ruby_1_8_7): * array.c (ary_new, rb_ary_initialize, rb_ary_store,
shyouhei 2008-06-20 08:12:46 +0900 (Fri, 20 Jun 2008)
New Revision: 17460
Modified files:
branches/ruby_1_8/ChangeLog
branches/ruby_1_8/array.c
branches/ruby_1_8/intern.h
branches/ruby_1_8/sprintf.c
branches/ruby_1_8/string.c
branches/ruby_1_8_5/ChangeLog
branches/ruby_1_8_5/array.c
branches/ruby_1_8_5/intern.h
branches/ruby_1_8_5/sprintf.c
branches/ruby_1_8_5/string.c
branches/ruby_1_8_5/version.h
branches/ruby_1_8_6/ChangeLog
branches/ruby_1_8_6/array.c
branches/ruby_1_8_6/intern.h
branches/ruby_1_8_6/sprintf.c
branches/ruby_1_8_6/string.c
branches/ruby_1_8_6/version.h
branches/ruby_1_8_7/ChangeLog
branches/ruby_1_8_7/array.c
branches/ruby_1_8_7/intern.h
branches/ruby_1_8_7/sprintf.c
branches/ruby_1_8_7/string.c
branches/ruby_1_8_7/version.h
trunk/ChangeLog
trunk/array.c
trunk/string.c
Log:
* array.c (ary_new, rb_ary_initialize, rb_ary_store,
rb_ary_aplice, rb_ary_times): integer overflows should be
checked. based on patches from Drew Yao <ayao at apple.com>
fixed CVE-2008-2726
* string.c (rb_str_buf_append): fixed unsafe use of alloca,
which led memory corruption. based on a patch from Drew Yao
<ayao at apple.com> fixed CVE-2008-2726
* sprintf.c (rb_str_format): backported from trunk.
* intern.h: ditto.
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_6/intern.h?r1=17460&r2=17459&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_6/ChangeLog?r1=17460&r2=17459&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/string.c?r1=17460&r2=17459&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/array.c?r1=17460&r2=17459&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_6/version.h?r1=17460&r2=17459&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_5/sprintf.c?r1=17460&r2=17459&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8/intern.h?r1=17460&r2=17459&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8/ChangeLog?r1=17460&r2=17459&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/ChangeLog?r1=17460&r2=17459&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8/sprintf.c?r1=17460&r2=17459&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_7/ChangeLog?r1=17460&r2=17459&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_5/string.c?r1=17460&r2=17459&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_5/intern.h?r1=17460&r2=17459&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_6/sprintf.c?r1=17460&r2=17459&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_7/string.c?r1=17460&r2=17459&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_7/sprintf.c?r1=17460&r2=17459&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_5/version.h?r1=17460&r2=17459&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_5/array.c?r1=17460&r2=17459&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8/array.c?r1=17460&r2=17459&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_6/string.c?r1=17460&r2=17459&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_6/array.c?r1=17460&r2=17459&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_7/version.h?r1=17460&r2=17459&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_7/intern.h?r1=17460&r2=17459&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_7/array.c?r1=17460&r2=17459&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_5/ChangeLog?r1=17460&r2=17459&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8/string.c?r1=17460&r2=17459&diff_format=u
Index: array.c
===================================================================
--- array.c (revision 17459)
+++ array.c (revision 17460)
@@ -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(register VALUE *mem, register long size)
@@ -114,7 +115,7 @@
if (len < 0) {
rb_raise(rb_eArgError, "negative array size (or size too big)");
}
- if (len > LONG_MAX / sizeof(VALUE)) {
+ if (len > ARY_MAX_SIZE) {
rb_raise(rb_eArgError, "array size too big");
}
ary = ary_alloc(klass);
@@ -313,7 +314,7 @@
if (len < 0) {
rb_raise(rb_eArgError, "negative array size");
}
- if (len > LONG_MAX / sizeof(VALUE)) {
+ if (len > ARY_MAX_SIZE) {
rb_raise(rb_eArgError, "array size too big");
}
rb_ary_modify(ary);
@@ -371,6 +372,9 @@
idx - RARRAY_LEN(ary));
}
}
+ else if (idx >= ARY_MAX_SIZE) {
+ rb_raise(rb_eIndexError, "index %ld too big", idx);
+ }
rb_ary_modify(ary);
if (idx >= ARY_CAPA(ary)) {
@@ -379,13 +383,10 @@
if (new_capa < ARY_DEFAULT_SIZE) {
new_capa = ARY_DEFAULT_SIZE;
}
- if (new_capa + idx < new_capa) {
- rb_raise(rb_eArgError, "index too big");
+ else if (new_capa >= ARY_MAX_SIZE - idx) {
+ new_capa = (ARY_MAX_SIZE - idx) / 2;
}
new_capa += idx;
- if (new_capa * (long)sizeof(VALUE) <= new_capa) {
- rb_raise(rb_eArgError, "index too big");
- }
RESIZE_CAPA(ary, new_capa);
}
if (idx > RARRAY_LEN(ary)) {
@@ -986,6 +987,9 @@
rb_ary_modify(ary);
if (beg >= RARRAY_LEN(ary)) {
len = beg + rlen;
+ if (len < 0 || len > ARY_MAX_SIZE) {
+ rb_raise(rb_eIndexError, "index %ld too big", beg);
+ }
if (len >= ARY_CAPA(ary)) {
RESIZE_CAPA(ary, len);
}
@@ -2250,7 +2254,7 @@
if (len < 0) {
rb_raise(rb_eArgError, "negative argument");
}
- if (LONG_MAX/len < RARRAY_LEN(ary)) {
+ if (ARY_MAX_SIZE/len < RARRAY_LEN(ary)) {
rb_raise(rb_eArgError, "argument too big");
}
len *= RARRAY_LEN(ary);
Index: ChangeLog
===================================================================
--- ChangeLog (revision 17459)
+++ ChangeLog (revision 17460)
@@ -1,3 +1,14 @@
+Wed Jun 18 21:52:38 2008 URABE Shyouhei <shyouhei@r...>
+
+ * array.c (ary_new, rb_ary_initialize, rb_ary_store,
+ rb_ary_aplice, rb_ary_times): integer overflows should be
+ checked. based on patches from Drew Yao <ayao at apple.com>
+ fixed CVE-2008-2726
+
+ * string.c (rb_enc_cr_str_buf_cat): fixed unsafe use of alloca,
+ which led memory corruption. based on a patch from Drew Yao
+ <ayao at apple.com> fixed CVE-2008-2726
+
Fri Jun 20 03:26:00 2008 NAKAMURA Usaku <usa@r...>
* process.c (rb_f_fork): NetBSD 4.0 or later can fork.
Index: string.c
===================================================================
--- string.c (revision 17459)
+++ string.c (revision 17460)
@@ -1562,6 +1562,9 @@
capa = RSTRING(str)->as.heap.aux.capa;
}
total = RSTRING_LEN(str)+len;
+ if (total < 0 || capa + 1 > LONG_MAX / 2) {
+ rb_raise(rb_eArgError, "string sizes too big");
+ }
if (capa <= total) {
while (total > capa) {
capa = (capa + 1) * 2;
Index: ruby_1_8/intern.h
===================================================================
--- ruby_1_8/intern.h (revision 17459)
+++ ruby_1_8/intern.h (revision 17460)
@@ -418,6 +418,7 @@
void ruby_default_signal _((int));
/* sprintf.c */
VALUE rb_f_sprintf _((int, VALUE*));
+VALUE rb_str_format _((int, VALUE*, VALUE));
/* string.c */
VALUE rb_str_new _((const char*, long));
VALUE rb_str_new2 _((const char*));
Index: ruby_1_8/array.c
===================================================================
--- ruby_1_8/array.c (revision 17459)
+++ ruby_1_8/array.c (revision 17460)
@@ -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)
@@ -120,7 +121,7 @@
if (len < 0) {
rb_raise(rb_eArgError, "negative array size (or size too big)");
}
- if (len > 0 && len * sizeof(VALUE) <= len) {
+ if (len > ARY_MAX_SIZE) {
rb_raise(rb_eArgError, "array size too big");
}
if (len == 0) len++;
@@ -314,7 +315,7 @@
if (len < 0) {
rb_raise(rb_eArgError, "negative array size");
}
- if (len > 0 && len * (long)sizeof(VALUE) <= len) {
+ if (len > ARY_MAX_SIZE) {
rb_raise(rb_eArgError, "array size too big");
}
if (len > RARRAY(ary)->aux.capa) {
@@ -379,6 +380,9 @@
idx - RARRAY(ary)->len);
}
}
+ else if (idx >= ARY_MAX_SIZE) {
+ rb_raise(rb_eIndexError, "index %ld too big", idx);
+ }
rb_ary_modify(ary);
if (idx >= RARRAY(ary)->aux.capa) {
@@ -387,10 +391,10 @@
if (new_capa < ARY_DEFAULT_SIZE) {
new_capa = ARY_DEFAULT_SIZE;
}
+ else if (new_capa >= ARY_MAX_SIZE - idx) {
+ new_capa = (ARY_MAX_SIZE - idx) / 2;
+ }
new_capa += idx;
- if (new_capa * (long)sizeof(VALUE) <= new_capa) {
- rb_raise(rb_eArgError, "index too big");
- }
REALLOC_N(RARRAY(ary)->ptr, VALUE, new_capa);
RARRAY(ary)->aux.capa = new_capa;
}
@@ -1091,6 +1095,9 @@
if (beg >= RARRAY(ary)->len) {
len = beg + rlen;
+ if (len < 0 || len > ARY_MAX_SIZE) {
+ 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;
@@ -2522,7 +2529,7 @@
if (len < 0) {
rb_raise(rb_eArgError, "negative argument");
}
- if (LONG_MAX/len < RARRAY(ary)->len) {
+ if (ARY_MAX_SIZE/len < RARRAY(ary)->len) {
rb_raise(rb_eArgError, "argument too big");
}
len *= RARRAY(ary)->len;
Index: ruby_1_8/ChangeLog
===================================================================
--- ruby_1_8/ChangeLog (revision 17459)
+++ ruby_1_8/ChangeLog (revision 17460)
@@ -1,3 +1,18 @@
+Wed Jun 18 22:17:35 2008 URABE Shyouhei <shyouhei@r...>
+
+ * array.c (ary_new, rb_ary_initialize, rb_ary_store,
+ rb_ary_aplice, rb_ary_times): integer overflows should be
+ checked. based on patches from Drew Yao <ayao at apple.com>
+ fixed CVE-2008-2726
+
+ * string.c (rb_str_buf_append): fixed unsafe use of alloca,
+ which led memory corruption. based on a patch from Drew Yao
+ <ayao at apple.com> fixed CVE-2008-2726
+
+ * sprintf.c (rb_str_format): backported from trunk.
+
+ * intern.h: ditto.
+
Fri Jun 20 02:16:43 2008 Yukihiro Matsumoto <matz@r...>
* lib/mathn.rb (Rational::power2): typo fixed. [ruby-core:17293]
Index: ruby_1_8/string.c
===================================================================
--- ruby_1_8/string.c (revision 17459)
+++ ruby_1_8/string.c (revision 17460)
@@ -459,22 +459,15 @@
*/
static VALUE
-rb_str_format(str, arg)
+rb_str_format_m(str, arg)
VALUE str, arg;
{
- VALUE *argv;
+ VALUE tmp = rb_check_array_type(arg);
- 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);
+ if (!NIL_P(tmp)) {
+ return rb_str_format(RARRAY_LEN(tmp), RARRAY_PTR(tmp), str);
}
-
- argv = ALLOCA_N(VALUE, 2);
- argv[0] = str;
- argv[1] = arg;
- return rb_f_sprintf(2, argv);
+ return rb_str_format(1, &arg, str);
}
static int
@@ -795,6 +788,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;
@@ -4923,7 +4919,7 @@
rb_define_method(rb_cString, "casecmp", rb_str_casecmp, 1);
rb_define_method(rb_cString, "+", rb_str_plus, 1);
rb_define_method(rb_cString, "*", rb_str_times, 1);
- rb_define_method(rb_cString, "%", rb_str_format, 1);
+ rb_define_method(rb_cString, "%", rb_str_format_m, 1);
rb_define_method(rb_cString, "[]", rb_str_aref_m, -1);
rb_define_method(rb_cString, "[]=", rb_str_aset_m, -1);
rb_define_method(rb_cString, "insert", rb_str_insert, 2);
Index: ruby_1_8/sprintf.c
===================================================================
--- ruby_1_8/sprintf.c (revision 17459)
+++ ruby_1_8/sprintf.c (revision 17460)
@@ -249,7 +249,15 @@
int argc;
VALUE *argv;
{
+ return rb_str_format(argc - 1, argv + 1, GETNTHARG(0));
+}
+
+VALUE
+rb_str_format(argc, argv, fmt)
+ int argc;
+ VALUE *argv;
VALUE fmt;
+{
const char *p, *end;
char *buf;
int blen, bsiz;
@@ -278,7 +286,8 @@
rb_raise(rb_eArgError, "flag after precision"); \
}
- fmt = GETNTHARG(0);
+ ++argc;
+ --argv;
if (OBJ_TAINTED(fmt)) tainted = 1;
StringValue(fmt);
fmt = rb_str_new4(fmt);
Index: ruby_1_8_5/intern.h
===================================================================
--- ruby_1_8_5/intern.h (revision 17459)
+++ ruby_1_8_5/intern.h (revision 17460)
@@ -392,6 +392,7 @@
const char *ruby_signal_name _((int));
/* sprintf.c */
VALUE rb_f_sprintf _((int, VALUE*));
+VALUE rb_str_format _((int, VALUE*, VALUE));
/* string.c */
VALUE rb_str_new _((const char*, long));
VALUE rb_str_new2 _((const char*));
Index: ruby_1_8_5/array.c
===================================================================
--- ruby_1_8_5/array.c (revision 17459)
+++ ruby_1_8_5/array.c (revision 17460)
@@ -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)
@@ -120,7 +121,7 @@
if (len < 0) {
rb_raise(rb_eArgError, "negative array size (or size too big)");
}
- if (len > 0 && len * sizeof(VALUE) <= len) {
+ if (len > ARY_MAX_SIZE) {
rb_raise(rb_eArgError, "array size too big");
}
if (len == 0) len++;
@@ -293,7 +294,7 @@
if (len < 0) {
rb_raise(rb_eArgError, "negative array size");
}
- if (len > 0 && len * (long)sizeof(VALUE) <= len) {
+ if (len > ARY_MAX_SIZE) {
rb_raise(rb_eArgError, "array size too big");
}
if (len > RARRAY(ary)->aux.capa) {
@@ -358,6 +359,9 @@
idx - RARRAY(ary)->len);
}
}
+ else if (idx >= ARY_MAX_SIZE) {
+ rb_raise(rb_eIndexError, "index %ld too big", idx);
+ }
rb_ary_modify(ary);
if (idx >= RARRAY(ary)->aux.capa) {
@@ -366,10 +370,10 @@
if (new_capa < ARY_DEFAULT_SIZE) {
new_capa = ARY_DEFAULT_SIZE;
}
+ else if (new_capa >= ARY_MAX_SIZE - idx) {
+ new_capa = (ARY_MAX_SIZE - idx) / 2;
+ }
new_capa += idx;
- if (new_capa * (long)sizeof(VALUE) <= new_capa) {
- rb_raise(rb_eArgError, "index too big");
- }
REALLOC_N(RARRAY(ary)->ptr, VALUE, new_capa);
RARRAY(ary)->aux.capa = new_capa;
}
@@ -968,6 +972,9 @@
if (beg >= RARRAY(ary)->len) {
len = beg + rlen;
+ if (len < 0 || len > ARY_MAX_SIZE) {
+ 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;
@@ -2370,7 +2377,7 @@
if (len < 0) {
rb_raise(rb_eArgError, "negative argument");
}
- if (LONG_MAX/len < RARRAY(ary)->len) {
+ if (ARY_MAX_SIZE/len < RARRAY(ary)->len) {
rb_raise(rb_eArgError, "argument too big");
}
len *= RARRAY(ary)->len;
Index: ruby_1_8_5/ChangeLog
===================================================================
--- ruby_1_8_5/ChangeLog (revision 17459)
+++ ruby_1_8_5/ChangeLog (revision 17460)
@@ -1,3 +1,18 @@
+Wed Jun 18 22:25:28 2008 URABE Shyouhei <shyouhei@r...>
+
+ * array.c (ary_new, rb_ary_initialize, rb_ary_store,
+ rb_ary_aplice, rb_ary_times): integer overflows should be
+ checked. based on patches from Drew Yao <ayao at apple.com>
+ fixed CVE-2008-2726
+
+ * string.c (rb_str_buf_append): fixed unsafe use of alloca,
+ which led memory corruption. based on a patch from Drew Yao
+ <ayao at apple.com> fixed CVE-2008-2726
+
+ * sprintf.c (rb_str_format): backported from trunk.
+
+ * intern.h: ditto.
+
Fri Jun 20 01:40:21 2008 Nobuyoshi Nakada <nobu@r...>
* array.c (rb_ary_equal, rb_ary_eql, rb_ary_hash, rb_ary_cmp):
Index: ruby_1_8_5/version.h
===================================================================
--- ruby_1_8_5/version.h (revision 17459)
+++ ruby_1_8_5/version.h (revision 17460)
@@ -2,7 +2,7 @@
#define RUBY_RELEASE_DATE "2008-06-20"
#define RUBY_VERSION_CODE 185
#define RUBY_RELEASE_CODE 20080620
-#define RUBY_PATCHLEVEL 228
+#define RUBY_PATCHLEVEL 229
#define RUBY_VERSION_MAJOR 1
#define RUBY_VERSION_MINOR 8
Index: ruby_1_8_5/string.c
===================================================================
--- ruby_1_8_5/string.c (revision 17459)
+++ ruby_1_8_5/string.c (revision 17460)
@@ -450,22 +450,15 @@
*/
static VALUE
-rb_str_format(str, arg)
+rb_str_format_m(str, arg)
VALUE str, arg;
{
- VALUE *argv;
+ VALUE tmp = rb_check_array_type(arg);
- 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);
+ if (!NIL_P(tmp)) {
+ return rb_str_format(RARRAY(tmp)->len, RARRAY(tmp)->ptr, str);
}
-
- argv = ALLOCA_N(VALUE, 2);
- argv[0] = str;
- argv[1] = arg;
- return rb_f_sprintf(2, argv);
+ return rb_str_format(1, &arg, str);
}
static int
@@ -777,6 +770,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;
@@ -4651,7 +4647,7 @@
rb_define_method(rb_cString, "casecmp", rb_str_casecmp, 1);
rb_define_method(rb_cString, "+", rb_str_plus, 1);
rb_define_method(rb_cString, "*", rb_str_times, 1);
- rb_define_method(rb_cString, "%", rb_str_format, 1);
+ rb_define_method(rb_cString, "%", rb_str_format_m, 1);
rb_define_method(rb_cString, "[]", rb_str_aref_m, -1);
rb_define_method(rb_cString, "[]=", rb_str_aset_m, -1);
rb_define_method(rb_cString, "insert", rb_str_insert, 2);
Index: ruby_1_8_5/sprintf.c
===================================================================
--- ruby_1_8_5/sprintf.c (revision 17459)
+++ ruby_1_8_5/sprintf.c (revision 17460)
@@ -247,7 +247,15 @@
int argc;
VALUE *argv;
{
+ return rb_str_format(argc - 1, argv + 1, GETNTHARG(0));
+}
+
+VALUE
+rb_str_format(argc, argv, fmt)
+ int argc;
+ VALUE *argv;
VALUE fmt;
+{
const char *p, *end;
char *buf;
int blen, bsiz;
@@ -276,7 +284,8 @@
rb_raise(rb_eArgError, "flag after precision"); \
}
- fmt = GETNTHARG(0);
+ ++argc;
+ --argv;
if (OBJ_TAINTED(fmt)) tainted = 1;
StringValue(fmt);
fmt = rb_str_new4(fmt);
Index: ruby_1_8_6/intern.h
===================================================================
--- ruby_1_8_6/intern.h (revision 17459)
+++ ruby_1_8_6/intern.h (revision 17460)
@@ -400,6 +400,7 @@
void ruby_default_signal _((int));
/* sprintf.c */
VALUE rb_f_sprintf _((int, VALUE*));
+VALUE rb_str_format _((int, VALUE*, VALUE));
/* string.c */
VALUE rb_str_new _((const char*, long));
VALUE rb_str_new2 _((const char*));
Index: ruby_1_8_6/array.c
===================================================================
--- ruby_1_8_6/array.c (revision 17459)
+++ ruby_1_8_6/array.c (revision 17460)
@@ -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)
@@ -120,7 +121,7 @@
if (len < 0) {
rb_raise(rb_eArgError, "negative array size (or size too big)");
}
- if (len > 0 && len * sizeof(VALUE) <= len) {
+ if (len > ARY_MAX_SIZE) {
rb_raise(rb_eArgError, "array size too big");
}
if (len == 0) len++;
@@ -293,7 +294,7 @@
if (len < 0) {
rb_raise(rb_eArgError, "negative array size");
}
- if (len > 0 && len * (long)sizeof(VALUE) <= len) {
+ if (len > ARY_MAX_SIZE) {
rb_raise(rb_eArgError, "array size too big");
}
if (len > RARRAY(ary)->aux.capa) {
@@ -358,6 +359,9 @@
idx - RARRAY(ary)->len);
}
}
+ else if (idx >= ARY_MAX_SIZE) {
+ rb_raise(rb_eIndexError, "index %ld too big", idx);
+ }
rb_ary_modify(ary);
if (idx >= RARRAY(ary)->aux.capa) {
@@ -366,10 +370,10 @@
if (new_capa < ARY_DEFAULT_SIZE) {
new_capa = ARY_DEFAULT_SIZE;
}
+ else if (new_capa >= ARY_MAX_SIZE - idx) {
+ new_capa = (ARY_MAX_SIZE - idx) / 2;
+ }
new_capa += idx;
- if (new_capa * (long)sizeof(VALUE) <= new_capa) {
- rb_raise(rb_eArgError, "index too big");
- }
REALLOC_N(RARRAY(ary)->ptr, VALUE, new_capa);
RARRAY(ary)->aux.capa = new_capa;
}
@@ -976,6 +980,9 @@
if (beg >= RARRAY(ary)->len) {
len = beg + rlen;
+ if (len < 0 || len > ARY_MAX_SIZE) {
+ 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;
@@ -2378,7 +2385,7 @@
if (len < 0) {
rb_raise(rb_eArgError, "negative argument");
}
- if (LONG_MAX/len < RARRAY(ary)->len) {
+ if (ARY_MAX_SIZE/len < RARRAY(ary)->len) {
rb_raise(rb_eArgError, "argument too big");
}
len *= RARRAY(ary)->len;
Index: ruby_1_8_6/ChangeLog
===================================================================
--- ruby_1_8_6/ChangeLog (revision 17459)
+++ ruby_1_8_6/ChangeLog (revision 17460)
@@ -1,3 +1,18 @@
+Wed Jun 18 22:25:10 2008 URABE Shyouhei <shyouhei@r...>
+
+ * array.c (ary_new, rb_ary_initialize, rb_ary_store,
+ rb_ary_aplice, rb_ary_times): integer overflows should be
+ checked. based on patches from Drew Yao <ayao at apple.com>
+ fixed CVE-2008-2726
+
+ * string.c (rb_str_buf_append): fixed unsafe use of alloca,
+ which led memory corruption. based on a patch from Drew Yao
+ <ayao at apple.com> fixed CVE-2008-2726
+
+ * sprintf.c (rb_str_format): backported from trunk.
+
+ * intern.h: ditto.
+
Fri Jun 20 01:40:21 2008 Nobuyoshi Nakada <nobu@r...>
* array.c (rb_ary_equal, rb_ary_eql, rb_ary_hash, rb_ary_cmp):
Index: ruby_1_8_6/version.h
===================================================================
--- ruby_1_8_6/version.h (revision 17459)
+++ ruby_1_8_6/version.h (revision 17460)
@@ -2,7 +2,7 @@
#define RUBY_RELEASE_DATE "2008-06-20"
#define RUBY_VERSION_CODE 186
#define RUBY_RELEASE_CODE 20080620
-#define RUBY_PATCHLEVEL 227
+#define RUBY_PATCHLEVEL 228
#define RUBY_VERSION_MAJOR 1
#define RUBY_VERSION_MINOR 8
Index: ruby_1_8_6/string.c
===================================================================
--- ruby_1_8_6/string.c (revision 17459)
+++ ruby_1_8_6/string.c (revision 17460)
@@ -452,22 +452,15 @@
*/
static VALUE
-rb_str_format(str, arg)
+rb_str_format_m(str, arg)
VALUE str, arg;
{
- VALUE *argv;
+ VALUE tmp = rb_check_array_type(arg);
- 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);
+ if (!NIL_P(tmp)) {
+ return rb_str_format(RARRAY_LEN(tmp), RARRAY_PTR(tmp), str);
}
-
- argv = ALLOCA_N(VALUE, 2);
- argv[0] = str;
- argv[1] = arg;
- return rb_f_sprintf(2, argv);
+ return rb_str_format(1, &arg, str);
}
static int
@@ -780,6 +773,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;
@@ -4657,7 +4653,7 @@
rb_define_method(rb_cString, "casecmp", rb_str_casecmp, 1);
rb_define_method(rb_cString, "+", rb_str_plus, 1);
rb_define_method(rb_cString, "*", rb_str_times, 1);
- rb_define_method(rb_cString, "%", rb_str_format, 1);
+ rb_define_method(rb_cString, "%", rb_str_format_m, 1);
rb_define_method(rb_cString, "[]", rb_str_aref_m, -1);
rb_define_method(rb_cString, "[]=", rb_str_aset_m, -1);
rb_define_method(rb_cString, "insert", rb_str_insert, 2);
Index: ruby_1_8_6/sprintf.c
===================================================================
--- ruby_1_8_6/sprintf.c (revision 17459)
+++ ruby_1_8_6/sprintf.c (revision 17460)
@@ -249,7 +249,15 @@
int argc;
VALUE *argv;
{
+ return rb_str_format(argc - 1, argv + 1, GETNTHARG(0));
+}
+
+VALUE
+rb_str_format(argc, argv, fmt)
+ int argc;
+ VALUE *argv;
VALUE fmt;
+{
const char *p, *end;
char *buf;
int blen, bsiz;
@@ -278,7 +286,8 @@
rb_raise(rb_eArgError, "flag after precision"); \
}
- fmt = GETNTHARG(0);
+ ++argc;
+ --argv;
if (OBJ_TAINTED(fmt)) tainted = 1;
StringValue(fmt);
fmt = rb_str_new4(fmt);
Index: ruby_1_8_7/intern.h
===================================================================
--- ruby_1_8_7/intern.h (revision 17459)
+++ ruby_1_8_7/intern.h (revision 17460)
@@ -418,6 +418,7 @@
void ruby_default_signal _((int));
/* sprintf.c */
VALUE rb_f_sprintf _((int, VALUE*));
+VALUE rb_str_format _((int, VALUE*, VALUE));
/* string.c */
VALUE rb_str_new _((const char*, long));
VALUE rb_str_new2 _((const char*));
Index: ruby_1_8_7/array.c
===================================================================
--- ruby_1_8_7/array.c (revision 17459)
+++ ruby_1_8_7/array.c (revision 17460)
@@ -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)
@@ -120,7 +121,7 @@
if (len < 0) {
rb_raise(rb_eArgError, "negative array size (or size too big)");
}
- if (len > 0 && len * sizeof(VALUE) <= len) {
+ if (len > ARY_MAX_SIZE) {
rb_raise(rb_eArgError, "array size too big");
}
if (len == 0) len++;
@@ -314,7 +315,7 @@
if (len < 0) {
rb_raise(rb_eArgError, "negative array size");
}
- if (len > 0 && len * (long)sizeof(VALUE) <= len) {
+ if (len > ARY_MAX_SIZE) {
rb_raise(rb_eArgError, "array size too big");
}
if (len > RARRAY(ary)->aux.capa) {
@@ -379,6 +380,9 @@
idx - RARRAY(ary)->len);
}
}
+ else if (idx >= ARY_MAX_SIZE) {
+ rb_raise(rb_eIndexError, "index %ld too big", idx);
+ }
rb_ary_modify(ary);
if (idx >= RARRAY(ary)->aux.capa) {
@@ -387,10 +391,10 @@
if (new_capa < ARY_DEFAULT_SIZE) {
new_capa = ARY_DEFAULT_SIZE;
}
+ else if (new_capa >= ARY_MAX_SIZE - idx) {
+ new_capa = (ARY_MAX_SIZE - idx) / 2;
+ }
new_capa += idx;
- if (new_capa * (long)sizeof(VALUE) <= new_capa) {
- rb_raise(rb_eArgError, "index too big");
- }
REALLOC_N(RARRAY(ary)->ptr, VALUE, new_capa);
RARRAY(ary)->aux.capa = new_capa;
}
@@ -1091,6 +1095,9 @@
if (beg >= RARRAY(ary)->len) {
len = beg + rlen;
+ if (len < 0 || len > ARY_MAX_SIZE) {
+ 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;
@@ -2522,7 +2529,7 @@
if (len < 0) {
rb_raise(rb_eArgError, "negative argument");
}
- if (LONG_MAX/len < RARRAY(ary)->len) {
+ if (ARY_MAX_SIZE/len < RARRAY(ary)->len) {
rb_raise(rb_eArgError, "argument too big");
}
len *= RARRAY(ary)->len;
Index: ruby_1_8_7/ChangeLog
===================================================================
--- ruby_1_8_7/ChangeLog (revision 17459)
+++ ruby_1_8_7/ChangeLog (revision 17460)
@@ -1,3 +1,18 @@
+Wed Jun 18 22:24:46 2008 URABE Shyouhei <shyouhei@r...>
+
+ * array.c (ary_new, rb_ary_initialize, rb_ary_store,
+ rb_ary_aplice, rb_ary_times): integer overflows should be
+ checked. based on patches from Drew Yao <ayao at apple.com>
+ fixed CVE-2008-2726
+
+ * string.c (rb_str_buf_append): fixed unsafe use of alloca,
+ which led memory corruption. based on a patch from Drew Yao
+ <ayao at apple.com> fixed CVE-2008-2726
+
+ * sprintf.c (rb_str_format): backported from trunk.
+
+ * intern.h: ditto.
+
Tue Jun 17 15:09:46 2008 Nobuyoshi Nakada <nobu@r...>
* file.c (file_expand_path): no need to expand root path which has no
Index: ruby_1_8_7/version.h
===================================================================
--- ruby_1_8_7/version.h (revision 17459)
+++ ruby_1_8_7/version.h (revision 17460)
@@ -1,15 +1,15 @@
#define RUBY_VERSION "1.8.7"
-#define RUBY_RELEASE_DATE "2008-06-17"
+#define RUBY_RELEASE_DATE "2008-06-20"
#define RUBY_VERSION_CODE 187
-#define RUBY_RELEASE_CODE 20080617
-#define RUBY_PATCHLEVEL 19
+#define RUBY_RELEASE_CODE 20080620
+#define RUBY_PATCHLEVEL 20
#define RUBY_VERSION_MAJOR 1
#define RUBY_VERSION_MINOR 8
#define RUBY_VERSION_TEENY 7
#define RUBY_RELEASE_YEAR 2008
#define RUBY_RELEASE_MONTH 6
-#define RUBY_RELEASE_DAY 17
+#define RUBY_RELEASE_DAY 20
#ifdef RUBY_EXTERN
RUBY_EXTERN const char ruby_version[];
Index: ruby_1_8_7/string.c
===================================================================
--- ruby_1_8_7/string.c (revision 17459)
+++ ruby_1_8_7/string.c (revision 17460)
@@ -459,22 +459,15 @@
*/
static VALUE
-rb_str_format(str, arg)
+rb_str_format_m(str, arg)
VALUE str, arg;
{
- VALUE *argv;
+ VALUE tmp = rb_check_array_type(arg);
- 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);
+ if (!NIL_P(tmp)) {
+ return rb_str_format(RARRAY_LEN(tmp), RARRAY_PTR(tmp), str);
}
-
- argv = ALLOCA_N(VALUE, 2);
- argv[0] = str;
- argv[1] = arg;
- return rb_f_sprintf(2, argv);
+ return rb_str_format(1, &arg, str);
}
static int
@@ -795,6 +788,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;
@@ -4923,7 +4919,7 @@
rb_define_method(rb_cString, "casecmp", rb_str_casecmp, 1);
rb_define_method(rb_cString, "+", rb_str_plus, 1);
rb_define_method(rb_cString, "*", rb_str_times, 1);
- rb_define_method(rb_cString, "%", rb_str_format, 1);
+ rb_define_method(rb_cString, "%", rb_str_format_m, 1);
rb_define_method(rb_cString, "[]", rb_str_aref_m, -1);
rb_define_method(rb_cString, "[]=", rb_str_aset_m, -1);
rb_define_method(rb_cString, "insert", rb_str_insert, 2);
Index: ruby_1_8_7/sprintf.c
===================================================================
--- ruby_1_8_7/sprintf.c (revision 17459)
+++ ruby_1_8_7/sprintf.c (revision 17460)
@@ -249,7 +249,15 @@
int argc;
VALUE *argv;
{
+ return rb_str_format(argc - 1, argv + 1, GETNTHARG(0));
+}
+
+VALUE
+rb_str_format(argc, argv, fmt)
+ int argc;
+ VALUE *argv;
VALUE fmt;
+{
const char *p, *end;
char *buf;
int blen, bsiz;
@@ -278,7 +286,8 @@
rb_raise(rb_eArgError, "flag after precision"); \
}
- fmt = GETNTHARG(0);
+ ++argc;
+ --argv;
if (OBJ_TAINTED(fmt)) tainted = 1;
StringValue(fmt);
fmt = rb_str_new4(fmt);
--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/