`Kernel.load`ing a file with a class definition in $SAFE = 1 underRuby 1.9.2-p180

M

Michael Granger

Hi,

[I tried posting this to StackOverflow first, so apologies to those for
whom this is a double-post of sorts.]

I am trying to use the two-argument form of Kernel.load while running in
safe level 1 to load a class definition inside an anonymous namespace.
For example, the file I'm trying to Kernel.load looks like:

# module.rb
class Foo < Superclass
def bar
puts "Bar!"
end
end

And the test case looks like:

# loader.rb

BASEDIR = File.expand_path( File.dirname(__FILE__) )
MODULE_FILE = File.join( BASEDIR, 'module.rb' ).untaint

$stderr.puts "Module file name (%p) is %s" %
[ MODULE_FILE, MODULE_FILE.tainted? ? "tainted" : "not tainted" ]

class Superclass
@subclasses = []
class << self; attr_reader :subclasses; end
def self::inherited( subclass )
super
@subclasses << subclass
end
end

$stderr.puts "Ruby version: #{RUBY_DESCRIPTION}"

$stderr.puts "In $SAFE = 0:"
Kernel.load( MODULE_FILE, true )
result = Superclass.subclasses.last
p result
$stderr.puts "Instantiating and calling its #bar method:"
result.new.bar

$stderr.puts "In $SAFE = 1:"
$SAFE = 1
Kernel.load( MODULE_FILE, true )
result = Superclass.subclasses.last
p result
$stderr.puts "Instantiating and calling its #bar method:"
result.new.bar

When I run it under Ruby 1.8.7, the output looks like:

Module file name ("/Users/mgranger/source/ruby/misc/safeload/\
module.rb") is not tainted
Ruby version: ruby 1.8.7 (2009-06-12 patchlevel 174) \
[universal-darwin10.0]
In $SAFE = 0:
#<Module:0x1001688d8>::Foo
Instantiating and calling its #bar method:
Bar!
In $SAFE = 1:
#<Module:0x100168090>::Foo
Instantiating and calling its #bar method:
Bar!

but under 1.9.2-p180, I get a SecurityError:

Module file name ("/Users/mgranger/source/ruby/misc/safeload/\
module.rb") is not tainted
Ruby version: ruby 1.9.2p180 (2011-02-18 revision 30909) \
[x86_64-darwin10.7.0]
In $SAFE = 0:
#<Module:0x0000010086b5b8>::Foo
Instantiating and calling its #bar method:
Bar!
In $SAFE = 1:
loader.rb:29:in `load': Insecure operation - load (SecurityError)
from loader.rb:29:in `<main>'

The documentation for Kernel.load (from rb_f_load() in load.c) says:

load(filename, wrap=false) -> true

Loads and executes the Ruby
program in the file _filename_. If the filename does not
resolve to an absolute path, the file is searched for in the library
directories listed in <code>$:</code>. If the optional _wrap_
parameter is +true+, the loaded script will be executed
under an anonymous module, protecting the calling program's global
namespace. In no circumstance will any local variables in the loaded
file be propagated to the loading environment.

which (at least to me) doesn't contain any clues.

If I replace the class definition with a puts or something, it loads
fine, but I can't seem to load a class inside an anonymous module any
longer. Any ideas?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Staff online

Members online

Forum statistics

Threads
473,767
Messages
2,569,571
Members
45,045
Latest member
DRCM

Latest Threads

Top