summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoryugui <yugui@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-02-22 04:30:22 +0000
committeryugui <yugui@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-02-22 04:30:22 +0000
commitabc40f03ef23ee760046577694b308b08c2f396a (patch)
tree98b4586c393be261dc7445c0445966d5de44774a
parentcb2f0c9d14f84f3a587046e0cd949532b0304c5f (diff)
merges r21917, r21955 and r21974 from trunk into ruby_1_9_1.
* load.c (rb_require_safe): raises when the path to be loaded is tainted. [ruby-dev:37843] --- * file.c (rb_find_file_ext): should not be infected from other load paths. --- * adds a test case for r21955 and r21917. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_9_1@22500 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog10
-rw-r--r--file.c1
-rw-r--r--load.c6
-rw-r--r--test/ruby/test_require.rb46
4 files changed, 62 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index 7bd91c4d50..97c41063b2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+Mon Feb 2 17:05:55 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * file.c (rb_find_file_ext): should not be infected from other
+ load paths.
+
+Sat Jan 31 19:09:30 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * load.c (rb_require_safe): raises when the path to be loaded is
+ tainted. [ruby-dev:37843]
+
Mon Feb 2 08:12:50 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
* lib/xmlrpc/server.rb (Server#serve): gets rid of hardcoded
diff --git a/file.c b/file.c
index 918ac112d5..e4261293ce 100644
--- a/file.c
+++ b/file.c
@@ -4551,6 +4551,7 @@ rb_find_file_ext(VALUE *filep, const char *const *ext)
*filep = tmp;
return j+1;
}
+ FL_UNSET(tmp, FL_TAINT | FL_UNTRUSTED);
}
rb_str_set_len(fname, fnlen);
}
diff --git a/load.c b/load.c
index 8e66a75718..8e533771f1 100644
--- a/load.c
+++ b/load.c
@@ -554,13 +554,17 @@ rb_require_safe(VALUE fname, int safe)
rb_set_safe_level_force(safe);
FilePathValue(fname);
RB_GC_GUARD(fname) = rb_str_new4(fname);
+ rb_set_safe_level_force(0);
found = search_required(fname, &path);
if (found) {
if (!path || !(ftptr = load_lock(RSTRING_PTR(path)))) {
result = Qfalse;
}
else {
- rb_set_safe_level_force(0);
+ if (safe > 0 && OBJ_TAINTED(path)) {
+ rb_raise(rb_eSecurityError, "cannot load from insecure path - %s",
+ RSTRING_PTR(path));
+ }
switch (found) {
case 'r':
rb_load(path, 0);
diff --git a/test/ruby/test_require.rb b/test/ruby/test_require.rb
index 4048ba038d..4bc44eff04 100644
--- a/test/ruby/test_require.rb
+++ b/test/ruby/test_require.rb
@@ -195,4 +195,50 @@ class TestRequire < Test::Unit::TestCase
assert_raise(ArgumentError) { at_exit }
end
+
+ def test_tainted_loadpath
+ t = Tempfile.new(["test_ruby_test_require", ".rb"])
+ abs_dir, file = File.dirname(t.path), File.basename(t.path)
+ abs_dir = File.expand_path(abs_dir).untaint
+
+ assert_in_out_err([], <<-INPUT, %w(:ok), [])
+ abs_dir = "#{ abs_dir }"
+ $: << abs_dir
+ require "#{ file }"
+ p :ok
+ INPUT
+
+ assert_in_out_err([], <<-INPUT, %w(:ok), [])
+ abs_dir = "#{ abs_dir }"
+ $: << abs_dir.taint
+ require "#{ file }"
+ p :ok
+ INPUT
+
+ assert_in_out_err([], <<-INPUT, %w(:ok), [])
+ abs_dir = "#{ abs_dir }"
+ $: << abs_dir.taint
+ $SAFE = 1
+ begin
+ require "#{ file }"
+ rescue SecurityError
+ p :ok
+ end
+ INPUT
+
+ assert_in_out_err([], <<-INPUT, %w(:ok), [])
+ abs_dir = "#{ abs_dir }"
+ $: << abs_dir.taint
+ $SAFE = 1
+ require "#{ t.path }"
+ p :ok
+ INPUT
+
+ assert_in_out_err([], <<-INPUT, %w(:ok), [])
+ abs_dir = "#{ abs_dir }"
+ $: << abs_dir << 'elsewhere'.taint
+ require "#{ file }"
+ p :ok
+ INPUT
+ end
end