summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--lib/tmpdir.rb9
-rw-r--r--test/test_tmpdir.rb20
3 files changed, 34 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 833307a67b..94b4c712d9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Mon Mar 12 07:19:03 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * lib/tmpdir.rb (Dir.tmpdir): should not use world-writable but
+ non-sticky directory.
+
+ * lib/tmpdir.rb (Dir.mktmpdir): check the parent directory.
+
Mon Mar 12 07:04:11 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
* random.c (Init_Random): removed rb_Random_DEFAULT and register as
diff --git a/lib/tmpdir.rb b/lib/tmpdir.rb
index d7f68272e8..0791c38746 100644
--- a/lib/tmpdir.rb
+++ b/lib/tmpdir.rb
@@ -23,7 +23,8 @@ class Dir
tmp = @@systmpdir
else
for dir in [ENV['TMPDIR'], ENV['TMP'], ENV['TEMP'], @@systmpdir, '/tmp']
- if dir and stat = File.stat(dir) and stat.directory? and stat.writable?
+ if dir and stat = File.stat(dir) and stat.directory? and stat.writable? and
+ (!stat.world_writable? or stat.sticky?)
tmp = dir
break
end rescue nil
@@ -82,7 +83,11 @@ class Dir
begin
yield path
ensure
- FileUtils.remove_entry_secure path
+ stat = File.stat(File.dirname(path))
+ if stat.world_writable? and !stat.sticky?
+ raise ArgumentError, "parent directory is world writable but not sticky"
+ end
+ FileUtils.remove_entry path
end
else
path
diff --git a/test/test_tmpdir.rb b/test/test_tmpdir.rb
new file mode 100644
index 0000000000..9ef22e3f55
--- /dev/null
+++ b/test/test_tmpdir.rb
@@ -0,0 +1,20 @@
+require 'test/unit'
+require 'tmpdir'
+
+class TestTmpdir < Test::Unit::TestCase
+ def test_world_writable
+ Dir.mktmpdir do |tmpdir|
+ # ToDo: fix for parallel test
+ olddir, ENV["TMPDIR"] = ENV["TMPDIR"], tmpdir
+ begin
+ assert_equal(tmpdir, Dir.tmpdir)
+ File.chmod(0777, tmpdir)
+ assert_not_equal(tmpdir, Dir.tmpdir)
+ File.chmod(01777, tmpdir)
+ assert_equal(tmpdir, Dir.tmpdir)
+ ensure
+ ENV["TMPDIR"] = olddir
+ end
+ end
+ end
+end