diff options
author | Alexey Khoroshilov <khoroshilov@ispras.ru> | 2014-07-17 19:11:45 -0400 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@primarydata.com> | 2014-08-03 17:14:10 -0400 |
commit | 1f70ef96b176bdb3b75230ec68850d83736b387b (patch) | |
tree | dd1007c5227311063ef2cfbd0f7ae8d38b345d04 /fs | |
parent | 411a99adffb4f993eee29759f744de01487044ac (diff) |
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')
-rw-r--r-- | fs/nfs/client.c | 8 |
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) | |||
110 | mutex_unlock(&nfs_version_mutex); | 110 | mutex_unlock(&nfs_version_mutex); |
111 | } | 111 | } |
112 | 112 | ||
113 | if (!IS_ERR(nfs)) | 113 | if (!IS_ERR(nfs) && !try_module_get(nfs->owner)) |
114 | try_module_get(nfs->owner); | 114 | return ERR_PTR(-EAGAIN); |
115 | return nfs; | 115 | return nfs; |
116 | } | 116 | } |
117 | 117 | ||
@@ -158,7 +158,8 @@ struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init) | |||
158 | goto error_0; | 158 | goto error_0; |
159 | 159 | ||
160 | clp->cl_nfs_mod = cl_init->nfs_mod; | 160 | clp->cl_nfs_mod = cl_init->nfs_mod; |
161 | try_module_get(clp->cl_nfs_mod->owner); | 161 | if (!try_module_get(clp->cl_nfs_mod->owner)) |
162 | goto error_dealloc; | ||
162 | 163 | ||
163 | clp->rpc_ops = clp->cl_nfs_mod->rpc_ops; | 164 | clp->rpc_ops = clp->cl_nfs_mod->rpc_ops; |
164 | 165 | ||
@@ -190,6 +191,7 @@ struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init) | |||
190 | 191 | ||
191 | error_cleanup: | 192 | error_cleanup: |
192 | put_nfs_version(clp->cl_nfs_mod); | 193 | put_nfs_version(clp->cl_nfs_mod); |
194 | error_dealloc: | ||
193 | kfree(clp); | 195 | kfree(clp); |
194 | error_0: | 196 | error_0: |
195 | return ERR_PTR(err); | 197 | return ERR_PTR(err); |