SUNRPC: Fix a race in rpc_info_open
There is a race between rpc_info_open and rpc_release_client() in that nothing stops a process from opening the file after the clnt->cl_kref goes to zero. Fix this by using atomic_inc_unless_zero()... Reported-by: J. Bruce Fields <bfields@redhat.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> Cc: stable@kernel.org
This commit is contained in:
parent
5a67657a2e
commit
006abe887c
3 changed files with 21 additions and 21 deletions
|
@ -371,21 +371,23 @@ rpc_show_info(struct seq_file *m, void *v)
|
|||
static int
|
||||
rpc_info_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct rpc_clnt *clnt;
|
||||
struct rpc_clnt *clnt = NULL;
|
||||
int ret = single_open(file, rpc_show_info, NULL);
|
||||
|
||||
if (!ret) {
|
||||
struct seq_file *m = file->private_data;
|
||||
mutex_lock(&inode->i_mutex);
|
||||
clnt = RPC_I(inode)->private;
|
||||
if (clnt) {
|
||||
kref_get(&clnt->cl_kref);
|
||||
|
||||
spin_lock(&file->f_path.dentry->d_lock);
|
||||
if (!d_unhashed(file->f_path.dentry))
|
||||
clnt = RPC_I(inode)->private;
|
||||
if (clnt != NULL && atomic_inc_not_zero(&clnt->cl_count)) {
|
||||
spin_unlock(&file->f_path.dentry->d_lock);
|
||||
m->private = clnt;
|
||||
} else {
|
||||
spin_unlock(&file->f_path.dentry->d_lock);
|
||||
single_release(inode, file);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue