On 01/09/2018 07:07 PM, William Hubbs wrote > > However, I'm not sure how to deal with the hard link issue in a way that > will not break service scripts. >
Systemd mitigates this by enabling the fs.protected_hardlinks sysctl by default, but they have the liberty of requiring a relatively new Linux kernel. The larger problem there is that, unless you have some kernel protection built-in, the "Z" type in the tmpfiles.d spec is always going to be exploitable: * https://github.com/OpenRC/opentmpfiles/issues/3 * https://github.com/systemd/systemd/issues/7736 (I didn't realize at the time that the OpenRC fix still contained a race condition.) Ultimately, it's not safe to chown/chmod/setfacl/whatever in a directory that is not writable only by yourself and root. There's some precedent for this in e.g. https://wiki.gentoo.org/wiki/Hardened/Grsecurity_Trusted_Path_Execution where they refuse to *execute* something that is writable by others. But a solution like that would break existing scripts. If it's any consolation, the tools like chown, chgrp, chmod, setfacl, etc. are all vulnerable to the same issue themselves. GNU chown has the "--from" flag (which still contains a race, by the way), but the other tools don't, and are all exploitable in the same way. Again the advice seems to be "don't do things if somebody can write to the directory you're in." Here's a very tedious proposal for OpenRC: 1. Create a new helper, called e.g. "newpath", that is like checkpath but only creates things, and doesn't modify them. 2. Have newpath throw a warning if it's used in a directory that is writable by someone other than root and the OpenRC user. This will prevent people from creating /foo/bar after /foo has already been created with owner "foo:foo". In other words, service script writers will be encouraged to do things in a safe order. Since we're starting over, this might even be made an error. 3. Deprecate checkpath 4. Wait a million years for people to switch from checkpath to newpath 5. Get rid of checkpath I'm not even sure that this solves the problem completely, but it's the only idea I've got left.