mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00
fs: fix dropping of rcu-walk from force_reval_path
As J. R. Okajima noted, force_reval_path passes in the same dentry to d_revalidate as the one in the nameidata structure (other callers pass in a child), so the locking breaks. This can oops with a chrooted nfs mount, for example. Similarly there can be other problems with revalidating a dentry which is already in nameidata of the path walk. Signed-off-by: Nick Piggin <npiggin@kernel.dk>
This commit is contained in:
parent
bb20c18db6
commit
90dbb77ba4
1 changed files with 8 additions and 0 deletions
|
@ -479,6 +479,14 @@ static int nameidata_dentry_drop_rcu(struct nameidata *nd, struct dentry *dentry
|
||||||
struct fs_struct *fs = current->fs;
|
struct fs_struct *fs = current->fs;
|
||||||
struct dentry *parent = nd->path.dentry;
|
struct dentry *parent = nd->path.dentry;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* It can be possible to revalidate the dentry that we started
|
||||||
|
* the path walk with. force_reval_path may also revalidate the
|
||||||
|
* dentry already committed to the nameidata.
|
||||||
|
*/
|
||||||
|
if (unlikely(parent == dentry))
|
||||||
|
return nameidata_drop_rcu(nd);
|
||||||
|
|
||||||
BUG_ON(!(nd->flags & LOOKUP_RCU));
|
BUG_ON(!(nd->flags & LOOKUP_RCU));
|
||||||
if (nd->root.mnt) {
|
if (nd->root.mnt) {
|
||||||
spin_lock(&fs->lock);
|
spin_lock(&fs->lock);
|
||||||
|
|
Loading…
Add table
Reference in a new issue