summaryrefslogtreecommitdiff
path: root/lang
diff options
context:
space:
mode:
authortaca <taca@pkgsrc.org>2005-09-21 14:03:22 +0000
committertaca <taca@pkgsrc.org>2005-09-21 14:03:22 +0000
commitb2a41fdcae3c5bec50cab8b2aab09ec65d725fda (patch)
treebc5cd7b7e7566e3273e22193fa0dba88d422a306 /lang
parentcd242845b844d90a352fe7d1b18993987ee28ee9 (diff)
downloadpkgsrc-b2a41fdcae3c5bec50cab8b2aab09ec65d725fda.tar.gz
Add a patch for fix the security problem which allows an arbitrary code
to run bypassing the safe level check. The patch was provided by Yukihiro Matsumoto on ruby-dev mailing list. Bump PKGREVISION.
Diffstat (limited to 'lang')
-rw-r--r--lang/ruby18-base/Makefile4
-rw-r--r--lang/ruby18-base/distinfo3
-rw-r--r--lang/ruby18-base/patches/patch-ad158
3 files changed, 162 insertions, 3 deletions
diff --git a/lang/ruby18-base/Makefile b/lang/ruby18-base/Makefile
index e1cee2cf9e1..02341468823 100644
--- a/lang/ruby18-base/Makefile
+++ b/lang/ruby18-base/Makefile
@@ -1,9 +1,9 @@
-# $NetBSD: Makefile,v 1.7 2005/09/18 13:38:50 taca Exp $
+# $NetBSD: Makefile,v 1.8 2005/09/21 14:03:22 taca Exp $
#
DISTNAME= ${RUBY_DISTNAME}
PKGNAME= ${RUBY_PKGPREFIX}-base-${RUBY_VERSION}
-PKGREVISION= 3
+PKGREVISION= 4
CATEGORIES= lang ruby
MASTER_SITES= ${MASTER_SITE_RUBY}
diff --git a/lang/ruby18-base/distinfo b/lang/ruby18-base/distinfo
index 08badca169b..8f1ebf5071f 100644
--- a/lang/ruby18-base/distinfo
+++ b/lang/ruby18-base/distinfo
@@ -1,4 +1,4 @@
-$NetBSD: distinfo,v 1.4 2005/09/19 15:19:13 taca Exp $
+$NetBSD: distinfo,v 1.5 2005/09/21 14:03:22 taca Exp $
SHA1 (ruby/ruby-1.8.2.tar.gz) = 409a917d3a0aba41f45bd053b767c85b2bc35ffa
RMD160 (ruby/ruby-1.8.2.tar.gz) = fc4dcdc2dda9bfbcf8ca19ca090aa55a18ea06a4
@@ -6,6 +6,7 @@ Size (ruby/ruby-1.8.2.tar.gz) = 3627349 bytes
SHA1 (patch-aa) = b0c96d7f10ff48245f97d7561e33ced4c4fed69d
SHA1 (patch-ab) = eeb4048b99784392b7a09a904748e8ff23205580
SHA1 (patch-ac) = 8a60292e7fd312df639404fc015c4f3eeef49137
+SHA1 (patch-ad) = 79661e47e0a489cf8f2ad81a9c816ce23d88902b
SHA1 (patch-al) = a62c126e971a0d45b00e873802bc9ee67786c47e
SHA1 (patch-am) = fe000acf64e20245058c83319030e11606e75004
SHA1 (patch-an) = aa56ea179d9b7bf6ece22b4d8bba0c9137a0e342
diff --git a/lang/ruby18-base/patches/patch-ad b/lang/ruby18-base/patches/patch-ad
new file mode 100644
index 00000000000..1370f447409
--- /dev/null
+++ b/lang/ruby18-base/patches/patch-ad
@@ -0,0 +1,158 @@
+$NetBSD: patch-ad,v 1.1 2005/09/21 14:03:22 taca Exp $
+
+--- eval.c.orig 2004-12-18 11:07:29.000000000 +0900
++++ eval.c
+@@ -252,6 +252,11 @@ struct cache_entry { /* method hash tab
+ static struct cache_entry cache[CACHE_SIZE];
+ static int ruby_running = 0;
+
++#define NOEX_TAINTED 8
++#define NOEX_SAFE(n) ((n) >> 4)
++#define NOEX_WITH(n, v) ((n) | (v) << 4)
++#define NOEX_WITH_SAFE(n) NOEX_WITH(n, ruby_safe_level)
++
+ void
+ rb_clear_cache()
+ {
+@@ -344,7 +349,7 @@ rb_add_method(klass, mid, node, noex)
+ }
+ if (OBJ_FROZEN(klass)) rb_error_frozen("class/module");
+ rb_clear_cache_by_id(mid);
+- body = NEW_METHOD(node, noex);
++ body = NEW_METHOD(node, NOEX_WITH_SAFE(noex));
+ st_insert(RCLASS(klass)->m_tbl, mid, (st_data_t)body);
+ if (node && mid != ID_ALLOCATOR && ruby_running) {
+ if (FL_TEST(klass, FL_SINGLETON)) {
+@@ -5456,20 +5461,21 @@ call_cfunc(func, recv, len, argc, argv)
+ }
+
+ static VALUE
+-rb_call0(klass, recv, id, oid, argc, argv, body, nosuper)
++rb_call0(klass, recv, id, oid, argc, argv, body, flags)
+ VALUE klass, recv;
+ ID id;
+ ID oid;
+ int argc; /* OK */
+ VALUE *argv; /* OK */
+ NODE *body; /* OK */
+- int nosuper;
++ int flags;
+ {
+ NODE *b2; /* OK */
+ volatile VALUE result = Qnil;
+ int itr;
+ static int tick;
+ TMP_PROTECT;
++ volatile int safe = -1;
+
+ switch (ruby_iter->iter) {
+ case ITER_PRE:
+@@ -5491,7 +5497,7 @@ rb_call0(klass, recv, id, oid, argc, arg
+
+ ruby_frame->last_func = id;
+ ruby_frame->orig_func = oid;
+- ruby_frame->last_class = nosuper?0:klass;
++ ruby_frame->last_class = (flags & NOEX_UNDEF)?0:klass;
+ ruby_frame->self = recv;
+ ruby_frame->argc = argc;
+ ruby_frame->argv = argv;
+@@ -5553,7 +5559,6 @@ rb_call0(klass, recv, id, oid, argc, arg
+ NODE *saved_cref = 0;
+
+ PUSH_SCOPE();
+-
+ if (body->nd_rval) {
+ saved_cref = ruby_cref;
+ ruby_cref = (NODE*)body->nd_rval;
+@@ -5572,9 +5577,16 @@ rb_call0(klass, recv, id, oid, argc, arg
+ }
+ 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);
++ }
+ PUSH_VARS();
+ PUSH_TAG(PROT_FUNC);
+-
+ if ((state = EXEC_TAG()) == 0) {
+ NODE *node = 0;
+ int i;
+@@ -5653,6 +5665,7 @@ rb_call0(klass, recv, id, oid, argc, arg
+ result = prot_tag->retval;
+ state = 0;
+ }
++ if (safe >= 0) ruby_safe_level = safe;
+ POP_TAG();
+ POP_VARS();
+ POP_CLASS();
+@@ -5740,7 +5753,7 @@ rb_call(klass, recv, mid, argc, argv, sc
+ }
+ }
+
+- return rb_call0(klass, recv, mid, id, argc, argv, body, noex & NOEX_NOSUPER);
++ return rb_call0(klass, recv, mid, id, argc, argv, body, noex);
+ }
+
+ VALUE
+@@ -8530,6 +8543,7 @@ struct METHOD {
+ VALUE klass, rklass;
+ VALUE recv;
+ ID id, oid;
++ int safe_level;
+ NODE *body;
+ };
+
+@@ -8577,6 +8591,7 @@ mnew(klass, obj, id, mklass)
+ data->body = body;
+ data->rklass = rklass;
+ data->oid = oid;
++ data->safe_level = NOEX_WITH_SAFE(0);
+ OBJ_INFECT(method, klass);
+
+ return method;
+@@ -8661,6 +8676,7 @@ method_unbind(obj)
+ data->body = orig->body;
+ data->rklass = orig->rklass;
+ data->oid = orig->oid;
++ data->safe_level = NOEX_WITH_SAFE(0);
+ OBJ_INFECT(method, obj);
+
+ return method;
+@@ -8782,26 +8798,21 @@ method_call(argc, argv, method)
+ {
+ VALUE result = Qnil; /* OK */
+ struct METHOD *data;
+- int state;
+- volatile int safe = -1;
++ int safe;
+
+ Data_Get_Struct(method, struct METHOD, data);
+ if (data->recv == Qundef) {
+ rb_raise(rb_eTypeError, "you cannot call unbound method; bind first");
+ }
+- PUSH_ITER(rb_block_given_p()?ITER_PRE:ITER_NOT);
+- PUSH_TAG(PROT_NONE);
+ if (OBJ_TAINTED(method)) {
+- safe = ruby_safe_level;
+- if (ruby_safe_level < 4) ruby_safe_level = 4;
++ safe = NOEX_WITH(data->safe_level, 4)|NOEX_TAINTED;
+ }
+- if ((state = EXEC_TAG()) == 0) {
+- result = rb_call0(data->klass,data->recv,data->id,data->oid,argc,argv,data->body,0);
++ else {
++ safe = data->safe_level;
+ }
+- POP_TAG();
++ PUSH_ITER(rb_block_given_p()?ITER_PRE:ITER_NOT);
++ result = rb_call0(data->klass,data->recv,data->id,data->oid,argc,argv,data->body,safe);
+ POP_ITER();
+- if (safe >= 0) ruby_safe_level = safe;
+- if (state) JUMP_TAG(state);
+ return result;
+ }
+