On Mon, May 5, 2025 at 12:30 PM Jan Kara <jack@xxxxxxx> wrote: > > On Fri 02-05-25 20:28:13, Mateusz Guzik wrote: > > The user would *not* get the path even if they realpath /bar/file as > > they don't have perms. You could argue the user does not have the > > rights to know where the file after said rename. > > Indeed. In particular if the directory hierarchy is deeper, the user could > learn about things he is never supposed to see. Thanks for explanation. > I realized I was wrong here, but it does not change anything. With O_PATH you can get a fd to a file even if you can't truly open the file itself, as long as you can traverse to it. Afterwards the kernel will happily return whatever path it can generate if you readlink on /proc/self/fd. So should someone reimplement userspace realpath this way they could get the result I claimed unobtainable. However, the result would be wrong from API perspective. Suppose a program tries to use it as a mapping "path provided by the user" -> "actual path" to catch de facto duplicate path names. In this sense, /bar/file is a broken result as opening /foo/file does not get you there. > > So I stand by the need to check rename seq. > > > > However, I wonder if it would be tolerable to redo the lookup with the > > *new* path and check if we got the same dentry at the end. If so, we > > know the path was obtainable by traversal. > > I agree that if following path lookup will succeed, it should be safe to > give out the path. But there's one more corner case - suppose you look up > > /foo/file > > while racing with rename /bar/file /foo/file. With userspace implementation > you're always going to get /foo/file as rename is atomic wrt other dir > operations. With the kernel implementation, you may call prepend_path() on > already deleted dentry with obvious results... > So I realized redoing the lookup does not work either for the same reason one needs sequence counters to synchro this kind of stuff. Suppose a thread continuously renames /foo/file /bar/file and /bar/file /foo/file. A sufficiently unlucky realpath implemented as above can return /bar/file. This all sums up however to once more returning -EAGAIN after lookup + prepend_path. -- Mateusz Guzik <mjguzik gmail.com>