Skip to content

Commit cb04a6b

Browse files
committed
Preserve tmpdir world-writable guard
1 parent d2ec6e2 commit cb04a6b

2 files changed

Lines changed: 21 additions & 6 deletions

File tree

lib/tmpdir.rb

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,20 +32,18 @@ def self.tmpdir
3232
case
3333
when !stat.directory?
3434
warn "#{name} is not a directory: #{dir}"
35+
when stat.world_writable? && !stat.sticky?
36+
warn "#{name} is world-writable: #{dir}"
3537
when !File.writable?(dir)
3638
# We call File.writable?, not stat.writable?, because you can't tell if a dir is actually
3739
# writable just from stat; OS mechanisms other than user/group/world bits can affect this.
3840
#
39-
# However, in some container environments (e.g. Kubernetes with read-only root filesystem
40-
# and emptyDir volumes), File.writable? may return false even though the directory is
41-
# actually writable via mounted volumes. Fall back to stat.writable? in that case.
41+
# However, File.writable? can be a false negative, so fall back to stat.writable?.
4242
if stat.writable?
4343
warn "#{name}: File.writable? reports not writable but file mode bits suggest writable, using anyway: #{dir}"
4444
break dir
4545
end
4646
warn "#{name} is not writable: #{dir}"
47-
when stat.world_writable? && !stat.sticky?
48-
warn "#{name} is world-writable: #{dir}"
4947
else
5048
break dir
5149
end

test/test_tmpdir.rb

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,26 @@ def test_writable_fallback_to_stat
9090
end
9191
end
9292

93+
def test_tmpdir_rejects_world_writable_non_sticky_before_writability
94+
omit "no meaning on this platform" if /mswin|mingw/ =~ RUBY_PLATFORM
95+
Dir.mktmpdir do |tmpdir|
96+
envs = %w[TMPDIR TMP TEMP]
97+
oldenv = envs.each_with_object({}) {|v, h| h[v] = ENV.delete(v)}
98+
begin
99+
ENV[envs[0]] = tmpdir
100+
File.chmod(0777, tmpdir)
101+
102+
assert_not_equal(tmpdir, assert_warn(/is world-writable/) { Dir.tmpdir })
103+
ensure
104+
File.chmod(0755, tmpdir)
105+
ENV.update(oldenv)
106+
end
107+
end
108+
end
109+
93110
def test_writable_fallback_both_fail
94111
omit "no meaning on this platform" if /mswin|mingw/ =~ RUBY_PLATFORM
95-
omit "root can write to any directory" if Process.uid == 0
112+
omit "root can write to any directory" if Process.euid == 0
96113
Dir.mktmpdir do |tmpdir|
97114
envs = %w[TMPDIR TMP TEMP]
98115
oldenv = envs.each_with_object({}) {|v, h| h[v] = ENV.delete(v)}

0 commit comments

Comments
 (0)