diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-06-15 13:02:58 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-06-19 13:32:45 -0400 |
commit | 0a9c63fae7df086ff5e107273c3cce8642430974 (patch) | |
tree | a8636a5d35f0ae5e45f64d27759dd02d7e2ca598 /fs | |
parent | 2a4c8994eeef50796015f8a2005e4a75c1929166 (diff) |
NFSv4.1: Fix a race in set_pnfs_layoutdriver
The call to try_module_get() dereferences ld_type outside the
spin locks, which means that it may be pointing to garbage if
a module unload was in progress.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfs/pnfs.c | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index bdf7e52943c8..bbc49caa7a82 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c | |||
@@ -70,6 +70,10 @@ find_pnfs_driver(u32 id) | |||
70 | 70 | ||
71 | spin_lock(&pnfs_spinlock); | 71 | spin_lock(&pnfs_spinlock); |
72 | local = find_pnfs_driver_locked(id); | 72 | local = find_pnfs_driver_locked(id); |
73 | if (local != NULL && !try_module_get(local->owner)) { | ||
74 | dprintk("%s: Could not grab reference on module\n", __func__); | ||
75 | local = NULL; | ||
76 | } | ||
73 | spin_unlock(&pnfs_spinlock); | 77 | spin_unlock(&pnfs_spinlock); |
74 | return local; | 78 | return local; |
75 | } | 79 | } |
@@ -118,10 +122,6 @@ set_pnfs_layoutdriver(struct nfs_server *server, const struct nfs_fh *mntfh, | |||
118 | goto out_no_driver; | 122 | goto out_no_driver; |
119 | } | 123 | } |
120 | } | 124 | } |
121 | if (!try_module_get(ld_type->owner)) { | ||
122 | dprintk("%s: Could not grab reference on module\n", __func__); | ||
123 | goto out_no_driver; | ||
124 | } | ||
125 | server->pnfs_curr_ld = ld_type; | 125 | server->pnfs_curr_ld = ld_type; |
126 | if (ld_type->set_layoutdriver | 126 | if (ld_type->set_layoutdriver |
127 | && ld_type->set_layoutdriver(server, mntfh)) { | 127 | && ld_type->set_layoutdriver(server, mntfh)) { |