summaryrefslogtreecommitdiffstats
path: root/fs/d_path.c (follow)
Commit message (Collapse)AuthorAgeFilesLines
* d_path: regularize handling of root dentry in __dentry_path()Al Viro2021-05-191-16/+5
| | | | | | | | | | | | | | | | | | | | | | | | All path-forming primitives boil down to sequence of prepend_name() on dentries encountered along the way toward root. Each time we prepend / + dentry name to the buffer. Normally that does exactly what we want, but there's a corner case when we don't call prepend_name() at all (in case of __dentry_path() that happens if we are given root dentry). We obviously want to end up with "/", rather than "", so this corner case needs to be handled. __dentry_path() used to manually put '/' in the end of buffer before doing anything else, to be overwritten by the first call of prepend_name() if one happens and to be left in place if we don't call prepend_name() at all. That required manually checking that we had space in the buffer (prepend_name() and prepend() take care of such checks themselves) and lead to clumsy keeping track of return value. A better approach is to check if the main loop has added anything into the buffer and prepend "/" if it hasn't. A side benefit of using prepend() is that it does the right thing if we'd already run out of buffer, making the overflow-handling logics simpler. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* d_path: saner calling conventions for __dentry_path()Al Viro2021-05-181-20/+13
| | | | | | | | | | | | | | | | 1) lift NUL-termination into the callers 2) pass pointer to the end of buffer instead of that to beginning. (1) allows to simplify dentry_path() - we don't need to play silly games with restoring the leading / of "//deleted" after __dentry_path() would've overwritten it with NUL. We also do not need to check if (either) prepend() in there fails - if the buffer is not large enough, we'll end with negative buflen after prepend() and __dentry_path() will return the right value (ERR_PTR(-ENAMETOOLONG)) just fine. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* d_path: "\0" is {0,0}, not {0}Al Viro2021-05-181-5/+5
| | | | | | Single-element array consisting of one NUL is spelled ""... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* constify dentry argument of dentry_path()/dentry_path_raw()Al Viro2021-03-211-5/+5
| | | | Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* fs: fix NULL dereference due to data race in prepend_path()Andrii Nakryiko2020-10-141-1/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Fix data race in prepend_path() with re-reading mnt->mnt_ns twice without holding the lock. is_mounted() does check for NULL, but is_anon_ns(mnt->mnt_ns) might re-read the pointer again which could be NULL already, if in between reads one of kern_unmount()/kern_unmount_array()/umount_tree() sets mnt->mnt_ns to NULL. This is seen in production with the following stack trace: BUG: kernel NULL pointer dereference, address: 0000000000000048 ... RIP: 0010:prepend_path.isra.4+0x1ce/0x2e0 Call Trace: d_path+0xe6/0x150 proc_pid_readlink+0x8f/0x100 vfs_readlink+0xf8/0x110 do_readlinkat+0xfd/0x120 __x64_sys_readlinkat+0x1a/0x20 do_syscall_64+0x42/0x110 entry_SYSCALL_64_after_hwframe+0x44/0xa9 Fixes: f2683bd8d5bd ("[PATCH] fix d_absolute_path() interplay with fsmount()") Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Reviewed-by: Josef Bacik <josef@toxicpanda.com> Cc: Alexander Viro <viro@zeniv.linux.org.uk> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* [PATCH] fix d_absolute_path() interplay with fsmount()Al Viro2019-08-311-2/+4
| | | | | | stuff in anon namespace should be treated as unattached. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* unexport simple_dname()Al Viro2019-05-211-1/+0
| | | | Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* split d_path() and friends into a separate fileAl Viro2018-03-291-0/+470
Those parts of fs/dcache.c are pretty much self-contained. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>