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?
[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?