New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
directory/file provider fail on OS X 10.11 due to SIP (System Integrity Protection) #3625
Comments
Option 2 definitely sounds better, or at least I'm not a fan of Option 1. FAC is really ugly code, though, and I'm hesitant to make it more complicated. It also sort of feels like |
Actually could you describe what you're trying to do in code? "If you want to write to '/usr/local'" is ambiguous since you might be referring to creating entries under /usr/local, or modifying perms on /usr/local which are two different things entirely. Creating entries under /usr/local should succeed fine if /usr is read-only, and we shouldn't be checking that. If that's the case then its a bug. I don't think that's what you're talking about? If you're trying to manage perms on /usr/local then that makes more sense about why we'd be checking |
On 10.11, you can |
@lamont-granquist I think you have it...I am referring to the behavior about checking the parent directory. Before any directory is created or has the permissions changed, it checks the parent directory to see if it is writable. If it isn't, it fails. This is done for recursive directory management as well. See:
with failure to be "writable" throwing: This is the exact error thrown on 10.11 Beta 2:
|
@lamont-granquist If I know where you want the functionality, I don't mind writing the code and testing. Let me know how you want to handle it ;) |
My first guess of where it should go is here: https://github.com/chef/chef/blob/master/chef-config/lib/chef-config/path_helper.rb And be used in chef via Chef::Utils::PathHelper. Although I'm not sure this is a "Path" helper, and a lot of that is Windows-specific. But implementing |
I believe I have the PathHelper done for SIP related checks, but I was curious where to put the actual logic. My proposal is to put it in the file and directory provider similar to this:
This would only check if the path is a SIP path on OS X 10.11 or newer and if it is a SIP path, it would see if it is on the exclusion list and return true if so. Let me know if there is a better place to put this or if you think it should be done differently. |
Here are more details on my implementation. It seems to be working now. PathHelper: https://gist.github.com/natewalck/12ab83d8a69ec3ecb80d#file-path_helper-rb I confirmed this allows me to change permissions on /usr/local, yet it will still prevent files from being written to /usr/* with the correct error message regarding insufficient permissions:
Let me know if this should be refactored and if I need to add any tests for it. |
Yeah it'll be most useful if you convert that into a PR so that we can review it with the diffs easier. It will definitely need some tests around it. |
Sure thing. I'll put the changes into file.rb as well and then we can iterate from there. Thanks for all the help! |
PR is in for this: #3704 |
Closing this since #3704 was merged |
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
With OS X 10.11, Apple has implemented a new system called SIP (System Integrity Protection, more info here with some great source links: https://en.wikipedia.org/wiki/System_Integrity_Protection)
I've dug into this a bit and here is what I've found:
If you want to write to '/usr/local', chef checks to see if '/usr' is writable:
https://github.com/chef/chef/blob/master/lib/chef/provider/directory.rb#L76-L79
This is normally ok, but because '/usr' is a protected directory, the call will return false. This is using ::File::writable? as found here: https://github.com/chef/chef/blob/master/lib/chef/file_access_control/unix.rb#L31-L32
On OS X 10.11 + SIP, '/usr/local' is writable, despite the fact that '/usr' itself is not. This kind of breaks how unix file permissions work (a little).
I've worked on two different solutions to this problem, with one of them working, but it is a real kludge.
Option 1 (AKA the kludge) - Change the directory/file/etc providers so they behave differently on OS X 10.11+.
Code: https://gist.github.com/natewalck/7340096da52a01722333
This also has some edge cases and isn't 100% complete.
Option 2
I've also written code that adds FileAccessControl::Macosx and includes all the functions from FileAccessControl::Unix, then overriding the writable? function to do all the extra SIP logic. To make this work, we would need to pass two more pieces of information everywhere writable? is called:
Here is the code for this one: https://gist.github.com/natewalck/33cd7705e6d5ccdb2929
This example doesn't implement everything as I described it, but you can get the general idea.
Adding these things also feels messy, so I would love other suggestions on how to fix this. I am more than willing to do the leg work and test it, but I want to make sure that I am doing it in the right way. I have code examples for the above things, as well as parsing out rootless.conf to get the list of SIP exception directories, which I will add to this issue as soon as I confirm a few things.
The text was updated successfully, but these errors were encountered: