-stable review patch. If anyone has any objections, please let us know.
------------------
From: Trond Myklebust <[email protected]>
We're presently running lock_kernel() under fs_lock via nfs's ->permission
handler. That's a ranking bug and sometimes a sleep-in-spinlock bug. This
problem was introduced in the openat() patchset.
We should not need to hold the current->fs->lock for a codepath that doesn't
use current->fs.
[[email protected]: fix error path]
Signed-off-by: Trond Myklebust <[email protected]>
Cc: Al Viro <[email protected]>
Signed-off-by: Sergey Vlasov <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Chris Wright <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
fs/namei.c | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
--- linux-2.6.16.21.orig/fs/namei.c
+++ linux-2.6.16.21/fs/namei.c
@@ -1077,8 +1077,8 @@ static int fastcall do_path_lookup(int d
nd->flags = flags;
nd->depth = 0;
- read_lock(¤t->fs->lock);
if (*name=='/') {
+ read_lock(¤t->fs->lock);
if (current->fs->altroot && !(nd->flags & LOOKUP_NOALT)) {
nd->mnt = mntget(current->fs->altrootmnt);
nd->dentry = dget(current->fs->altroot);
@@ -1089,33 +1089,35 @@ static int fastcall do_path_lookup(int d
}
nd->mnt = mntget(current->fs->rootmnt);
nd->dentry = dget(current->fs->root);
+ read_unlock(¤t->fs->lock);
} else if (dfd == AT_FDCWD) {
+ read_lock(¤t->fs->lock);
nd->mnt = mntget(current->fs->pwdmnt);
nd->dentry = dget(current->fs->pwd);
+ read_unlock(¤t->fs->lock);
} else {
struct dentry *dentry;
file = fget_light(dfd, &fput_needed);
retval = -EBADF;
if (!file)
- goto unlock_fail;
+ goto out_fail;
dentry = file->f_dentry;
retval = -ENOTDIR;
if (!S_ISDIR(dentry->d_inode->i_mode))
- goto fput_unlock_fail;
+ goto fput_fail;
retval = file_permission(file, MAY_EXEC);
if (retval)
- goto fput_unlock_fail;
+ goto fput_fail;
nd->mnt = mntget(file->f_vfsmnt);
nd->dentry = dget(dentry);
fput_light(file, fput_needed);
}
- read_unlock(¤t->fs->lock);
current->total_link_count = 0;
retval = link_path_walk(name, nd);
out:
@@ -1124,13 +1126,12 @@ out:
nd->dentry->d_inode))
audit_inode(name, nd->dentry->d_inode, flags);
}
+out_fail:
return retval;
-fput_unlock_fail:
+fput_fail:
fput_light(file, fput_needed);
-unlock_fail:
- read_unlock(¤t->fs->lock);
- return retval;
+ goto out_fail;
}
int fastcall path_lookup(const char *name, unsigned int flags,
--
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[Index of Archives]
[Kernel Newbies]
[Netfilter]
[Bugtraq]
[Photo]
[Stuff]
[Gimp]
[Yosemite News]
[MIPS Linux]
[ARM Linux]
[Linux Security]
[Linux RAID]
[Video 4 Linux]
[Linux for the blind]
[Linux Resources]