]> git.hungrycats.org Git - linux/commitdiff
svcrpc: fix double-free on shutdown of nfsd after changing pool mode
authorJ. Bruce Fields <bfields@redhat.com>
Fri, 23 Dec 2011 01:22:49 +0000 (18:22 -0700)
committerWilly Tarreau <w@1wt.eu>
Sat, 11 Feb 2012 14:38:28 +0000 (15:38 +0100)
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@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Signed-off-by: Willy Tarreau <w@1wt.eu>
net/sunrpc/svc.c

index 5a32cb7c4bb486267a03d15892adc7ce5db93c93..8a41977bc3d41e3deedba257c268d72c5843efd8 100644 (file)
@@ -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;
        }