diff --git a/ChangeLog b/ChangeLog index ef78cf14b4..1cd67e0ec0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Tue Jan 29 16:50:25 2013 Nobuyoshi Nakada + + * vm_trace.c (set_trace_func, thread_{add,set}_trace_func_m): check + safe level as well as 1.8. + Tue Jan 29 16:49:19 2013 Nobuyoshi Nakada * proc.c (rb_mod_method_arity): return original arity of the method if diff --git a/test/ruby/test_settracefunc.rb b/test/ruby/test_settracefunc.rb index af97651493..264b805127 100644 --- a/test/ruby/test_settracefunc.rb +++ b/test/ruby/test_settracefunc.rb @@ -397,6 +397,38 @@ class TestSetTraceFunc < Test::Unit::TestCase assert_equal(self, ok, bug3921) end + def assert_security_error_safe4 + func = lambda { + $SAFE = 4 + proc {yield} + }.call + assert_raise(SecurityError, &func) + end + + def test_set_safe4 + assert_security_error_safe4 do + set_trace_func(lambda {|*|}) + end + end + + def test_thread_set_safe4 + th = Thread.start {sleep} + assert_security_error_safe4 do + th.set_trace_func(lambda {|*|}) + end + ensure + th.kill + end + + def test_thread_add_safe4 + th = Thread.start {sleep} + assert_security_error_safe4 do + th.add_trace_func(lambda {|*|}) + end + ensure + th.kill + end + class << self define_method(:method_added, Module.method(:method_added)) end diff --git a/vm_trace.c b/vm_trace.c index 9165e37bf3..36fa2327ea 100644 --- a/vm_trace.c +++ b/vm_trace.c @@ -443,6 +443,8 @@ static void call_trace_func(rb_event_flag_t, VALUE data, VALUE self, ID id, VALU static VALUE set_trace_func(VALUE obj, VALUE trace) { + rb_secure(4); + rb_remove_event_hook(call_trace_func); if (NIL_P(trace)) { @@ -479,6 +481,8 @@ static VALUE thread_add_trace_func_m(VALUE obj, VALUE trace) { rb_thread_t *th; + + rb_secure(4); GetThreadPtr(obj, th); thread_add_trace_func(th, trace); return trace; @@ -498,6 +502,8 @@ static VALUE thread_set_trace_func_m(VALUE obj, VALUE trace) { rb_thread_t *th; + + rb_secure(4); GetThreadPtr(obj, th); rb_threadptr_remove_event_hook(th, call_trace_func, Qundef);