$OpenBSD: patch-array_c,v 1.1 2008/07/21 09:40:42 bernd Exp $ Fixes multiple security vulnerabilities. http://secunia.com/advisories/29794/ Patch against ruby-1.8.6p114 from: http://blog.phusion.nl/assets/r8ee-security-patch-20080623-2.txt and https://launchpad.net/ubuntu/+source/ruby1.8 1.8.6-p229 and 1.8.7-p21 will break rails applications. --- array.c.orig Fri Sep 7 09:46:40 2007 +++ array.c Tue Jul 1 20:47:08 2008 @@ -20,6 +20,7 @@ VALUE rb_cArray; 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 @@ ary_new(klass, len) 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 @@ rb_ary_initialize(argc, argv, ary) 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) { @@ -359,6 +360,10 @@ rb_ary_store(ary, idx, val) } } + if (idx >= ARY_MAX_SIZE) { + rb_raise(rb_eIndexError, "index %ld too big", idx); + } + rb_ary_modify(ary); if (idx >= RARRAY(ary)->aux.capa) { long new_capa = RARRAY(ary)->aux.capa / 2; @@ -366,6 +371,9 @@ rb_ary_store(ary, idx, val) if (new_capa < ARY_DEFAULT_SIZE) { new_capa = ARY_DEFAULT_SIZE; } + 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"); @@ -975,6 +983,9 @@ rb_ary_splice(ary, beg, len, rpl) rb_ary_modify(ary); if (beg >= RARRAY(ary)->len) { + if (beg > ARY_MAX_SIZE - rlen) { + rb_raise(rb_eIndexError, "index %ld too big", beg); + } len = beg + rlen; if (len >= RARRAY(ary)->aux.capa) { REALLOC_N(RARRAY(ary)->ptr, VALUE, len); @@ -2378,7 +2389,7 @@ rb_ary_times(ary, times) 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;