29.04.2024 01:12, stsp пишет:
freely pass device nodes around, then perhaps the ability to pass an r/o dir fd that can suddenly give creds, is probably not something new...
Actually there is probably something new anyway. The process knows to close all sensitive files before dropping privs. But this may not be the case with dirs, because dir_fd pretty much invalidates itself when you drop privs: you'll get EPERM from openat() if you no longer have rights to open the file, and dir_fd doesn't help. Which is why someone may neglect to close dir_fd before dropping privs, but with O_CRED_ALLOW that would be a mistake. Or what about this scenario: receiver gets this fd thinking its some useful and harmless file fd that would be needed even after priv drop. So he makes sure with F_GETFL that this fd is O_RDONLY and doesn't close it. But it appears to be malicious O_CRED_ALLOW dir_fd, which basically exposes many files for a write. So I am concerned about the cases where an fd was not closed before a priv drop, because the process didn't realize the threat.
But if the*whole point* of opening the fd was to capture privileges and preserve them across a privilege drop, and the program loads malicious code after dropping privs, then that's a risk that's taken intentionally.
If you opened an fd yourself, then yes. You know what have you opened, and you care to close sensitive fds before dropping privs, or you take the risk. But if you requested something from another process and got some fd as the result, the kernel doesn't guarantee you got an fd to what you have requested. You can get a malicious fd, which is not "so" possible when you open an fd yourself. So if you want to keep such an fd open, you will probably at least make sure its read-only, its not a device node (with fstat) and so on. All checks pass, and oops, O_CRED_ALLOW... So why my patch makes O_CRED_ALLOW non-passable? Because the receiver has no way to see the potential harm within such fd. So if he intended to keep an fd open after some basic safety checks, he will be tricked. So while I think its a rather bad idea to leave the received fds open after priv drop, I don't completely exclude the possibility that someone did that, together with a few safety checks which would be tricked by O_CRED_ALLOW.