On 2019-07-14, Al Viro viro@zeniv.linux.org.uk wrote:
On Sun, Jul 14, 2019 at 05:00:29PM +1000, Aleksa Sarai wrote:
The basic property being guaranteed by LOOKUP_IN_ROOT is that it will not result in resolution of a path component which was not inside the root of the dirfd tree at some point during resolution (and that all absolute symlink and ".." resolution will be done relative to the dirfd). This may smell slightly of chroot(2), because unfortunately it is a similar concept -- the reason for this is to allow for a more efficient way to safely resolve paths inside a rootfs than spawning a separate process to then pass back the fd to the caller.
IDGI... If attacker can modify your subtree, you have already lost - after all, they can make anything appear inside that tree just before your syscall is made and bring it back out immediately afterwards. And if they can't, what is the race you are trying to protect against? Confused...
I'll be honest, this code mostly exists because Jann Horn said that it was necessary in order for this interface to be safe against those kinds of attacks. Though, it's also entirely possible I just am mis-remembering the attack scenario he described when I posted v1 of this series last year.
The use-case I need this functionality for (as do other container runtimes) is one where you are trying to safely interact with a directory tree that is a (malicious) container's root filesystem -- so the container won't be able to move the directory tree root, nor can they move things outside the rootfs into it (or the reverse). Users dealing with FTP, web, or file servers probably have similar requirements.
There is an obvious race condition if you allow the attacker to move the root (I give an example and test-case of it in the last patch in the series), and given that it is fairly trivial to defend against I don't see the downside in including it? But it's obviously your call -- and maybe Jann Horn can explain the reasoning behind this much better than I can.