1. 5

    As noted in another comment, the issue isn’t that /usr/bin/gem overwrites any part of Ruby that comes with the system; it doesn’t have permissions to do that under SIP. Instead, it’s installing a new version of rubygems into /Library/Ruby, which takes precedence over the copy in /System if it exists.

    I think the underlying problem is that Apple patched the wrong file. Apple patched rubygems/defaults.rb, but that’s a file that comes with rubygems, so it’ll be overridden by a /usr/bin/gem update --system. Rubygems supports customizations via a different file, rubygems/defaults/operating_system.rb. That file isn’t installed by default, but if it exists it always takes precedence over rubygems/defaults; that would have prevented this problem. Homebrew uses that to customize the gem bindir in exactly the same way OS X does.

    1. 3

      Someone on Twitter pointed out to me that this is surprising (and maybe even a bug of sorts): Apparently Apple patches gem in such a way that it doesn’t install binaries to /usr/bin by default any longer.

      But that is surprising because your post-update gem was trying to install to /usr/bin. Out of curiosity, what is the default install directory for gems in the defaults file (grep for if defined? RUBY_FRAMEWORK_VERSION):


      I’m just wondering if the update to gem overwrote this patch. If so, that seems to be a bug: Apple tried to protect users from this kind of problem, but it should also forbid updating that defaults file.

      Update A few people tried the same global gem update and reported that the it installs a new defaults.rb file in /Library/Ruby/Gems. That defaults file is then read before the one patched by Apple, and boom: breakage when gem tries to install to /usr/bin. A relatively easy fix might be to patch the new defaults.rb by hand, so that it matches the Apple patch. It’s trivial change. I mention all this for future Googlers, but it may also help you now. Good luck!

      1. 5

        I looked into this, found that the /usr/bin/gem update --system isn’t installing anywhere inside /usr/bin or within the system Ruby at /System; it doesn’t have permissions to do that. Instead, the rubygems update is installing a new rubygems at /Library/Ruby/Site/2.0.0/, which is a sudo-writeable location under SIP; that is loaded by Ruby first before the version that comes with the OS, and it includes a version of rubygems/defaults.rb which lists /usr/bin as the default gem bindir. If you remove /Library/Ruby/Site/2.0.0/rubygems and /Library/Ruby/Site/2.0.0/rubygems.rb, gem will go back to using the original system-installed version and all will be fine; alternately, you can patch /Library/Ruby/Site/2.0.0/rubygems/defaults.rb to change the bindir.


        $ /usr/bin/ruby -e 'require "rubygems/defaults"; puts Gem.default_bindir'


        $ /usr/bin/ruby -e 'require "rubygems/defaults"; puts Gem.default_bindir'
        1. 8

          Privacy Badger is based on the ABP code, so I’d expect it to have the same problems described in the article.

        1. 2

          Just a note, this is actually an older version of the design for this scanner. Up-to-date instructions (including a laser-cut kit you can buy or make!) is available here.