Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Wrong permissions on system-wide installed gem files #2136

zeha opened this Issue Oct 29, 2012 · 14 comments


None yet
6 participants

zeha commented Oct 29, 2012

When using bundler as non-root, gem files installed into the system location can end up with the wrong permissions, when the user running bundler has a umask != 022.
Additionally, gem cache files end up being owned by the user running bundler.

Example for the cache file ownership:

% cat Gemfile
source :rubygems
gem "tzinfo"
% ls -la /var/lib/gems/1.9.1/cache/tzinfo-*
-rw-r--r-- 1 ch ch 311808 Okt 29 15:55 /var/lib/gems/1.9.1/cache/tzinfo-0.3.34.gem

Looking at the code, lib/bundler/fetcher.rb does a sudo mv of the cache file into it's final location; replacing this with cp should make this part of the issue go away.

The other part is that the files of the gem themselves end up being created with the users umask.

Example (from the original reporter) with umask 027:

-rw-r----- 1 rrt rrt  89K Oct 29 10:30 addressable-2.3.2.gem 
-rw-r----- 1 rrt rrt  35K Oct 29 10:30 crack-0.3.1.gem 
-rw-r----- 1 rrt rrt 109K Oct 29 10:30 rake- 

(Other users won't be able to read these gems.)

I'd have expected all the gem files to be owned by root, and have normalized permissions of 0644 / 0755 respectively.

This issue was reported by a user of the Debian package for bundler [1], but I have reproduced this with bundler 1.2.1 installed with gem install.

% ruby -v
ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux]
% gem1.9.1 -v
% bundle -v
Bundler version 1.2.1

[1] http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=691743

(Edited twice because I failed to understand the entirety of the issue at first.)


indirect commented Oct 29, 2012

Is the only way to normalize the permissions on the files to run chmod? Because we used to do that, and disabled it because someone else filed a bug about us not respecting the system umask.


zeha commented Nov 11, 2012

Do you have a reference to the other ticket? Can't seem to find that.
Not sure what the concept of "the system umask" is. install(1) and others usually just apply a standard set of permissions, without any masking.


indirect commented Nov 12, 2012

I've never used install(1) before, and neither Bundler nor Rubygems use it, so I'm not sure how that's relevant to this particular issue. When I said "system umask" I actually meant the user's umask.

Bundler originally normalized permissions, someone filed a bug that we should respect the current umask, and now we do. Why should we stop respecting the umask? Bundler installing to "system" gems does not actually mean it is installing gems that are available to the entire system, that's up to the system's administrator. It just means that Bundler is installing gems to the GEM_HOME directory, rather than a directory isolated to the single Gemfile being installed.


zeha commented Nov 12, 2012

Actually, I do not care so much about the umask, but about files ending up in root-owned directories that are user-writeable. If I'm not missing something, the system administrator can not easily change this. - And, this should be easy to fix with s/mv/cp/.

Regarding install(1), I just noticed that Ruby itself actually uses tools/rbinstall.rb, and Ruby itself forces 0644/0755 on the files it installs.

I'm not asking you to override the user's umask if Bundler writes to user-owned directories; but the very moment Bundler writes to directories owned by root (especially if these are the default Rubygems directories), the calling user's umask has no place in determining file permissions any more. (Note that Bundler starts sudo here; it leaves the security domain of the calling user, so the calling users settings should not apply.)

If you say that the umask problem is a Rubygems problem, then I agree that you should not try to fix it and I'll see that the original Debian bug will get reassigned to Ruby(gems).


xaviershay commented Aug 13, 2013

@indirect any reason not to use cp? If that fixes the issue, seems unobjectionable to me.


indirect commented Oct 3, 2013

cp seems fine to me. sorry for taking so long to respond to this.


indirect commented Dec 3, 2013

@rbeede so now that you've conclusively demonstrated that this issue is in Rubygems and not in Bundler... should I close this?

rbeede commented Dec 3, 2013

Would it be feasible to have Bundler provide some type of warning about file ownership and permissions if it detects it is writing into a directory owned by root? Perhaps something along the lines of:

"WARNING: Files were written to which may be a system-wide library location (owned by root), but the permission mode applied was <####> which is [not accessible to everyone | writable by anyone]. Please verify this is what you intended and if not manually correct the permissions yourself."


indirect commented Dec 16, 2013

A warning along those lines seems reasonable.


indirect commented Jan 9, 2014

Bundler still honors Rubygems' permissions as set, but now sets its own permissions on any files created by it to 0777 & ~File.umask.

@indirect indirect closed this Jan 9, 2014

zoni commented Aug 6, 2014

It would be nice if a warning like the one mentioned by @rbeede was implemented. It seems rubygems emits a warning at gem build time, but you never get to see it when installing with bundler.

I just installed some gems with bundler (1.3.5) with a umask of 066 and got the following traceback for my trouble, which is not very user-friendly:

$ kitchen version     
/usr/local/lib/site_ruby/2.0.0/rubygems/stub_specification.rb:71:in `initialize': Permission denied - /var/lib/gems/2.0.0/specifications/rspec-mocks-2.99.2.gemspec (Errno::EACCES)
        from /usr/local/lib/site_ruby/2.0.0/rubygems/stub_specification.rb:71:in `open'
        from /usr/local/lib/site_ruby/2.0.0/rubygems/stub_specification.rb:71:in `data'
        from /usr/local/lib/site_ruby/2.0.0/rubygems/stub_specification.rb:158:in `valid?'
        from /usr/local/lib/site_ruby/2.0.0/rubygems/specification.rb:719:in `block in each_stub'
        from /usr/local/lib/site_ruby/2.0.0/rubygems/specification.rb:711:in `block (2 levels) in each_gemspec'
        from /usr/local/lib/site_ruby/2.0.0/rubygems/specification.rb:710:in `each'
        from /usr/local/lib/site_ruby/2.0.0/rubygems/specification.rb:710:in `block in each_gemspec'
        from /usr/local/lib/site_ruby/2.0.0/rubygems/specification.rb:709:in `each'
        from /usr/local/lib/site_ruby/2.0.0/rubygems/specification.rb:709:in `each_gemspec'
        from /usr/local/lib/site_ruby/2.0.0/rubygems/specification.rb:717:in `each_stub'
        from /usr/local/lib/site_ruby/2.0.0/rubygems/specification.rb:736:in `stubs'
        from /usr/local/lib/site_ruby/2.0.0/rubygems/dependency.rb:255:in `matching_specs'
        from /usr/local/lib/site_ruby/2.0.0/rubygems/dependency.rb:279:in `to_specs'
        from /usr/local/lib/site_ruby/2.0.0/rubygems/dependency.rb:309:in `to_spec'
        from /usr/local/lib/site_ruby/2.0.0/rubygems/core_ext/kernel_gem.rb:53:in `gem'
        from /usr/local/lib/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:46:in `require'
        from /usr/local/lib/site_ruby/2.0.0/rubygems/user_interaction.rb:8:in `<top (required)>'
        from /usr/local/lib/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:55:in `require'
        from /usr/local/lib/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:55:in `require'
        from /usr/lib/ruby/vendor_ruby/bundler/rubygems_integration.rb:3:in `<top (required)>'
        from /usr/local/lib/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:55:in `require'
        from /usr/local/lib/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:55:in `require'
        from /usr/lib/ruby/vendor_ruby/bundler.rb:6:in `<top (required)>'
        from /usr/local/lib/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:55:in `require'
        from /usr/local/lib/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:55:in `require'
        from /usr/bin/bundle:7:in `<main>'

1.3.5 is admittedly pretty old now, but looking through the changelog, I see no mention of any such warning having been implemented in later versions so I don't believe that to matter in this instance.


indirect commented Aug 6, 2014

I'd be happy to accept a pull request for such a warning, but please try using a version of Bundler that is less than two years old, first.

@miketheman miketheman referenced this issue in twitter/thrift_client Nov 13, 2015


Incorrect permissions set #32

jmehnle commented Mar 3, 2016


Bundler still honors Rubygems' permissions as set, but now sets its own permissions on any files created by it to 0777 & ~File.umask.

As of what Bundler version?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment