From c5c05460ac20abcbc0ed686eb4acf06da7a39a79 Mon Sep 17 00:00:00 2001 From: Jeremy Evans Date: Fri, 20 Sep 2019 19:06:22 -0700 Subject: Warn on access/modify of $SAFE, and remove effects of modifying $SAFE This removes the security features added by $SAFE = 1, and warns for access or modification of $SAFE from Ruby-level, as well as warning when calling all public C functions related to $SAFE. This modifies some internal functions that took a safe level argument to no longer take the argument. rb_require_safe now warns, rb_require_string has been added as a version that takes a VALUE and does not warn. One public C function that still takes a safe level argument and that this doesn't warn for is rb_eval_cmd. We may want to consider adding an alternative method that does not take a safe level argument, and warn for rb_eval_cmd. --- test/ruby/test_alias.rb | 6 ------ test/ruby/test_file.rb | 12 ------------ test/ruby/test_optimization.rb | 11 ----------- test/ruby/test_proc.rb | 39 --------------------------------------- test/ruby/test_require.rb | 7 ------- test/ruby/test_rubyoptions.rb | 14 -------------- test/ruby/test_thread.rb | 17 ----------------- 7 files changed, 106 deletions(-) (limited to 'test/ruby') diff --git a/test/ruby/test_alias.rb b/test/ruby/test_alias.rb index e81636fa43..33fb82e1d7 100644 --- a/test/ruby/test_alias.rb +++ b/test/ruby/test_alias.rb @@ -47,12 +47,6 @@ class TestAlias < Test::Unit::TestCase assert_raise(NoMethodError) { x.quux } end - class C - def m - $SAFE - end - end - def test_nonexistmethod assert_raise(NameError){ Class.new{ diff --git a/test/ruby/test_file.rb b/test/ruby/test_file.rb index f984a8fd23..5599040e1e 100644 --- a/test/ruby/test_file.rb +++ b/test/ruby/test_file.rb @@ -471,18 +471,6 @@ class TestFile < Test::Unit::TestCase end end - def test_untainted_path - bug5374 = '[ruby-core:39745]' - cwd = ("./"*40+".".taint).dup.untaint - in_safe = proc {|safe| $SAFE = safe; File.stat(cwd)} - assert_not_send([cwd, :tainted?]) - (0..1).each do |level| - assert_nothing_raised(SecurityError, bug5374) {in_safe[level]} - end - ensure - $SAFE = 0 - end - if /(bcc|ms|cyg)win|mingw|emx/ =~ RUBY_PLATFORM def test_long_unc feature3399 = '[ruby-core:30623]' diff --git a/test/ruby/test_optimization.rb b/test/ruby/test_optimization.rb index f26b31f115..b42314b765 100644 --- a/test/ruby/test_optimization.rb +++ b/test/ruby/test_optimization.rb @@ -714,17 +714,6 @@ class TestRubyOptimization < Test::Unit::TestCase END end - def test_block_parameter_should_restore_safe_level - assert_separately [], <<-END - # - def foo &b - $SAFE = 1 - b.call - end - assert_equal 1, foo{$SAFE} - END - end - def test_peephole_optimization_without_trace assert_separately [], <<-END RubyVM::InstructionSequence.compile_option = {trace_instruction: false} diff --git a/test/ruby/test_proc.rb b/test/ruby/test_proc.rb index 5c12043873..0e0b5c7b8b 100644 --- a/test/ruby/test_proc.rb +++ b/test/ruby/test_proc.rb @@ -157,45 +157,6 @@ class TestProc < Test::Unit::TestCase assert_equal(12, Proc.new{|a,&b| b.call(a)}.call(12) {|x| x}) end - def test_safe - safe = $SAFE - c = Class.new - x = c.new - - p = proc { - $SAFE += 1 - proc {$SAFE} - }.call - - assert_equal(safe + 1, $SAFE) - assert_equal(safe + 1, p.call) - assert_equal(safe + 1, $SAFE) - - $SAFE = 0 - c.class_eval {define_method(:safe, p)} - assert_equal(safe, x.safe) - - $SAFE = 0 - p = proc {$SAFE += 1} - assert_equal(safe + 1, p.call) - assert_equal(safe + 1, $SAFE) - - $SAFE = 0 - c.class_eval {define_method(:inc, p)} - assert_equal(safe + 1, proc {x.inc; $SAFE}.call) - assert_equal(safe + 1, $SAFE) - - $SAFE = 0 - assert_equal(safe + 1, proc {x.method(:inc).call; $SAFE}.call) - assert_equal(safe + 1, $SAFE) - - $SAFE = 0 - assert_equal(safe + 1, proc {x.method(:inc).to_proc.call; $SAFE}.call) - assert_equal(safe + 1, $SAFE) - ensure - $SAFE = 0 - end - def m2 "OK" end diff --git a/test/ruby/test_require.rb b/test/ruby/test_require.rb index 560ce3ff28..e21ed88e47 100644 --- a/test/ruby/test_require.rb +++ b/test/ruby/test_require.rb @@ -396,13 +396,6 @@ class TestRequire < Test::Unit::TestCase assert_nothing_raised {require "#{ file }"} INPUT - assert_separately([], <<-INPUT) - abs_dir = "#{ abs_dir }" - $: << abs_dir.taint - $SAFE = 1 - assert_raise(SecurityError) {require "#{ file }"} - INPUT - assert_separately([], <<-INPUT) abs_dir = "#{ abs_dir }" $: << abs_dir << 'elsewhere'.taint diff --git a/test/ruby/test_rubyoptions.rb b/test/ruby/test_rubyoptions.rb index 22ea6b5293..27a9434a5c 100644 --- a/test/ruby/test_rubyoptions.rb +++ b/test/ruby/test_rubyoptions.rb @@ -79,14 +79,6 @@ class TestRubyOptions < Test::Unit::TestCase ENV['RUBYOPT'] = save_rubyopt end - def test_safe_level - assert_in_out_err(%w(-T -e) + [""], "", [], - /no -e allowed in tainted mode \(SecurityError\)/) - - assert_in_out_err(%w(-T4 -S foo.rb), "", [], - /no -S allowed in tainted mode \(SecurityError\)/) - end - def test_debug assert_in_out_err(["--disable-gems", "-de", "p $DEBUG"], "", %w(true), []) @@ -326,12 +318,6 @@ class TestRubyOptions < Test::Unit::TestCase ENV['RUBYOPT'] = '-e "p 1"' assert_in_out_err([], "", [], /invalid switch in RUBYOPT: -e \(RuntimeError\)/) - ENV['RUBYOPT'] = '-T1' - assert_in_out_err(["--disable-gems"], "", [], /no program input from stdin allowed in tainted mode \(SecurityError\)/) - - ENV['RUBYOPT'] = '-T4' - assert_in_out_err(["--disable-gems"], "", [], /no program input from stdin allowed in tainted mode \(SecurityError\)/) - ENV['RUBYOPT'] = '-Eus-ascii -KN' assert_in_out_err(%w(-Eutf-8 -KU), "p '\u3042'") do |r, e| assert_equal("\"\u3042\"", r.join.force_encoding(Encoding::UTF_8)) diff --git a/test/ruby/test_thread.rb b/test/ruby/test_thread.rb index e0efb7b2e0..adfad7e7e8 100644 --- a/test/ruby/test_thread.rb +++ b/test/ruby/test_thread.rb @@ -533,23 +533,6 @@ class TestThread < Test::Unit::TestCase waiter&.kill&.join end - def test_safe_level - ok = false - t = Thread.new do - EnvUtil.suppress_warning do - $SAFE = 1 - end - ok = true - sleep - end - Thread.pass until ok - assert_equal($SAFE, Thread.current.safe_level) - assert_equal($SAFE, t.safe_level) - ensure - $SAFE = 0 - t&.kill&.join - end - def test_thread_local t = Thread.new { sleep } -- cgit v1.2.3