[16/27] svcrpc: fix double-free on shutdown of nfsd after changing pool mode
From: Greg KH
Date: Mon Jan 23 2012 - 19:13:09 EST
2.6.32-longterm review patch. If anyone has any objections, please let me know.
------------------
From: "J. Bruce Fields" <bfields@xxxxxxxxxx>
commit 61c8504c428edcebf23b97775a129c5b393a302b upstream.
The pool_to and to_pool fields of the global svc_pool_map are freed on
shutdown, but are initialized in nfsd startup only in the
SVC_POOL_PERCPU and SVC_POOL_PERNODE cases.
They *are* initialized to zero on kernel startup. So as long as you use
only SVC_POOL_GLOBAL (the default), this will never be a problem.
You're also OK if you only ever use SVC_POOL_PERCPU or SVC_POOL_PERNODE.
However, the following sequence events leads to a double-free:
1. set SVC_POOL_PERCPU or SVC_POOL_PERNODE
2. start nfsd: both fields are initialized.
3. shutdown nfsd: both fields are freed.
4. set SVC_POOL_GLOBAL
5. start nfsd: the fields are left untouched.
6. shutdown nfsd: now we try to free them again.
Step 4 is actually unnecessary, since (for some bizarre reason), nfsd
automatically resets the pool mode to SVC_POOL_GLOBAL on shutdown.
Signed-off-by: J. Bruce Fields <bfields@xxxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxx>
---
net/sunrpc/svc.c | 3 +++
1 file changed, 3 insertions(+)
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -166,6 +166,7 @@ svc_pool_map_alloc_arrays(struct svc_poo
fail_free:
kfree(m->to_pool);
+ m->to_pool = NULL;
fail:
return -ENOMEM;
}
@@ -286,7 +287,9 @@ svc_pool_map_put(void)
if (!--m->count) {
m->mode = SVC_POOL_DEFAULT;
kfree(m->to_pool);
+ m->to_pool = NULL;
kfree(m->pool_to);
+ m->pool_to = NULL;
m->npools = 0;
}
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/