[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]