Describe the bug
Basic Ruby rake command that use direct path to Ruby's bin print a permission warning.
script.rb:4: warning: Insecure world writable dir /home/runner in PATH, mode 040777
Area for Triage:
Ruby
Question, Bug, or Feature?:
Bug
Virtual environments affected
Expected behavior
No warnings
Actual behavior
https://github.com/benoittgt/actions_ruby_testing
Create a ruby file:
# script.rb
require 'rake'
require 'rake/tasklib'
system("#{Rake::TaskLib::RUBY} -e 'p :foo'")
ruby script.rb in a Github Actions after setting up Ruby.I have the same issue with actions/setup-ruby@master and eregon/use-ruby-action@master, only the path change.
The command generated looks like this:
/home/runner/.rubies/ruby-2.6.5/bin/ruby -e 'p :foo'
Related
I believe this warning comes from standard Ruby, whenever a subprocess is created.
The warning is from https://github.com/ruby/ruby/blob/v2_6_5/file.c#L5899-L5904
I think the fix for this would be to not have /home/runner as world writable.
Permissions like 755 or 775 for /home/runner should remove the warning, since the code check for S_IWOTH.
Thanks a lot @eregon for the additional information. 馃檹
Maybe the issue is with ubuntu image itself.
name: CI
on: [pull_request, push]
jobs:
test:
strategy:
matrix:
os: [ ubuntu-latest]
ruby: ["2.6"]
runs-on: ${{ matrix.os }}
steps:
- run: ls -l /home/
Run ls -l /home/
total 12
drwxrwxrwx+ 3 root root 4096 Jan 3 00:43 packer
drwxrwxrwx 7 runner docker 4096 Jan 13 22:31 runner
drwxrwxrwx+ 3 runneradmin runneradmin 4096 Jan 13 17:29 runneradmin
Seems to be too much rights...
This is not a multi-user machine, so there's little concern in having overly-broad rights to a home directory. Since many users run workflows in containers - which don't necessarily have the same uid/gid maps - it's much easier to have the workspace directory writable by the users inside that container.
Curious if this giving you an _error_ or is this giving you a _warning_?
@ethomson It ends up as an error by failing tests due to causing extra output on STDERR, and some tests capture STDERR:
https://github.com/benoittgt/rspec-core/commit/6f49b7d5535ae80674f58d049ff892238c6269af/checks?check_suite_id=392370319#step:11:921
Failures:
1) RSpec::Core::RakeTask with_clean_environment is set removes the environment variables
Failure/Error:
expect {
task.with_clean_environment = true
task.ruby_opts = '-e "puts \"Environment: #{ENV.keys}\""'
task.run_task false
}.to avoid_outputting.to_stderr.and output(essential_shell_variables).to_stdout_from_any_process
expected block to not output to stderr, but output "/home/runner/work/rspec-core/rspec-core/lib/rspec/core/rake_task.rb:95: warning: Insecure world writable dir /home/runner in PATH, mode 040777\n"
(from https://github.community/t5/GitHub-Actions/How-to-avoid-message-quot-warning-Insecure-world-writable-dir/m-p/42980/highlight/true#M5192)
@eregon - changing those permissions now will potentially break workflows that might depend on it and since it's not a widely necessary breaking change I rather keep it as is. Can you add a step to tighten those permissions when your workflow starts?
@alepauly: you're asking _everyone who runs Ruby on GH-Actions_ to tweak their workflow. That doesn't sound like a working plan.
@tenderlove is there a chance that there's some sort of environment variable or setting that says "yes, I know I have a world-writable directory, everything's fine"?
To be honest, I don't think it is Ruby's business what permissions user decided to have on their home directory. But it is very unlikely that this warning will be removed from older releases that people still use to test on CIs.
Perhaps we could get the setup-ruby action to setup the permissions correctly, though that applies to self-hosted runners as well, at least it limits the permission changing to ruby workflows only.
@ethomson
@tenderlove is there a chance that there's some sort of environment variable or setting that says "yes, I know I have a world-writable directory, everything's fine"?
There doesn't seem to be: https://github.com/ruby/ruby/blob/v2_6_5/file.c#L5863-L5869
FWIW here is what the Docker images made by Dockers maintainers do to avoid this issue:
https://github.com/docker-library/ruby/blob/82eecb7596c3cb466dd87d4b0350d189a330b925/2.7/buster/Dockerfile#L38-L45
At least they acknowledge it's a hack.
I agree it's not really Ruby's business to warn about this, so it sounds worth having an easier way to disable the check for future versions. Of course it won't fix existing versions.
@eregon - changing those permissions now will potentially break workflows that might depend on it and since it's not a widely necessary breaking change I rather keep it as is. Can you add a step to tighten those permissions when your workflow starts?
Could you show an example workflow that would break?
Is there maybe a setting of Docker we could set so it properly maps the UIDs/GIDs if it's not already the case? From my experience with Docker I never had the issue.
I think having 777 permissions anywhere is encouraging bad practices, and could lead to not catching permissions problems in CI when there would be on any realistic deployment scenario.
Could you show an example workflow that would break?
OTOH I know the actions/runner needs to be able to write to that directory. When thinking of other customer workflows, I can imagine workflows that do things under an alternate user and try to write output could fail. I'm not exactly sure what that scenario would be but given that these images are used on thousands of builds daily for all sorts of development, I wouldn't be surprised if some would break.
This is why I think that asking setup-ruby to take care of it would be a good solution that makes it so not all Ruby workflows have to repeat the same setup and so that non-Ruby workflows are not affected.
@bryanmacfarlane What do you think? Is this something we should fix in setup-ruby-like actions then?
BTW I'm not sure why but the warnings happen on 2.4.9, 2.5.7 and 2.6.5 but not on 2.7.0,
see https://github.com/ruby/spec/runs/413531104 under Run specs. It's only on Linux, macOS seems to have safe permissions and the check is not performed on Windows.
BTW I'm not sure why but the warnings happen on 2.4.9, 2.5.7 and 2.6.5 but not on 2.7.0,
Random guessing https://github.com/ruby/ruby/commit/ffd0820ab317542f8780aac475da590a4bdbc7a8#diff-eff9999082c8ce7d8ba1fc1d79f439cfL4848 馃し鈥嶁檪
I'm with @ethomson on this is not a multi-user machine. the workflow owns the machine form the life time of the job and has full admin access.
Regarding the point from @alepauly on modifying permissions. If we were to do it (and per point above, I don't think it's an issue), it would be the responsibility of whoever laid down the bits (image gen in the cache case, setup-ruby if it pulls JIT). Right now setup-ruby just sets up the path for what the vm image gen lays down.
It looks like the world readable is set even if ruby isn't in the picture per comment at top of this thread https://github.com/actions/virtual-environments/issues/267#issuecomment-573906292
The runner is installed onto the ubuntu image with world writable permissions (instead of user writable). @alepauly that is done by the MMS provisioner which sets up the VM. It's also dangerous as you pointed out to narrow that even though I think user writable/owned by the account the provisioner sets up the runner to run as would be fairly safe.
I think another possible change is for image gen/provisioner to setup the tool cache outside the runner path (it's just an envvar) and set /toolcache/ruby dir to user writable. That would limit scope of impact to just the ruby tools. Once again, whoever sets up the toolcache directory structure and populates it (image gen) should set permissions on the top level dirs.
/home/runner/.rubies/ruby-2.6.5/bin/ruby -e 'p :foo'
The final thing that has me confused is the path 鈽濓笍 . That's not under the tool path. @eregon is your setup action extracting directly under the runner directory or is it extracting into the tool cache directory? I'm hoping the provisioner didn't set the tool cache to the root of the runner dir.
@bryanmacfarlane There are two directories with 777 permissions, as noted in the Community Discussion. Here is the log showing both:
warning: Insecure world writable dir /home/runner in PATH, mode 040777 ($HOME)warning: Insecure world writable dir /opt/hostedtoolcache/Ruby/2.5.5/x64/bin in PATH, mode 040777None of them are set by Ruby actions, they are from the image.
https://github.com/eregon/use-ruby-action extracts under the $HOME/.rubies directory, which is typical of how Ruby managers do it. It's also common to have custom executables under聽$HOME/bin.
@eregon - cool. I believe the provisioner creates the /home/runner and the image gen process creates /opts/hostedtoolcache/Ruby (someone should verify whether it's just inheriting from hostedtoolcache.
Here is a run showing permissions of relevant paths:
https://github.com/eregon/use-ruby-action/runs/421289303
$ ruby -e "system(RbConfig.ruby, '-e', 'p(:foo)')"
-e:1: warning: Insecure world writable dir /home/runner in PATH, mode 040777
:foo
$ echo $PATH
/home/runner/.rubies/ruby-2.6.5/bin:/usr/share/rust/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
/home = 755 (OK)
Directories with 777 (drwxrwxrwx):
/home/runner
/opt
/opt/hostedtoolcache
/opt/hostedtoolcache/Ruby
/opt/hostedtoolcache/Ruby/2.5.7
/opt/hostedtoolcache/Ruby/2.5.7/x64
/opt/hostedtoolcache/Ruby/2.5.7/x64/bin
All files under /opt/hostedtoolcache/Ruby/2.5.7/x64/bin are also 777
Which means if anything from the hostedtoolcache is in PATH, Ruby (no matter from where it's run) will trigger a warning when it shells out to a subprocess.
Yep, so we should look at what in the image generation process creates and sets permissions to
/opt/hostedtoolcache
Ruby sub directories is just inheriting those permissions.
There are even more directories with 777 permissions part of PATH (revealed when fixing $HOME permissions):
warning: Insecure world writable dir /usr/share/rust/.cargo/bin in PATH, mode 040777
All these are 777:
/usr/share
/usr/share/rust
/usr/share/rust/.cargo
/usr/share/rust/.cargo/bin
Which means that's completely impractical to fix in a setup action as it's many directories, and should be fixed when building the image.
When I was testing Github action. I ended up doing:
- name: Run build
run: |
sudo chmod 755 /home/runner
sudo chmod 755 -R /usr/share
script/run_build
````
I had this kind of warning captured in the output:
1) RSpec loads mocks and expectations when the constants are referenced
Failure/Error: @example_group_instance.instance_exec(*args, &block)
RuntimeError:
Warnings were generated: /home/runner/.rubies/ruby-2.6.5/lib/ruby/2.6.0/open3.rb:213: warning: Insecure world writable dir /usr/share/rust/.cargo/bin in PATH, mode 040777
```
For https://github.com/eregon/use-ruby-action, since I build all Rubies myself, for now I will use
CPPFLAGS="-DENABLE_PATH_CHECK=0" ./configure ...
(found at https://stackoverflow.com/a/21868701/388803)
That disables the check and should be the most compatible.
Those builds are meant to be used within GitHub Actions only, so it should be fine.
It's still not ideal of course, and I think for setup-ruby you'll want to fix the image permissions at least for /opt (and everything below) and /usr/share (and everything below).
That disables the check and should be the most compatible.
Those builds are meant to be used within GitHub Actions only, so it should be fine.
This seems like a good solution.
@alepauly can we make sure that all the rubies that we build include this setting (if we don't already)?
It's still not ideal of course, and I think for setup-ruby you'll want to fix the image permissions at least for /opt (and everything below) and /usr/share (and everything below).
The problem with this is that setup-ruby has now changed the environment for anything that executes _after_ it. It makes it _very_ hard to reason about the environment - if you had something that depended on lax permissions, and it worked _before_ a setup-ruby invocation and failed after an invocation, that would be extremely confusing (at best).
@ethomson I wasn't clear, I agree setup-ruby shouldn't change permissions as that would be hard to debug.
What I meant was I think it would be better to fix the permissions of /opt and /usr/share (recursively) when building the virtual environment. as @bryanmacfarlane suggested above for /opt/hostedtoolcache.
@alepauly can we make sure that all the rubies that we build include this setting (if we don't already)?
@ethomson yep! we'll look into that.
It's still not ideal of course, and I think for
setup-rubyyou'll want to fix the image permissions at least for/opt(and everything below) and/usr/share(and everything below).
This would only be necessary of the binaries are not compiled with -DENABLE_PATH_CHECK=0, correct?
This would only be necessary of the binaries are not compiled with
-DENABLE_PATH_CHECK=0, correct?
Right, although I think it would still be a good thing to fix, and other tools might not like having world-writable directories in the PATH.
@benoittgt new ruby packages with DENABLE_PATH_CHECK=0 have been generated and will be delivered during the next VM image rollout(approx. 1-2 weeks)
@benoittgt the image has been deployed. Could you check the ruby behavior, please?
Hello @miketimofeev
I have another error only on Github CI related to a complicated loading mechanism on an RSpec dependency.
https://github.com/benoittgt/actions_ruby_testing/runs/460385848?check_suite_focus=true
But I did a simple test with a ruby script that was failing before:
require 'rake'
require 'rake/tasklib'
system("#{Rake::TaskLib::RUBY} -e 'p :foo'")
And I do not have noise anymore. For me the issue can be closed. I will keep you informed if I succeed fixing the rspec-core CI.
@benoittgt thanks for the update!
I have a same error when trying to load DPDK applications. It's a C++ library that will verify it does not load plugins from openly-accessible path, so the ruby solution does not work here. Or can I set back the permission correctly ? sudo chmod seems a little horrible...
Can I build instead somewhere safe? Eg create a folder in /tmp?
@tbarbette Could you please create a new issue with all the details if you need any assistance with it?
Most helpful comment
Here is a run showing permissions of relevant paths:
https://github.com/eregon/use-ruby-action/runs/421289303
Which means if anything from the hostedtoolcache is in
PATH, Ruby (no matter from where it's run) will trigger a warning when it shells out to a subprocess.