summary refs log tree commit diff
path: root/fs/nfs
diff options
context:
space:
mode:
authorAlexey Khoroshilov <khoroshilov@ispras.ru>2014-07-18 03:11:45 +0400
committerTrond Myklebust <trond.myklebust@primarydata.com>2014-08-03 17:14:10 -0400
commit1f70ef96b176bdb3b75230ec68850d83736b387b (patch)
treedd1007c5227311063ef2cfbd0f7ae8d38b345d04 /fs/nfs
parent411a99adffb4f993eee29759f744de01487044ac (diff)
downloadlinux-1f70ef96b176bdb3b75230ec68850d83736b387b.tar.gz
NFS: add checks for returned value of try_module_get()
There is a couple of places in client code where returned value
of try_module_get() is ignored. As a result there is a small chance
to premature unload module because of unbalanced refcounting.

The patch adds error handling in that places.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/client.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 168aa0df2658..b7bfa2765370 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -110,8 +110,8 @@ struct nfs_subversion *get_nfs_version(unsigned int version)
 		mutex_unlock(&nfs_version_mutex);
 	}
 
-	if (!IS_ERR(nfs))
-		try_module_get(nfs->owner);
+	if (!IS_ERR(nfs) && !try_module_get(nfs->owner))
+		return ERR_PTR(-EAGAIN);
 	return nfs;
 }
 
@@ -158,7 +158,8 @@ struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init)
 		goto error_0;
 
 	clp->cl_nfs_mod = cl_init->nfs_mod;
-	try_module_get(clp->cl_nfs_mod->owner);
+	if (!try_module_get(clp->cl_nfs_mod->owner))
+		goto error_dealloc;
 
 	clp->rpc_ops = clp->cl_nfs_mod->rpc_ops;
 
@@ -190,6 +191,7 @@ struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init)
 
 error_cleanup:
 	put_nfs_version(clp->cl_nfs_mod);
+error_dealloc:
 	kfree(clp);
 error_0:
 	return ERR_PTR(err);