diff options
author | taca <taca@pkgsrc.org> | 2005-09-21 14:03:22 +0000 |
---|---|---|
committer | taca <taca@pkgsrc.org> | 2005-09-21 14:03:22 +0000 |
commit | b2a41fdcae3c5bec50cab8b2aab09ec65d725fda (patch) | |
tree | bc5cd7b7e7566e3273e22193fa0dba88d422a306 | |
parent | cd242845b844d90a352fe7d1b18993987ee28ee9 (diff) | |
download | pkgsrc-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.
-rw-r--r-- | lang/ruby18-base/Makefile | 4 | ||||
-rw-r--r-- | lang/ruby18-base/distinfo | 3 | ||||
-rw-r--r-- | lang/ruby18-base/patches/patch-ad | 158 |
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; + } + |