ruby-changes:14217
From: yugui <ko1@a...>
Date: Mon, 7 Dec 2009 13:11:50 +0900 (JST)
Subject: [ruby-changes:14217] Ruby:r26038 (trunk, ruby_1_9_1): * string.c (rb_str_justify): CVE-2009-4124.
yugui 2009-12-07 13:11:26 +0900 (Mon, 07 Dec 2009) New Revision: 26038 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=26038 Log: * string.c (rb_str_justify): CVE-2009-4124. Fixes a bug reported by Emmanouel Kellinis <Emmanouel.Kellinis AT kpmg.co.uk>, KPMG London; Patch by nobu. Modified files: branches/ruby_1_9_1/ChangeLog branches/ruby_1_9_1/string.c trunk/ChangeLog trunk/string.c Index: ChangeLog =================================================================== --- ChangeLog (revision 26037) +++ ChangeLog (revision 26038) @@ -1,3 +1,10 @@ +Mon Dec 7 13:05:59 2009 Yuki Sonoda (Yugui) <yugui@y...> + + * string.c (rb_str_justify): CVE-2009-4124. + Fixes a bug reported by + Emmanouel Kellinis <Emmanouel.Kellinis AT kpmg.co.uk>, KPMG London; + Patch by nobu. + Sun Dec 6 23:50:46 2009 NARUSE, Yui <naruse@r...> * strftime.c: %l should be 1..12 instead of 0..12 [ruby-core:27072] Index: string.c =================================================================== --- string.c (revision 26037) +++ string.c (revision 26038) @@ -6593,7 +6593,7 @@ VALUE res; char *p; const char *f = " "; - long n, llen, rlen; + long n, size, llen, rlen, llen2 = 0, rlen2 = 0; volatile VALUE pad; int singlebyte = 1, cr; @@ -6617,44 +6617,49 @@ llen = (jflag == 'l') ? 0 : ((jflag == 'r') ? n : n/2); rlen = n - llen; cr = ENC_CODERANGE(str); - res = rb_str_new5(str, 0, RSTRING_LEN(str)+n*flen/fclen+2); + if (flen > 1) { + llen2 = str_offset(f, f + flen, llen % fclen, enc, singlebyte); + rlen2 = str_offset(f, f + flen, rlen % fclen, enc, singlebyte); + } + size = RSTRING_LEN(str); + if ((len = llen / fclen + rlen / fclen) >= LONG_MAX / flen || + (len *= flen) >= LONG_MAX - llen2 - rlen2 || + (len += llen2 + rlen2) >= LONG_MAX - size) { + rb_raise(rb_eArgError, "argument too big"); + } + len += size; + res = rb_str_new5(str, 0, len); p = RSTRING_PTR(res); - while (llen) { - if (flen <= 1) { - *p++ = *f; - llen--; - } - else if (llen > fclen) { + if (flen <= 1) { + memset(p, *f, llen); + p += llen; + } + else { + while (llen > fclen) { memcpy(p,f,flen); p += flen; llen -= fclen; } - else { - char *fp = str_nth(f, f+flen, llen, enc, singlebyte); - n = fp - f; - memcpy(p,f,n); - p+=n; - break; + if (llen > 0) { + memcpy(p, f, llen2); + p += llen2; } } - memcpy(p, RSTRING_PTR(str), RSTRING_LEN(str)); - p+=RSTRING_LEN(str); - while (rlen) { - if (flen <= 1) { - *p++ = *f; - rlen--; - } - else if (rlen > fclen) { + memcpy(p, RSTRING_PTR(str), size); + p += size; + if (flen <= 1) { + memset(p, *f, rlen); + p += rlen; + } + else { + while (rlen > fclen) { memcpy(p,f,flen); p += flen; rlen -= fclen; } - else { - char *fp = str_nth(f, f+flen, rlen, enc, singlebyte); - n = fp - f; - memcpy(p,f,n); - p+=n; - break; + if (rlen > 0) { + memcpy(p, f, rlen2); + p += rlen2; } } *p = '\0'; Index: ruby_1_9_1/ChangeLog =================================================================== --- ruby_1_9_1/ChangeLog (revision 26037) +++ ruby_1_9_1/ChangeLog (revision 26038) @@ -1,3 +1,10 @@ +Sat Dec 5 18:52:56 2009 Yuki Sonoda (Yugui) <yugui@y...> + + * string.c (rb_str_justify): CVE-2009-4124. + Fixes a bug reported by + Emmanouel Kellinis <Emmanouel.Kellinis AT kpmg.co.uk>, KPMG London; + Patch by nobu. + Sat Dec 5 14:29:49 2009 Yuki Sonoda (Yugui) <yugui@y...> * lib/irb/extend-command.rb (IRB::ExtendCommandBundle::def_extend_command): Index: ruby_1_9_1/string.c =================================================================== --- ruby_1_9_1/string.c (revision 26037) +++ ruby_1_9_1/string.c (revision 26038) @@ -6473,7 +6473,7 @@ VALUE res; char *p; const char *f = " "; - long n, llen, rlen; + long n, size, llen, rlen, llen2 = 0, rlen2 = 0; volatile VALUE pad; int singlebyte = 1, cr; @@ -6497,44 +6497,49 @@ llen = (jflag == 'l') ? 0 : ((jflag == 'r') ? n : n/2); rlen = n - llen; cr = ENC_CODERANGE(str); - res = rb_str_new5(str, 0, RSTRING_LEN(str)+n*flen/fclen+2); + if (flen > 1) { + llen2 = str_offset(f, f + flen, llen % fclen, enc, singlebyte); + rlen2 = str_offset(f, f + flen, rlen % fclen, enc, singlebyte); + } + size = RSTRING_LEN(str); + if ((len = llen / fclen + rlen / fclen) >= LONG_MAX / flen || + (len *= flen) >= LONG_MAX - llen2 - rlen2 || + (len += llen2 + rlen2) >= LONG_MAX - size) { + rb_raise(rb_eArgError, "argument too big"); + } + len += size; + res = rb_str_new5(str, 0, len); p = RSTRING_PTR(res); - while (llen) { - if (flen <= 1) { - *p++ = *f; - llen--; - } - else if (llen > fclen) { + if (flen <= 1) { + memset(p, *f, llen); + p += llen; + } + else { + while (llen > fclen) { memcpy(p,f,flen); p += flen; llen -= fclen; } - else { - char *fp = str_nth(f, f+flen, llen, enc, singlebyte); - n = fp - f; - memcpy(p,f,n); - p+=n; - break; + if (llen > 0) { + memcpy(p, f, llen2); + p += llen2; } } - memcpy(p, RSTRING_PTR(str), RSTRING_LEN(str)); - p+=RSTRING_LEN(str); - while (rlen) { - if (flen <= 1) { - *p++ = *f; - rlen--; - } - else if (rlen > fclen) { + memcpy(p, RSTRING_PTR(str), size); + p += size; + if (flen <= 1) { + memset(p, *f, rlen); + p += rlen; + } + else { + while (rlen > fclen) { memcpy(p,f,flen); p += flen; rlen -= fclen; } - else { - char *fp = str_nth(f, f+flen, rlen, enc, singlebyte); - n = fp - f; - memcpy(p,f,n); - p+=n; - break; + if (rlen > 0) { + memcpy(p, f, rlen2); + p += rlen2; } } *p = '\0'; -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/