diff options
| author | KJ Tsanaktsidis <kj@kjtsanaktsidis.id.au> | 2024-08-08 21:24:13 +1000 |
|---|---|---|
| committer | KJ Tsanaktsidis <kj@kjtsanaktsidis.id.au> | 2024-08-23 09:34:41 +1000 |
| commit | 8800127d80fb1063a186ced65af445e79a518924 (patch) | |
| tree | a708756994a29730cd7c63e187586bb2be4ffc60 /test/ruby | |
| parent | 165635049a2f5af83efe2bd64b08e7b59e925e18 (diff) | |
Skip some tests which don't work under permissionless containers
When running as UID 0 but without CAP_DAC_OVERRIDE (for example, in a
docker container running with --uid 0 but --cap-drop=all), these tests
won't work because of hard-coded assumptions about what uid 0 can and
can't do.
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/11402
Diffstat (limited to 'test/ruby')
| -rw-r--r-- | test/ruby/test_file_exhaustive.rb | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/test/ruby/test_file_exhaustive.rb b/test/ruby/test_file_exhaustive.rb index de09811946..f3068cb189 100644 --- a/test/ruby/test_file_exhaustive.rb +++ b/test/ruby/test_file_exhaustive.rb @@ -186,6 +186,12 @@ class TestFileExhaustive < Test::Unit::TestCase @blockdev end + def root_without_capabilities? + return false unless Process.uid == 0 + return false unless system('command', '-v', 'capsh', out: File::NULL) + !system('capsh', '--has-p=CAP_DAC_OVERRIDE', out: File::NULL, err: File::NULL) + end + def test_path [regular_file, utf8_file].each do |file| assert_equal(file, File.open(file) {|f| f.path}) @@ -1538,8 +1544,17 @@ class TestFileExhaustive < Test::Unit::TestCase assert_equal(stat.size?, File.size?(f), f) assert_bool_equal(stat.socket?, File.socket?(f), f) assert_bool_equal(stat.setuid?, File.setuid?(f), f) - assert_bool_equal(stat.writable?, File.writable?(f), f) - assert_bool_equal(stat.writable_real?, File.writable_real?(f), f) + # It's possible in Linux to be uid 0, but not to have the CAP_DAC_OVERRIDE + # capability that allows skipping file permissions checks (e.g. some kinds + # of "rootless" container setups). In these cases, stat.writable? will be + # true (because it always returns true if Process.uid == 0), but + # File.writeable? will be false (because it actually asks the kernel to do + # an access check). + # Skip these two assertions in that case. + unless root_without_capabilities? + assert_bool_equal(stat.writable?, File.writable?(f), f) + assert_bool_equal(stat.writable_real?, File.writable_real?(f), f) + end assert_bool_equal(stat.executable?, File.executable?(f), f) assert_bool_equal(stat.executable_real?, File.executable_real?(f), f) assert_bool_equal(stat.zero?, File.zero?(f), f) |
