Skip to content

Do not hard-code permissions for new gem directories during bundle install#9557

Open
maxfelsher-cgi wants to merge 1 commit into
ruby:masterfrom
maxfelsher-cgi:fix-install-permissions
Open

Do not hard-code permissions for new gem directories during bundle install#9557
maxfelsher-cgi wants to merge 1 commit into
ruby:masterfrom
maxfelsher-cgi:fix-install-permissions

Conversation

@maxfelsher-cgi
Copy link
Copy Markdown

What was the end-user or developer problem that led to this PR?

This fixes #9395. Without this change, when running bundle install, any newly created gem directory has permissions rwxr-xr-x regardless of umask settings and regardless of the set-group-ID bit of the parent directory. This makes it much harder to remove gems in a multi-user environment (for example, where different developers have conducted deployments). It also differs from the behavior of gem install ..., which does respect the umask and the set-group-ID bit.

What is your fix for the problem, implemented in this PR?

The mode: 0o755 argument was removed from the FileUtils.mkdir_p call that creates the new directory for the gem being installed. This avoids setting specific permissions and lets the system's default permission handling (such as umask and set-group-ID bits) function.

The hard-coding was originally set up in 79386f4 as part of what appeared to be an unrelated reimplementation of Bundler::RubyGemsGemInstaller#install. Previous to that commit, Bundler::RubyGemsGemInstaller was using the implementation in the parent class, GemInstaller#install. In the commit, the implementation from GemInstaller was copied and then modified to fit Bundler's needs, removing code that wasn't necessary for Bundler. However, I believe a mistake was made during that modification. In the GemInstaller implementation, the relevant lines looked like this:

dir_mode = options[:dir_mode]
FileUtils.mkdir_p gem_dir, :mode => dir_mode && 0755

In that case, if options[:dir_mode] was nil, then the resulting call was FileUtils.mkdir_p gem_dir, :mode => nil, which was equivalent to FileUtils.mkdir_p gem_dir. If options[:dir_mode] was truthy, then the call was FileUtils.mkdir_p gem_dir, :mode => 0755. (Note that there was a line further down that ran File.chmod(dir_mode, gem_dir) if dir_mode.) My impression is that usually options[:dir_mode] is not set.

After 79386f4, the Bundler implementation was:

FileUtils.mkdir_p gem_dir, :mode => 0o755

This made it so that the FileUtils.mkdir_p call always set the mode parameter, instead of hardly ever. I suspect that the code dir_mode && 0755 (using the short-circuiting operator) may have been misread as dir_mode & 0755 (using the bitwise AND method). The bitwise-AND reading was how I read the code at first glance, and it would make sense that such an interpretation would lead someone to change the code to simply 0755 when removing dir_mode.

There have been some updates to both implementations since 79386f4, but nothing that affects the reasoning above. I saw no mentions of the permissions change in the commit message or associated pull request, and given that gem install continues to have the old behavior, I believe the change was unintentional. It is much more complicated to fix the permissions after the fact without invoking superuser privileges, so I think the right place to make the adjustment is here, where the files are being created.

Make sure the following tasks are checked

…stall

This hard-coding was overriding umask and setgid settings, making it very difficult to manage gem installations through a shared group. In addition, it differs from the behavior of `gem install`.

The hard-coding was originally added in 79386f4 as part of an unrelated reimplementation of `Bundler::RubyGemsGemInstaller#install`, but it looks like the logic on the corresponding line of `Gem::Installer#install` might have been misinterpreted, as that line only sets the `mode` argument if `options[:dir_mode]` is set.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bundler hard-codes permissions of directories for new gems, making multi-user management very difficult

1 participant