diff options
author | Alexey Khoroshilov <khoroshilov@ispras.ru> | 2014-07-18 03: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) | |
download | op-kernel-dev-1f70ef96b176bdb3b75230ec68850d83736b387b.zip op-kernel-dev-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')
-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 168aa0d..b7bfa27 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); |