mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-04 12:16:41 +00:00
svcrpc: fix double-free on shutdown of nfsd after changing pool mode
commit 61c8504c42
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@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Signed-off-by: Willy Tarreau <w@1wt.eu>
This commit is contained in:
parent
2e9633af99
commit
b57fdc838c
@ -163,6 +163,7 @@ svc_pool_map_alloc_arrays(struct svc_pool_map *m, unsigned int maxpools)
|
||||
|
||||
fail_free:
|
||||
kfree(m->to_pool);
|
||||
m->to_pool = NULL;
|
||||
fail:
|
||||
return -ENOMEM;
|
||||
}
|
||||
@ -283,7 +284,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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user