Skip to content

Commit

Permalink
[GR-18163] Fix file permissions predicates for superuser
Browse files Browse the repository at this point in the history
PullRequest: truffleruby/3429
  • Loading branch information
andrykonchin committed Jul 22, 2022
2 parents 545cdd6 + 0c8bf49 commit 78264ff
Show file tree
Hide file tree
Showing 9 changed files with 147 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Bug fixes:

* Fix `StringIO` to set position correctly after reading multi-byte characters (#2207, @aardvark179).
* Update `Process` methods to use `module_function` (@bjfish).
* Fix `File::Stat`'s `#executable?` and `#executable_real?` predicates that unconditionally returned `true` for a superuser (#2690, @andrykonchin).

Compatibility:

Expand Down
10 changes: 10 additions & 0 deletions spec/mspec/lib/mspec/guards/superuser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,20 @@ def match?
end
end

class RealSuperUserGuard < SpecGuard
def match?
Process.uid == 0
end
end

def as_superuser(&block)
SuperUserGuard.new.run_if(:as_superuser, &block)
end

def as_real_superuser(&block)
RealSuperUserGuard.new.run_if(:as_real_superuser, &block)
end

def as_user(&block)
SuperUserGuard.new.run_unless(:as_user, &block)
end
35 changes: 35 additions & 0 deletions spec/ruby/shared/file/executable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,41 @@
-> { @object.send(@method, nil) }.should raise_error(TypeError)
-> { @object.send(@method, false) }.should raise_error(TypeError)
end

platform_is_not :windows do
as_superuser do
context "when run by a superuser" do
before :each do
@file = tmp('temp3.txt')
touch @file
end

after :each do
rm_r @file
end

it "returns true if file owner has permission to execute" do
File.chmod(0766, @file)
@object.send(@method, @file).should == true
end

it "returns true if group has permission to execute" do
File.chmod(0676, @file)
@object.send(@method, @file).should == true
end

it "returns true if other have permission to execute" do
File.chmod(0667, @file)
@object.send(@method, @file).should == true
end

it "return false if nobody has permission to execute" do
File.chmod(0666, @file)
@object.send(@method, @file).should == false
end
end
end
end
end

describe :file_executable_missing, shared: true do
Expand Down
35 changes: 35 additions & 0 deletions spec/ruby/shared/file/executable_real.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,41 @@
-> { @object.send(@method, nil) }.should raise_error(TypeError)
-> { @object.send(@method, false) }.should raise_error(TypeError)
end

platform_is_not :windows do
as_real_superuser do
context "when run by a real superuser" do
before :each do
@file = tmp('temp3.txt')
touch @file
end

after :each do
rm_r @file
end

it "returns true if file owner has permission to execute" do
File.chmod(0766, @file)
@object.send(@method, @file).should == true
end

it "returns true if group has permission to execute" do
File.chmod(0676, @file)
@object.send(@method, @file).should == true
end

it "returns true if other have permission to execute" do
File.chmod(0667, @file)
@object.send(@method, @file).should == true
end

it "return false if nobody has permission to execute" do
File.chmod(0666, @file)
@object.send(@method, @file).should == false
end
end
end
end
end

describe :file_executable_real_missing, shared: true do
Expand Down
16 changes: 16 additions & 0 deletions spec/ruby/shared/file/readable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,22 @@
it "accepts an object that has a #to_path method" do
@object.send(@method, mock_to_path(@file2)).should == true
end

platform_is_not :windows do
as_superuser do
context "when run by a superuser" do
it "returns true unconditionally" do
file = tmp('temp.txt')
touch file

File.chmod(0333, file)
@object.send(@method, file).should == true

rm_r file
end
end
end
end
end

describe :file_readable_missing, shared: true do
Expand Down
16 changes: 16 additions & 0 deletions spec/ruby/shared/file/readable_real.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,22 @@
it "accepts an object that has a #to_path method" do
File.open(@file,'w') { @object.send(@method, mock_to_path(@file)).should == true }
end

platform_is_not :windows do
as_real_superuser do
context "when run by a real superuser" do
it "returns true unconditionally" do
file = tmp('temp.txt')
touch file

File.chmod(0333, file)
@object.send(@method, file).should == true

rm_r file
end
end
end
end
end

describe :file_readable_real_missing, shared: true do
Expand Down
16 changes: 16 additions & 0 deletions spec/ruby/shared/file/writable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,22 @@
it "accepts an object that has a #to_path method" do
File.open(@file,'w') { @object.send(@method, mock_to_path(@file)).should == true }
end

platform_is_not :windows do
as_superuser do
context "when run by a superuser" do
it "returns true unconditionally" do
file = tmp('temp.txt')
touch file

File.chmod(0555, file)
@object.send(@method, file).should == true

rm_r file
end
end
end
end
end

describe :file_writable_missing, shared: true do
Expand Down
16 changes: 16 additions & 0 deletions spec/ruby/shared/file/writable_real.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,22 @@
-> { @object.send(@method, nil) }.should raise_error(TypeError)
-> { @object.send(@method, false) }.should raise_error(TypeError)
end

platform_is_not :windows do
as_real_superuser do
context "when run by a real superuser" do
it "returns true unconditionally" do
file = tmp('temp.txt')
touch file

File.chmod(0555, file)
@object.send(@method, file).should == true

rm_r file
end
end
end
end
end

describe :file_writable_real_missing, shared: true do
Expand Down
4 changes: 2 additions & 2 deletions src/main/ruby/truffleruby/core/stat.rb
Original file line number Diff line number Diff line change
Expand Up @@ -131,14 +131,14 @@ def directory?
end

def executable?
return true if superuser?
return mode & S_IXUGO != 0 if superuser?
return mode & S_IXUSR != 0 if owned?
return mode & S_IXGRP != 0 if grpowned?
mode & S_IXOTH != 0
end

def executable_real?
return true if rsuperuser?
return mode & S_IXUGO != 0 if rsuperuser?
return mode & S_IXUSR != 0 if rowned?
return mode & S_IXGRP != 0 if rgrpowned?
mode & S_IXOTH != 0
Expand Down

0 comments on commit 78264ff

Please sign in to comment.