From 095f1324ea2d6b52172301cc62c6a0dac7f5e1c8 Mon Sep 17 00:00:00 2001 From: Mamoru Tasaka Date: Dec 06 2009 19:55:53 +0000 Subject: - Patch for bigdecimal DOS issue (CVE-2009-1904, bug 504958) --- diff --git a/ruby-1.8.6-CVE-2009-1904-bigdecimal.patch b/ruby-1.8.6-CVE-2009-1904-bigdecimal.patch new file mode 100644 index 0000000..b440df0 --- /dev/null +++ b/ruby-1.8.6-CVE-2009-1904-bigdecimal.patch @@ -0,0 +1,221 @@ +--- branches/ruby_1_8_6/ext/bigdecimal/bigdecimal.c 2009/02/11 14:36:59 22241 ++++ branches/ruby_1_8_6/ext/bigdecimal/bigdecimal.c 2009/06/08 19:01:00 23652 +@@ -306,17 +306,22 @@ + BigDecimal_dump(int argc, VALUE *argv, VALUE self) + { + ENTER(5); +- char sz[50]; + Real *vp; + char *psz; + VALUE dummy; ++ volatile VALUE dump; ++ + rb_scan_args(argc, argv, "01", &dummy); + GUARD_OBJ(vp,GetVpValue(self,1)); +- sprintf(sz,"%lu:",VpMaxPrec(vp)*VpBaseFig()); +- psz = ALLOCA_N(char,(unsigned int)VpNumOfChars(vp,"E")+strlen(sz)); +- sprintf(psz,"%s",sz); ++ ++ dump = rb_str_new(0,VpNumOfChars(vp,"E")+50); ++ psz = RSTRING_PTR(dump); ++ sprintf(psz,"%lu:",VpMaxPrec(vp)*VpBaseFig()); ++ + VpToString(vp, psz+strlen(psz), 0, 0); +- return rb_str_new2(psz); ++ ++ rb_str_resize(dump, strlen(psz)); ++ return dump; + } + + /* +@@ -520,6 +525,7 @@ + ENTER(5); + int e,n,i,nf; + U_LONG v,b,j; ++ volatile VALUE str; + char *psz,*pch; + Real *p; + +@@ -534,7 +540,7 @@ + return Qnil; + } else if(VpIsNegInf(p)) { + VpException(VP_EXCEPTION_INFINITY,"Computation results to '-Infinity'",0); +- return Qnil; ++ return Qnil; + } + + e = VpExponent10(p); +@@ -544,10 +550,12 @@ + e = VpGetSign(p)*p->frac[0]; + return INT2FIX(e); + } +- psz = ALLOCA_N(char,(unsigned int)(e+nf+2)); + ++ str = rb_str_new(0, e+nf+2); ++ psz = RSTRING_PTR(str); + n = (e+nf-1)/nf; + pch = psz; ++ + if(VpGetSign(p)<0) *pch++ = '-'; + for(i=0;i DBL_MAX_10_EXP) goto erange; ++ str = rb_str_new(0, VpNumOfChars(p,"E")); ++ buf = RSTRING_PTR(str); ++ + VpToString(p, buf, 0, 0); + errno = 0; + d = strtod(buf, 0); + if(errno == ERANGE) { ++ erange: + VpException(VP_EXCEPTION_OVERFLOW,"BigDecimal to Float conversion",0); + if(d>0.0) return rb_float_new(DBL_MAX); + else return rb_float_new(-DBL_MAX); +@@ -1491,6 +1505,7 @@ + int fmt=0; /* 0:E format */ + int fPlus=0; /* =0:default,=1: set ' ' before digits ,set '+' before digits. */ + Real *vp; ++ volatile VALUE str; + char *psz; + char ch; + U_LONG nc; +@@ -1527,14 +1542,17 @@ + } + if(mc>0) nc += (nc + mc - 1) / mc + 1; + +- psz = ALLOCA_N(char,(unsigned int)nc); ++ str = rb_str_new(0, nc); ++ psz = RSTRING_PTR(str); + + if(fmt) { + VpToFString(vp, psz, mc, fPlus); + } else { + VpToString (vp, psz, mc, fPlus); + } +- return rb_str_new2(psz); ++ ++ rb_str_resize(str, strlen(psz)); ++ return str; + } + + /* Splits a BigDecimal number into four parts, returned as an array of values. +@@ -1566,24 +1584,29 @@ + { + ENTER(5); + Real *vp; +- VALUE obj,obj1; ++ VALUE obj,str; + S_LONG e; + S_LONG s; + char *psz1; + + GUARD_OBJ(vp,GetVpValue(self,1)); +- psz1 = ALLOCA_N(char,(unsigned int)VpNumOfChars(vp,"E")); ++ str = rb_str_new(0, VpNumOfChars(vp,"E")); ++ psz1 = RSTRING_PTR(str); ++ + VpSzMantissa(vp,psz1); + s = 1; + if(psz1[0]=='-') { +- s = -1; ++psz1; ++ int len = strlen(psz1+1); ++ memmove(psz1, psz1+1, len); ++ psz1[len] = '\0'; ++ s = -1; + } + if(psz1[0]=='N') s=0; /* NaN */ + e = VpExponent10(vp); +- obj1 = rb_str_new2(psz1); + obj = rb_ary_new2(4); + rb_ary_push(obj, INT2FIX(s)); +- rb_ary_push(obj, obj1); ++ rb_ary_push(obj, str); ++ rb_str_resize(str, strlen(psz1)); + rb_ary_push(obj, INT2FIX(10)); + rb_ary_push(obj, INT2NUM(e)); + return obj; +@@ -1616,20 +1639,23 @@ + { + ENTER(5); + Real *vp; +- VALUE obj; ++ volatile VALUE obj; + unsigned int nc; +- char *psz1; +- char *pszAll; ++ char *psz, *tmp; + + GUARD_OBJ(vp,GetVpValue(self,1)); + nc = VpNumOfChars(vp,"E"); + nc +=(nc + 9) / 10; + +- psz1 = ALLOCA_N(char,nc); +- pszAll = ALLOCA_N(char,nc+256); +- VpToString(vp, psz1, 10, 0); +- sprintf(pszAll,"#",self,psz1,VpPrec(vp)*VpBaseFig(),VpMaxPrec(vp)*VpBaseFig()); +- obj = rb_str_new2(pszAll); ++ obj = rb_str_new(0, nc+256); ++ psz = RSTRING_PTR(obj); ++ sprintf(psz,"#",VpPrec(vp)*VpBaseFig(),VpMaxPrec(vp)*VpBaseFig()); ++ rb_str_resize(obj, strlen(psz)); ++ + return obj; + } + +@@ -2482,6 +2508,7 @@ + int sign=1; + Real *vp = NULL; + U_LONG mf = VpGetPrecLimit(); ++ volatile VALUE buf; + + mx = (mx + BASE_FIG - 1) / BASE_FIG + 1; /* Determine allocation unit. */ + if(szVal) { +@@ -2509,7 +2536,9 @@ + + /* Skip all '_' after digit: 2006-6-30 */ + ni = 0; +- psz = ALLOCA_N(char,strlen(szVal)+1); ++ buf = rb_str_new(0,strlen(szVal)+1); ++ psz = RSTRING_PTR(buf); ++ + i = 0; + ipn = 0; + while((psz[i]=szVal[ipn])!=0) { +@@ -3601,7 +3630,7 @@ + nc += fprintf(fp, "0."); + n = a->Prec; + for(i=0;i < n;++i) { +- m = BASE1; ++ m = BASE1; + e = a->frac[i]; + while(m) { + nn = e / m; +@@ -3778,6 +3807,7 @@ + return 0; + } + ++ + VP_EXPORT void + VpToString(Real *a,char *psz,int fFmt,int fPlus) + /* fPlus =0:default, =1: set ' ' before digits , =2:set '+' before digits. */ diff --git a/ruby.spec b/ruby.spec index c0e342f..bbf966e 100644 --- a/ruby.spec +++ b/ruby.spec @@ -16,7 +16,7 @@ Name: ruby Version: %{rubyver}%{?dotpatchlevel} -Release: 1%{?dist} +Release: 2%{?dist} License: Ruby or GPLv2 URL: http://www.ruby-lang.org/ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -44,6 +44,7 @@ Patch26: ruby-1.8.6-rexml-CVE-2008-3790.patch Patch27: ruby-1.8.6-p287-CVE-2008-5189.patch Patch28: ruby-1.8.6-p287-remove-ssl-rand-range.patch Patch29: ruby-always-use-i386.patch +Patch30: ruby-1.8.6-CVE-2009-1904-bigdecimal.patch Summary: An interpreter of object-oriented scripting language Group: Development/Languages @@ -173,6 +174,7 @@ pushd %{name}-%{arcver} %patch27 -p0 %patch28 -p1 %patch29 -p1 +%patch30 -p2 popd %build @@ -531,6 +533,9 @@ rm -rf $RPM_BUILD_ROOT %{_emacs_sitestartdir}/ruby-mode-init.el %changelog +* Mon Dec 7 2009 Mamoru Tasaka - 1.8.6.386-2 +- Patch for bigdecimal DOS issue (CVE-2009-1904, bug 504958) + * Sun May 31 2009 Jeroen van Meeuwen - 1.8.6.368-1 - New upstream release (p368)