tmpdir.rb: permission of user given directory

* lib/tmpdir.rb (Dir.mktmpdir): check if the permission of the
  parent directory only when using the default temporary
  directory, and no check against user given directory.  the
  security is the user's responsibility in that case.
  [ruby-core:91216] [Bug #15555]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66909 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2019-01-23 06:06:47 +00:00
parent 05c3256b28
commit 1fae154c07
2 changed files with 18 additions and 5 deletions

View File

@ -83,14 +83,20 @@ class Dir
# end # end
# #
def self.mktmpdir(prefix_suffix=nil, *rest) def self.mktmpdir(prefix_suffix=nil, *rest)
path = Tmpname.create(prefix_suffix || "d", *rest) {|n| mkdir(n, 0700)} base = nil
path = Tmpname.create(prefix_suffix || "d", *rest) {|path, _, _, d|
base = d
mkdir(path, 0700)
}
if block_given? if block_given?
begin begin
yield path yield path
ensure ensure
stat = File.stat(File.dirname(path)) unless base
if stat.world_writable? and !stat.sticky? stat = File.stat(File.dirname(path))
raise ArgumentError, "parent directory is world writable but not sticky" if stat.world_writable? and !stat.sticky?
raise ArgumentError, "parent directory is world writable but not sticky"
end
end end
FileUtils.remove_entry path FileUtils.remove_entry path
end end
@ -110,6 +116,7 @@ class Dir
if $SAFE > 0 and tmpdir.tainted? if $SAFE > 0 and tmpdir.tainted?
tmpdir = '/tmp' tmpdir = '/tmp'
else else
origdir = tmpdir
tmpdir ||= tmpdir() tmpdir ||= tmpdir()
end end
n = nil n = nil
@ -125,7 +132,7 @@ class Dir
path = "#{prefix}#{t}-#{$$}-#{rand(0x100000000).to_s(36)}"\ path = "#{prefix}#{t}-#{$$}-#{rand(0x100000000).to_s(36)}"\
"#{n ? %[-#{n}] : ''}#{suffix||''}" "#{n ? %[-#{n}] : ''}#{suffix||''}"
path = File.join(tmpdir, path) path = File.join(tmpdir, path)
yield(path, n, opts) yield(path, n, opts, origdir)
rescue Errno::EEXIST rescue Errno::EEXIST
n ||= 0 n ||= 0
n += 1 n += 1

View File

@ -33,6 +33,12 @@ class TestTmpdir < Test::Unit::TestCase
assert_equal(tmpdir, Dir.tmpdir) assert_equal(tmpdir, Dir.tmpdir)
File.chmod(0777, tmpdir) File.chmod(0777, tmpdir)
assert_not_equal(tmpdir, Dir.tmpdir) assert_not_equal(tmpdir, Dir.tmpdir)
newdir = Dir.mktmpdir("d", tmpdir) do |dir|
assert_file.directory? dir
assert_equal(tmpdir, File.dirname(dir))
dir
end
assert_file.not_exist?(newdir)
File.chmod(01777, tmpdir) File.chmod(01777, tmpdir)
assert_equal(tmpdir, Dir.tmpdir) assert_equal(tmpdir, Dir.tmpdir)
ensure ensure