Преглед изворни кода

Security Fixes (CVE-2006-3694)

Ralf S. Engelschall пре 19 година
родитељ
комит
9b648f8614
2 измењених фајлова са 94 додато и 1 уклоњено
  1. 93 0
      ruby/ruby.patch
  2. 1 1
      ruby/ruby.spec

+ 93 - 0
ruby/ruby.patch

@@ -22,3 +22,96 @@ Index: ext/dbm/extconf.rb
      db_check(dblib) and break
    end
  end
+
+-----------------------------------------------------------------------------
+
+Security Fixes (CVE-2006-3694)
+
+- eval.c, alias(): preserve current safe level
+  http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/ruby/eval.c?cvsroot=src&r1=1.616.2.166&r2=1.616.2.167
+  (only relevant part)
+- re.c: do not modify untainted levels in safe levels > 3
+  http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/ruby/re.c?cvsroot=src&r1=1.114.2.17&r2=1.114.2.18
+  (only last hunk is relevant)
+- dir.c: should not close untainted dir stream
+  http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/ruby/dir.c?cvsroot=src&r1=1.92.2.32&r2=1.92.2.33
+
+Index: dir.c
+--- dir.c.orig	2005-09-14 15:40:58 +0200
++++ dir.c	2006-07-28 10:47:57 +0200
+@@ -325,7 +325,17 @@
+     rb_raise(rb_eIOError, "closed directory");
+ }
+ 
++static void
++dir_check(dir)
++    VALUE dir;
++{
++    if (!OBJ_TAINTED(dir) && rb_safe_level() >= 4)
++	rb_raise(rb_eSecurityError, "Insecure: operation on untainted Dir");
++    rb_check_frozen(dir);
++}
++
+ #define GetDIR(obj, dirp) do {\
++    dir_check(dir);\
+     Data_Get_Struct(obj, struct dir_data, dirp);\
+     if (dirp->dir == NULL) dir_closed();\
+ } while (0)
+@@ -536,6 +546,9 @@
+ {
+     struct dir_data *dirp;
+ 
++    if (rb_safe_level() >= 4 && !OBJ_TAINTED(dir)) {
++	rb_raise(rb_eSecurityError, "Insecure: can't close");
++    }
+     GetDIR(dir, dirp);
+     closedir(dirp->dir);
+     dirp->dir = NULL;
+Index: eval.c
+--- eval.c.orig	2005-12-20 14:41:47 +0100
++++ eval.c	2006-07-28 10:47:57 +0200
+@@ -2097,7 +2097,8 @@
+ 	}
+     }
+     st_insert(RCLASS(klass)->m_tbl, name,
+-      (st_data_t)NEW_METHOD(NEW_FBODY(body, def, origin), orig->nd_noex));
++	      (st_data_t)NEW_METHOD(NEW_FBODY(body, def, origin),
++				    NOEX_WITH_SAFE(orig->nd_noex)));
+     if (singleton) {
+ 	rb_funcall(singleton, singleton_added, 1, ID2SYM(name));
+     }
+@@ -5638,6 +5639,11 @@
+     TMP_PROTECT;
+     volatile int safe = -1;
+ 
++    if (NOEX_SAFE(flags) > ruby_safe_level &&
++	!(flags&NOEX_TAINTED) && ruby_safe_level == 0 && NOEX_SAFE(flags) > 2) {
++	rb_raise(rb_eSecurityError, "calling insecure method: %s",
++		 rb_id2name(id));
++    }
+     switch (ruby_iter->iter) {
+       case ITER_PRE:
+       case ITER_PAS:
+@@ -5742,10 +5748,6 @@
+ 	    b2 = body = body->nd_next;
+ 
+ 	    if (NOEX_SAFE(flags) > ruby_safe_level) {
+-		if (!(flags&NOEX_TAINTED) && ruby_safe_level == 0 && NOEX_SAFE(flags) > 2) {
+-		    rb_raise(rb_eSecurityError, "calling insecure method: %s",
+-			     rb_id2name(id));
+-		}
+ 		safe = ruby_safe_level;
+ 		ruby_safe_level = NOEX_SAFE(flags);
+ 	    }
+Index: re.c
+--- re.c.orig	2005-12-13 04:27:51 +0100
++++ re.c	2006-07-28 10:47:57 +0200
+@@ -1332,6 +1332,8 @@
+ {
+     struct RRegexp *re = RREGEXP(obj);
+ 
++    if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4)
++	rb_raise(rb_eSecurityError, "Insecure: can't modify regexp");
+     if (re->ptr) re_free_pattern(re->ptr);
+     if (re->str) free(re->str);
+     re->ptr = 0;

+ 1 - 1
ruby/ruby.spec

@@ -33,7 +33,7 @@ Class:        BASE
 Group:        Language
 License:      GPL
 Version:      1.8.4
-Release:      20051225
+Release:      20060728
 
 #   list of sources
 Source0:      ftp://ftp.ruby-lang.org/pub/ruby/ruby-%{version}.tar.gz