aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/client.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2006-08-24 01:03:05 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-09-22 23:24:54 -0400
commit5dd3177ae5012c1e2ad7a9ffdbd0e0d0de2f60e4 (patch)
tree2a8730d6443f6d33e8879cfc323396f9a570b97b /fs/nfs/client.c
parent275a082fe9308e710324e26ccb5363c53d8fd45f (diff)
NFSv4: Fix a use-after-free issue with the nfs server.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/client.c')
-rw-r--r--fs/nfs/client.c36
1 files changed, 21 insertions, 15 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 12941a8a6d75..f1ff2aec2ca5 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -164,6 +164,26 @@ error_0:
164 return NULL; 164 return NULL;
165} 165}
166 166
167static void nfs4_shutdown_client(struct nfs_client *clp)
168{
169#ifdef CONFIG_NFS_V4
170 if (__test_and_clear_bit(NFS_CS_RENEWD, &clp->cl_res_state))
171 nfs4_kill_renewd(clp);
172 while (!list_empty(&clp->cl_unused)) {
173 struct nfs4_state_owner *sp;
174
175 sp = list_entry(clp->cl_unused.next,
176 struct nfs4_state_owner,
177 so_list);
178 list_del(&sp->so_list);
179 kfree(sp);
180 }
181 BUG_ON(!list_empty(&clp->cl_state_owners));
182 if (__test_and_clear_bit(NFS_CS_IDMAP, &clp->cl_res_state))
183 nfs_idmap_delete(clp);
184#endif
185}
186
167/* 187/*
168 * Destroy a shared client record 188 * Destroy a shared client record
169 */ 189 */
@@ -171,21 +191,7 @@ static void nfs_free_client(struct nfs_client *clp)
171{ 191{
172 dprintk("--> nfs_free_client(%d)\n", clp->cl_nfsversion); 192 dprintk("--> nfs_free_client(%d)\n", clp->cl_nfsversion);
173 193
174#ifdef CONFIG_NFS_V4 194 nfs4_shutdown_client(clp);
175 if (__test_and_clear_bit(NFS_CS_IDMAP, &clp->cl_res_state)) {
176 while (!list_empty(&clp->cl_unused)) {
177 struct nfs4_state_owner *sp;
178
179 sp = list_entry(clp->cl_unused.next,
180 struct nfs4_state_owner,
181 so_list);
182 list_del(&sp->so_list);
183 kfree(sp);
184 }
185 BUG_ON(!list_empty(&clp->cl_state_owners));
186 nfs_idmap_delete(clp);
187 }
188#endif
189 195
190 /* -EIO all pending I/O */ 196 /* -EIO all pending I/O */
191 if (!IS_ERR(clp->cl_rpcclient)) 197 if (!IS_ERR(clp->cl_rpcclient))